diff --git a/.gitignore b/.gitignore index 3faf97ab..2f71820b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # dependencies /node_modules +/.hutch /.pnp .pnp.js diff --git a/Jenkinsfile b/Jenkinsfile index 5fd1dd0c..37ea48a5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -182,6 +182,9 @@ try { parallel( 'Windows Build': buildOnLabel('windows', 'bun run build:app', false), 'Windows CEF Build': buildOnLabel('windows', 'bun run build:app', true), + // Electrobun 2.0.1 does not publish macOS x64 Hutch/core artifacts. + // Keep both jobs so CI can use an Apple Silicon or Intel agent when + // upstream adds the matching host; the other arch fails host-natively. 'MacOS x64 Build': buildMacOnLabel('macos', 'x64', false), 'MacOS x64 CEF Build': buildMacOnLabel('macos', 'x64', true), 'MacOS arm64 Build': buildMacOnLabel('macos', 'arm64', false), diff --git a/bun.lock b/bun.lock index df592f55..a29ef545 100644 --- a/bun.lock +++ b/bun.lock @@ -84,7 +84,7 @@ "@eslint/js": "^9.39.2", "@vitejs/plugin-react": "^5.0.2", "concurrently": "^9.2.1", - "electrobun": "1.18.1", + "electrobun": "2.0.1", "electron": "^38.7.1", "electron-builder": "^26.0.12", "electron-packager": "^17.1.2", @@ -187,8 +187,6 @@ "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "7.27.1", "@babel/helper-validator-identifier": "7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], - "@babylonjs/core": ["@babylonjs/core@7.54.3", "", {}, "sha512-P5ncXVd8GEUJLhwloP9V0oVwQYIrvZztguVeLlvd5Rx+9aQnenKjpV8auJ6SRsUlAmNZU4pFTKzwF6o2EUfhAw=="], - "@borewit/text-codec": ["@borewit/text-codec@0.2.2", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="], "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.3.4", "", { "dependencies": { "mime": "3.0.0" } }, "sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q=="], @@ -771,8 +769,6 @@ "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="], - "@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="], - "@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="], "@tsparticles/basic": ["@tsparticles/basic@3.9.1", "", { "dependencies": { "@tsparticles/engine": "3.9.1", "@tsparticles/move-base": "3.9.1", "@tsparticles/plugin-hex-color": "3.9.1", "@tsparticles/plugin-hsl-color": "3.9.1", "@tsparticles/plugin-rgb-color": "3.9.1", "@tsparticles/shape-circle": "3.9.1", "@tsparticles/updater-color": "3.9.1", "@tsparticles/updater-opacity": "3.9.1", "@tsparticles/updater-out-modes": "3.9.1", "@tsparticles/updater-size": "3.9.1" } }, "sha512-ijr2dHMx0IQHqhKW3qA8tfwrR2XYbbWYdaJMQuBo2CkwBVIhZ76U+H20Y492j/NXpd1FUnt2aC0l4CEVGVGdeQ=="], @@ -879,8 +875,6 @@ "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "7.29.0" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], - "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], - "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="], @@ -1031,8 +1025,6 @@ "asn1js": ["asn1js@3.0.10", "", { "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.5", "tslib": "^2.8.1" } }, "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg=="], - "ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="], - "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], "async-exit-hook": ["async-exit-hook@2.0.1", "", {}, "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw=="], @@ -1065,8 +1057,6 @@ "baseline-browser-mapping": ["baseline-browser-mapping@2.11.4", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-s4+sLr9mZ/CyqeRritFeYV/Zx73OAtmaHn6kkBS1XRoJn1hrg3xIDUcpicAEX68tkcIN0iBCgti31C8zxtkhsQ=="], - "basic-ftp": ["basic-ftp@5.3.1", "", {}, "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw=="], - "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], "bluebird": ["bluebird@3.7.2", "", {}, "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="], @@ -1101,8 +1091,6 @@ "builtins": ["builtins@5.1.0", "", { "dependencies": { "semver": "7.7.3" } }, "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg=="], - "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], - "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], "bytestreamjs": ["bytestreamjs@2.0.1", "", {}, "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ=="], @@ -1257,7 +1245,7 @@ "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="], - "data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="], + "data-uri-to-buffer": ["data-uri-to-buffer@2.0.2", "", {}, "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA=="], "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "1.0.4", "es-errors": "1.3.0", "is-data-view": "1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="], @@ -1291,8 +1279,6 @@ "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="], - "degenerator": ["degenerator@5.0.1", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" } }, "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ=="], - "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], @@ -1341,7 +1327,7 @@ "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], - "electrobun": ["electrobun@1.18.1", "", { "dependencies": { "@babylonjs/core": "^7.45.0", "@types/bun": "^1.3.8", "png-to-ico": "^2.1.8", "proxy-agent": "^6.5.0", "rcedit": "^4.0.1", "three": "^0.165.0" }, "bin": { "electrobun": "bin/electrobun.cjs" } }, "sha512-tgZ+WKGskn/1/Y5i1mpVCCkgRa1O31Tz7MIArBTK44GfPzT43uOq9c/HvxdQGrLeZV8ZvjK1lQrwqSXCgh6tvA=="], + "electrobun": ["electrobun@2.0.1", "", { "bin": { "electrobun": "bin/electrobun.cjs" } }, "sha512-1+OjJ0tMemjVrUEsh/AhmxnqUNpyCfJslCbcWOvkogFJuNVMmTlWMzyZem/Ts/7lg8f7ULWu8uuQBsKeGQsu7A=="], "electron": ["electron@38.8.6", "", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^22.7.7", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-lyBhcVi9QYAZL6FO6r5twAWAjWnYomo3iVDvrb5SJZlq928BGemHOKG0tPIq41NOLaCu9f3XdEEjMkjQPjprRg=="], @@ -1405,8 +1391,6 @@ "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], - "escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="], - "eslint": ["eslint@9.39.2", "", { "dependencies": { "@eslint-community/eslint-utils": "4.9.1", "@eslint-community/regexpp": "4.12.2", "@eslint/config-array": "0.21.1", "@eslint/config-helpers": "0.4.2", "@eslint/core": "0.17.0", "@eslint/eslintrc": "3.3.3", "@eslint/js": "9.39.2", "@eslint/plugin-kit": "0.4.1", "@humanfs/node": "0.16.7", "@humanwhocodes/module-importer": "1.0.1", "@humanwhocodes/retry": "0.4.3", "@types/estree": "1.0.8", "ajv": "6.12.6", "chalk": "4.1.2", "cross-spawn": "7.0.6", "debug": "4.4.3", "escape-string-regexp": "4.0.0", "eslint-scope": "8.4.0", "eslint-visitor-keys": "4.2.1", "espree": "10.4.0", "esquery": "1.7.0", "esutils": "2.0.3", "fast-deep-equal": "3.1.3", "file-entry-cache": "8.0.0", "find-up": "5.0.0", "glob-parent": "6.0.2", "ignore": "5.3.2", "imurmurhash": "0.1.4", "is-glob": "4.0.3", "json-stable-stringify-without-jsonify": "1.0.1", "lodash.merge": "4.6.2", "minimatch": "3.1.2", "natural-compare": "1.4.0", "optionator": "0.9.4" }, "optionalDependencies": { "jiti": "2.6.1" }, "bin": { "eslint": "bin/eslint.js" } }, "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw=="], "eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": "9.39.2" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="], @@ -1443,8 +1427,6 @@ "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "8.15.0", "acorn-jsx": "5.3.2", "eslint-visitor-keys": "4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], - "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], - "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "5.3.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="], "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "5.3.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], @@ -1569,8 +1551,6 @@ "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "1.0.4", "es-errors": "1.3.0", "get-intrinsic": "1.3.0" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="], - "get-uri": ["get-uri@6.0.5", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg=="], - "gifwrap": ["gifwrap@0.10.1", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="], "glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "1.0.0", "inflight": "1.0.6", "inherits": "2.0.4", "minimatch": "3.1.2", "once": "1.4.0", "path-is-absolute": "1.0.1" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], @@ -1663,8 +1643,6 @@ "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], - "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], - "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], @@ -1831,7 +1809,7 @@ "lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="], - "lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "3.1.1" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "magic-string": ["magic-string@0.25.9", "", { "dependencies": { "sourcemap-codec": "1.4.8" } }, "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ=="], @@ -1989,8 +1967,6 @@ "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], - "netmask": ["netmask@2.1.1", "", {}, "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA=="], - "no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "2.0.2", "tslib": "2.8.1" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="], "node-abi": ["node-abi@4.33.0", "", { "dependencies": { "semver": "^7.6.3" } }, "sha512-vLBWCKb+7LWsX+TbfzWOkw0W81m377tyx3hOweBTjO43CXZnRGS1/JPWs20fr0PgZyDXk6ROYrylsEycK8raDA=="], @@ -2059,10 +2035,6 @@ "p-try": ["p-try@1.0.0", "", {}, "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww=="], - "pac-proxy-agent": ["pac-proxy-agent@7.2.0", "", { "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", "socks-proxy-agent": "^8.0.5" } }, "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA=="], - - "pac-resolver": ["pac-resolver@7.0.1", "", { "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" } }, "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg=="], - "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "3.1.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], @@ -2193,8 +2165,6 @@ "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], - "proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="], - "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], @@ -2465,18 +2435,12 @@ "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], - "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], - "snake-case": ["snake-case@3.0.4", "", { "dependencies": { "dot-case": "3.0.4", "tslib": "2.8.1" } }, "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg=="], "socket.io-client": ["socket.io-client@4.8.3", "", { "dependencies": { "@socket.io/component-emitter": "3.1.2", "debug": "4.4.3", "engine.io-client": "6.6.4", "socket.io-parser": "4.2.5" } }, "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g=="], "socket.io-parser": ["socket.io-parser@4.2.5", "", { "dependencies": { "@socket.io/component-emitter": "3.1.2", "debug": "4.4.3" } }, "sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ=="], - "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "10.1.0", "smart-buffer": "4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], - - "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "7.1.4", "debug": "4.4.3", "socks": "2.8.7" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], - "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], @@ -2779,8 +2743,6 @@ "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "3.1.1" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], - "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -2891,8 +2853,6 @@ "boxen/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], - "bun-types/@types/node": ["@types/node@25.2.0", "", { "dependencies": { "undici-types": "7.16.0" } }, "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w=="], - "chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "4.3.0", "string-width": "4.2.3", "strip-ansi": "6.0.1" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], @@ -2915,8 +2875,6 @@ "dotenv-expand/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], - "electrobun/three": ["three@0.165.0", "", {}, "sha512-cc96IlVYGydeceu0e5xq70H8/yoVT/tXBxV/W8A/U6uOq7DXc4/s1Mkmnu6SqoYGhSRWWYFOhVwvq6V0VtbplA=="], - "electron-packager/fs-extra": ["fs-extra@11.4.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA=="], "electron-packager/rcedit": ["rcedit@3.1.0", "", { "dependencies": { "cross-spawn-windows-exe": "^1.1.0" } }, "sha512-WRlRdY1qZbu1L11DklT07KuHfRk42l0NFFJdaExELEu4fEQ982bP5Z6OWGPj/wLLIuKRQDCxZJGAwoFsxhZhNA=="], @@ -2927,8 +2885,6 @@ "engine.io-client/ws": ["ws@8.18.3", "", {}, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], - "escodegen/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], "eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], @@ -2957,8 +2913,6 @@ "get-package-info/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - "get-source/data-uri-to-buffer": ["data-uri-to-buffer@2.0.2", "", {}, "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA=="], - "get-source/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "has-ansi/ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="], @@ -2973,6 +2927,8 @@ "loglevel-colored-level-prefix/chalk": ["chalk@1.1.3", "", { "dependencies": { "ansi-styles": "2.2.1", "escape-string-regexp": "1.0.5", "has-ansi": "2.0.0", "strip-ansi": "3.0.1", "supports-color": "2.0.0" } }, "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A=="], + "lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -3107,8 +3063,6 @@ "xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], - "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - "@electron/get/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], "@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], @@ -3233,8 +3187,6 @@ "boxen/string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "6.2.2" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], - "bun-types/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], - "compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "cross-spawn-windows-exe/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], diff --git a/electrobun.config.ts b/electrobun.config.ts index 89e9a27a..06c17573 100644 --- a/electrobun.config.ts +++ b/electrobun.config.ts @@ -14,13 +14,6 @@ const bundleCEF = ["1", "true", "yes"].includes( String(process.env.ELECTROBUN_BUNDLE_CEF || "").toLowerCase(), ); const defaultRenderer = bundleCEF ? "cef" : "native"; -const targetOs = - process.env.ELECTROBUN_OS || - (process.platform === "darwin" - ? "macos" - : process.platform === "win32" - ? "win" - : "linux"); export default { app: { @@ -34,18 +27,9 @@ export default { exitOnLastWindowClosed: true, }, build: { + mainProcess: "bun", buildFolder: "build", artifactFolder: "app_dist", - // macOS WebKit loads views:// assets reliably from a flat app folder; - // ASAR-packed views can fail to load module scripts on first launch. - useAsar: isStable && targetOs !== "macos", - asarUnpack: [ - "*.node", - "*.dll", - "*.dylib", - "*.so", - "views/**", - ], bun: { entrypoint: "src/bun/index.js", }, diff --git a/hutch.config.ts b/hutch.config.ts new file mode 100644 index 00000000..d87eae4b --- /dev/null +++ b/hutch.config.ts @@ -0,0 +1,3 @@ +export default { + packageManager: "bun", +}; diff --git a/package.json b/package.json index 6f8f66ca..7ed20e68 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "build:electron": "vite build && electron-builder", "build:cloudflare": "cross-env VITE_DEPLOY_TARGET=cloudflare vite build", "deploy": "npm run build:cloudflare && wrangler pages deploy --branch main", - "postinstall": "bun scripts/patch-electrobun-src.mjs && bun scripts/build-macos-effects.mjs", + "postinstall": "bun scripts/build-macos-effects.mjs", "generate-app-icons": "bun scripts/generate-app-icons.mjs", "build:macos-effects": "bun scripts/build-macos-effects.mjs", "clean": "bun scripts/clean-build.mjs" @@ -125,7 +125,7 @@ "@eslint/js": "^9.39.2", "@vitejs/plugin-react": "^5.0.2", "concurrently": "^9.2.1", - "electrobun": "1.18.1", + "electrobun": "2.0.1", "electron": "^38.7.1", "electron-builder": "^26.0.12", "electron-packager": "^17.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4d0abed..60aef08b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -249,8 +249,8 @@ importers: specifier: ^9.2.1 version: 9.2.1 electrobun: - specifier: 1.18.1 - version: 1.18.1 + specifier: 2.0.1 + version: 2.0.1 electron: specifier: ^38.7.1 version: 38.8.0 @@ -517,9 +517,6 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@babylonjs/core@7.54.3': - resolution: {integrity: sha512-P5ncXVd8GEUJLhwloP9V0oVwQYIrvZztguVeLlvd5Rx+9aQnenKjpV8auJ6SRsUlAmNZU4pFTKzwF6o2EUfhAw==} - '@borewit/text-codec@0.2.2': resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} @@ -2040,9 +2037,6 @@ packages: '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - '@tootallnate/quickjs-emscripten@0.23.0': - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - '@trysound/sax@0.2.0': resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -2251,9 +2245,6 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - '@types/bun@1.3.14': - resolution: {integrity: sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw==} - '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} @@ -2622,10 +2613,6 @@ packages: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} - ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} - astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -2684,10 +2671,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - basic-ftp@5.3.1: - resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==} - engines: {node: '>=10.0.0'} - bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -2756,9 +2739,6 @@ packages: builtins@5.1.0: resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} - bun-types@1.3.14: - resolution: {integrity: sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ==} - bytes@3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} @@ -3130,10 +3110,6 @@ packages: data-uri-to-buffer@2.0.2: resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} - data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} - data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} @@ -3217,10 +3193,6 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -3320,8 +3292,9 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electrobun@1.18.1: - resolution: {integrity: sha512-tgZ+WKGskn/1/Y5i1mpVCCkgRa1O31Tz7MIArBTK44GfPzT43uOq9c/HvxdQGrLeZV8ZvjK1lQrwqSXCgh6tvA==} + electrobun@2.0.1: + resolution: {integrity: sha512-1+OjJ0tMemjVrUEsh/AhmxnqUNpyCfJslCbcWOvkogFJuNVMmTlWMzyZem/Ts/7lg8f7ULWu8uuQBsKeGQsu7A==} + engines: {node: '>=18'} hasBin: true electron-builder-squirrel-windows@26.7.0: @@ -3465,11 +3438,6 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} - escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - eslint-config-prettier@10.1.8: resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true @@ -3632,11 +3600,6 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - esquery@1.7.0: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} @@ -3929,10 +3892,6 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-uri@6.0.5: - resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} - engines: {node: '>= 14'} - gifwrap@0.10.1: resolution: {integrity: sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==} @@ -4503,10 +4462,6 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} @@ -4858,10 +4813,6 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} - netmask@2.1.1: - resolution: {integrity: sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==} - engines: {node: '>= 0.4.0'} - no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -5017,14 +4968,6 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - pac-proxy-agent@7.2.0: - resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} - engines: {node: '>= 14'} - - pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} - package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -5303,10 +5246,6 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} - proxy-agent@6.5.0: - resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} - engines: {node: '>= 14'} - proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -6260,9 +6199,6 @@ packages: three@0.159.0: resolution: {integrity: sha512-eCmhlLGbBgucuo4VEA9IO3Qpc7dh8Bd4VKzr7WfW4+8hMcIfoAVi1ev0pJYN9PTTsCslbcKgBwr2wNZ1EvLInA==} - three@0.165.0: - resolution: {integrity: sha512-cc96IlVYGydeceu0e5xq70H8/yoVT/tXBxV/W8A/U6uOq7DXc4/s1Mkmnu6SqoYGhSRWWYFOhVwvq6V0VtbplA==} - three@0.176.0: resolution: {integrity: sha512-PWRKYWQo23ojf9oZSlRGH8K09q7nRSWx6LY/HF/UUrMdYgN9i1e2OwJYHoQjwc6HF/4lvvYLC5YC1X8UJL2ZpA==} @@ -6990,8 +6926,6 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@babylonjs/core@7.54.3': {} - '@borewit/text-codec@0.2.2': {} '@cloudflare/kv-asset-handler@0.3.4': @@ -8677,8 +8611,6 @@ snapshots: '@tokenizer/token@0.3.0': {} - '@tootallnate/quickjs-emscripten@0.23.0': {} - '@trysound/sax@0.2.0': {} '@tsparticles/basic@3.9.1': @@ -8930,10 +8862,6 @@ snapshots: dependencies: '@babel/types': 7.29.0 - '@types/bun@1.3.14': - dependencies: - bun-types: 1.3.14 - '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.2.0 @@ -9432,10 +9360,6 @@ snapshots: assert-plus@1.0.0: optional: true - ast-types@0.13.4: - dependencies: - tslib: 2.8.1 - astral-regex@2.0.0: optional: true @@ -9484,8 +9408,6 @@ snapshots: baseline-browser-mapping@2.11.4: {} - basic-ftp@5.3.1: {} - bl@4.1.0: dependencies: buffer: 5.7.1 @@ -9594,10 +9516,6 @@ snapshots: dependencies: semver: 7.7.3 - bun-types@1.3.14: - dependencies: - '@types/node': 25.2.0 - bytes@3.0.0: {} bytes@3.1.2: {} @@ -9974,8 +9892,6 @@ snapshots: data-uri-to-buffer@2.0.2: {} - data-uri-to-buffer@6.0.2: {} - data-view-buffer@1.0.2: dependencies: call-bound: 1.0.4 @@ -10048,12 +9964,6 @@ snapshots: defu@6.1.4: {} - degenerator@5.0.1: - dependencies: - ast-types: 0.13.4 - escodegen: 2.1.0 - esprima: 4.0.1 - delayed-stream@1.0.0: {} depd@2.0.0: {} @@ -10167,16 +10077,7 @@ snapshots: dependencies: jake: 10.9.4 - electrobun@1.18.1: - dependencies: - '@babylonjs/core': 7.54.3 - '@types/bun': 1.3.14 - png-to-ico: 2.1.8 - proxy-agent: 6.5.0 - rcedit: 4.0.1 - three: 0.165.0 - transitivePeerDependencies: - - supports-color + electrobun@2.0.1: {} electron-builder-squirrel-windows@26.7.0(dmg-builder@26.7.0): dependencies: @@ -10478,14 +10379,6 @@ snapshots: escape-string-regexp@5.0.0: {} - escodegen@2.1.0: - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)): dependencies: eslint: 9.39.2(jiti@2.6.1) @@ -10753,8 +10646,6 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 3.4.3 - esprima@4.0.1: {} - esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -11106,14 +10997,6 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-uri@6.0.5: - dependencies: - basic-ftp: 5.3.1 - data-uri-to-buffer: 6.0.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - gifwrap@0.10.1: dependencies: image-q: 4.0.0 @@ -11724,8 +11607,6 @@ snapshots: dependencies: yallist: 4.0.0 - lru-cache@7.18.3: {} - magic-string@0.25.9: dependencies: sourcemap-codec: 1.4.8 @@ -12268,8 +12149,6 @@ snapshots: negotiator@1.0.0: {} - netmask@2.1.1: {} - no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -12457,24 +12336,6 @@ snapshots: p-try@2.2.0: {} - pac-proxy-agent@7.2.0: - dependencies: - '@tootallnate/quickjs-emscripten': 0.23.0 - agent-base: 7.1.4 - debug: 4.4.3 - get-uri: 6.0.5 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - pac-resolver@7.0.1: - dependencies: - degenerator: 5.0.1 - netmask: 2.1.1 - package-json-from-dist@1.0.1: {} pako@1.0.11: {} @@ -12784,19 +12645,6 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 - proxy-agent@6.5.0: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - lru-cache: 7.18.3 - pac-proxy-agent: 7.2.0 - proxy-from-env: 1.1.0 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - proxy-from-env@1.1.0: {} pump@3.0.3: @@ -14048,8 +13896,6 @@ snapshots: three@0.159.0: {} - three@0.165.0: {} - three@0.176.0: {} three@0.179.1: {} diff --git a/public/appupdate.js b/public/appupdate.js index 214115b2..bcfd3522 100644 --- a/public/appupdate.js +++ b/public/appupdate.js @@ -4,7 +4,7 @@ import https from "node:https"; import os from "node:os"; import path from "node:path"; import process from "node:process"; -import { Utils } from "electrobun/bun"; +import { Utils } from "electrobun/main"; import { launchMacInstaller } from "./macappupdate.js"; import { launchWindowsInstaller } from "./winappupdate.js"; import { scheduleAppRestart } from "./updater-runner.js"; diff --git a/scripts/build-macos.mjs b/scripts/build-macos.mjs index bacf15a5..55df7d77 100644 --- a/scripts/build-macos.mjs +++ b/scripts/build-macos.mjs @@ -5,107 +5,49 @@ import { getReleaseArch, isBundleCefEnabled } from "./release-artifact-utils.mjs const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const hostArch = getReleaseArch(process.arch); -const targetArchs = process.env.ELECTROBUN_TARGET_ARCH - ? [getReleaseArch(process.env.ELECTROBUN_TARGET_ARCH)] - : ["arm64", "x64"]; +const requestedArch = process.env.ELECTROBUN_TARGET_ARCH + ? getReleaseArch(process.env.ELECTROBUN_TARGET_ARCH) + : hostArch; const bundleCef = isBundleCefEnabled(); -function canRunUnderArch(archFlag) { - const result = spawnSync("arch", [archFlag, "true"], { - encoding: "utf8", - stdio: ["ignore", "pipe", "pipe"], - }); - return result.status === 0; +if (requestedArch !== hostArch) { + console.error( + `Electrobun 2 builds only for the current host (${hostArch}). Cannot build macOS ${requestedArch} from this machine. Electrobun 2.0.1 does not publish macOS x64 cores.`, + ); + process.exit(1); } -function run(command, args, options = {}) { - const result = spawnSync(command, args, { - cwd: rootDir, - stdio: "inherit", - env: process.env, - ...options, - }); - - if (result.status !== 0) { - process.exit(result.status ?? 1); - } -} - -function buildElectrobunEnv(targetArch) { - return { - ...process.env, - ELECTROBUN_BUILD_ENV: "stable", - ELECTROBUN_OS: "macos", - ELECTROBUN_ARCH: targetArch, - ELECTROBUN_FORCE_ARCH: targetArch, - ELECTROBUN_TARGET_ARCH: targetArch, - NODE_ENV: "production", - }; -} - -function getInvocation(targetArch) { - const env = buildElectrobunEnv(targetArch); - const runScript = path.join(rootDir, "scripts/run-electrobun-build.mjs"); - - if (targetArch === hostArch) { - return { command: "bun", args: [runScript], env }; - } - - if (targetArch === "x64" && hostArch === "arm64" && canRunUnderArch("-x86_64")) { - return { - command: "arch", - args: ["-x86_64", "bun", runScript], - env, - }; - } - - if (targetArch === "arm64" && hostArch === "x64") { - return { command: "bun", args: [runScript], env }; - } - - return null; -} - -const orderedTargets = [...targetArchs].sort((a, b) => { - if (a === hostArch) return -1; - if (b === hostArch) return 1; - return 0; -}); +const env = { + ...process.env, + ELECTROBUN_BUILD_ENV: "stable", + ELECTROBUN_OS: "macos", + ELECTROBUN_ARCH: hostArch, + ELECTROBUN_FORCE_ARCH: hostArch, + ELECTROBUN_TARGET_ARCH: hostArch, + NODE_ENV: "production", +}; console.log(`Host architecture: ${hostArch}`); console.log(`CEF bundling: ${bundleCef ? "enabled" : "disabled"}`); -console.log(`Build order: ${orderedTargets.join(", ")}`); +console.log( + `\n=== Building macOS ${hostArch} (cef=${bundleCef}) ===`, +); +console.log( + `ELECTROBUN_BUILD_ENV=stable ELECTROBUN_OS=macos ELECTROBUN_ARCH=${hostArch} ELECTROBUN_BUNDLE_CEF=${bundleCef}\n`, +); -let builtCount = 0; +const result = spawnSync( + "bun", + [path.join(rootDir, "scripts/run-electrobun-build.mjs")], + { + cwd: rootDir, + stdio: "inherit", + env, + }, +); -for (const targetArch of orderedTargets) { - const invocation = getInvocation(targetArch); - if (!invocation) { - console.error( - `Cannot build macOS ${targetArch} from host ${hostArch}.`, - ); - continue; - } - - console.log(`\n=== Building macOS ${targetArch} (host ${hostArch}, cef=${bundleCef}) ===`); - console.log( - `ELECTROBUN_BUILD_ENV=stable ELECTROBUN_OS=macos ELECTROBUN_ARCH=${targetArch} ELECTROBUN_BUNDLE_CEF=${bundleCef}\n`, - ); - - run(invocation.command, invocation.args, { env: invocation.env }); - builtCount += 1; +if (result.status !== 0) { + process.exit(result.status ?? 1); } -if (builtCount === 0) { - console.error("No macOS architectures were built."); - process.exit(1); -} - -if (builtCount < targetArchs.length) { - console.error( - `Built ${builtCount}/${targetArchs.length} macOS architectures.`, - ); - process.exit(1); -} - -console.log(`\nBuilt macOS architectures: ${orderedTargets.join(", ")}`); +console.log(`\nBuilt macOS architecture: ${hostArch}`); diff --git a/scripts/ensure-electrobun-core.mjs b/scripts/ensure-electrobun-core.mjs deleted file mode 100644 index 1881010a..00000000 --- a/scripts/ensure-electrobun-core.mjs +++ /dev/null @@ -1,131 +0,0 @@ -import { - createWriteStream, - existsSync, - mkdirSync, - readdirSync, - unlinkSync, -} from "node:fs"; -import { spawnSync } from "node:child_process"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import { getReleaseArch } from "./release-artifact-utils.mjs"; -import { fixMacosHeaderpad } from "./fix-macos-headerpad.mjs"; - -const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); -const electrobunDir = path.join(rootDir, "node_modules/electrobun"); -const electrobunVersion = JSON.parse( - await Bun.file(path.join(electrobunDir, "package.json")).text(), -).version; - -function getPlatformPaths(targetOS, targetArch) { - const binExt = targetOS === "win" ? ".exe" : ""; - const platformDistDir = path.join( - electrobunDir, - `dist-${targetOS}-${targetArch}`, - ); - - return { - platformDistDir, - bunBinary: path.join(platformDistDir, "bun") + binExt, - bsdiff: path.join(platformDistDir, "bsdiff") + binExt, - bspatch: path.join(platformDistDir, "bspatch") + binExt, - launcher: path.join(platformDistDir, "launcher") + binExt, - nativeWrapperMacos: path.join(platformDistDir, "libNativeWrapper.dylib"), - }; -} - -async function downloadFile(url, destination) { - const response = await fetch(url); - if (!response.ok) { - throw new Error(`Failed to download ${url}: ${response.status} ${response.statusText}`); - } - - mkdirSync(path.dirname(destination), { recursive: true }); - const fileStream = createWriteStream(destination); - const reader = response.body?.getReader(); - if (!reader) { - throw new Error(`No response body for ${url}`); - } - - while (true) { - const { done, value } = await reader.read(); - if (done) break; - fileStream.write(Buffer.from(value)); - } - - await new Promise((resolve, reject) => { - fileStream.end((error) => (error ? reject(error) : resolve())); - }); -} - -function extractTarGz(tarPath, destination) { - mkdirSync(destination, { recursive: true }); - const result = spawnSync("tar", ["-xzf", tarPath, "-C", destination], { - stdio: "inherit", - }); - if (result.status !== 0) { - throw new Error(`tar extraction failed for ${tarPath}`); - } -} - -async function ensureCoreDependencies(targetOS, targetArch) { - const paths = getPlatformPaths(targetOS, targetArch); - const required = [ - paths.bunBinary, - paths.bsdiff, - paths.bspatch, - paths.launcher, - paths.nativeWrapperMacos, - ]; - - if (required.every((filePath) => existsSync(filePath))) { - console.log(`ensure-electrobun-core: ${targetOS}-${targetArch} already present`); - return; - } - - const platformName = - targetOS === "macos" ? "darwin" : targetOS === "win" ? "win" : "linux"; - const url = `https://github.com/blackboardsh/electrobun/releases/download/v${electrobunVersion}/electrobun-core-${platformName}-${targetArch}.tar.gz`; - const tempFile = path.join( - electrobunDir, - `core-${targetOS}-${targetArch}-temp.tar.gz`, - ); - - console.log(`ensure-electrobun-core: downloading ${targetOS}-${targetArch}`); - console.log(url); - - await downloadFile(url, tempFile); - extractTarGz(tempFile, paths.platformDistDir); - - if (existsSync(tempFile)) { - unlinkSync(tempFile); - } - - const missing = required.filter((filePath) => !existsSync(filePath)); - if (missing.length > 0) { - const extracted = existsSync(paths.platformDistDir) - ? readdirSync(paths.platformDistDir) - : []; - throw new Error( - `Missing ${targetOS}-${targetArch} binaries after extract: ${missing.join(", ")}; extracted=${extracted.join(", ")}`, - ); - } - - console.log(`ensure-electrobun-core: ${targetOS}-${targetArch} ready`); -} - -const targetOS = "macos"; -const hostArch = getReleaseArch(process.arch); -const targetArch = getReleaseArch( - process.env.ELECTROBUN_TARGET_ARCH || - process.env.ELECTROBUN_FORCE_ARCH || - process.arch, -); - -const archesToEnsure = new Set([hostArch, targetArch]); -for (const arch of archesToEnsure) { - await ensureCoreDependencies(targetOS, arch); - // electrobun#485: x64 core binaries lack Mach-O headerpad and get corrupted - // by codesign; free a load-command slot before anything copies or signs them. - fixMacosHeaderpad(getPlatformPaths(targetOS, arch).platformDistDir); -} diff --git a/scripts/expand-macos-bundle.mjs b/scripts/expand-macos-bundle.mjs index 6559f8c8..56c90add 100644 --- a/scripts/expand-macos-bundle.mjs +++ b/scripts/expand-macos-bundle.mjs @@ -8,12 +8,12 @@ import { import path from "node:path"; import { spawnSync } from "node:child_process"; import { tmpdir } from "node:os"; -import { fileURLToPath } from "node:url"; -const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const buildEnv = process.env.ELECTROBUN_BUILD_ENV || "dev"; const targetOs = process.env.ELECTROBUN_OS || "macos"; -const wrapperPath = process.env.ELECTROBUN_WRAPPER_BUNDLE_PATH; +const wrapperPath = + process.env.ELECTROBUN_WRAPPER_BUNDLE_PATH || + process.env.ELECTROBUN_WRAPPER_PATH; if (buildEnv === "dev" || targetOs !== "macos") { console.log("expand-macos-bundle: skipping (dev or non-macOS build)"); @@ -21,7 +21,9 @@ if (buildEnv === "dev" || targetOs !== "macos") { } if (!wrapperPath || !existsSync(wrapperPath)) { - console.error("expand-macos-bundle: ELECTROBUN_WRAPPER_BUNDLE_PATH not set or missing"); + console.error( + "expand-macos-bundle: ELECTROBUN_WRAPPER_BUNDLE_PATH not set or missing", + ); process.exit(1); } @@ -45,30 +47,31 @@ if (!existsSync(tarZstPath)) { process.exit(0); } +function resolveZstdCommand() { + const which = spawnSync("which", ["zstd"], { encoding: "utf8" }); + if (which.status === 0 && which.stdout.trim()) { + return which.stdout.trim(); + } + + for (const candidate of ["/opt/homebrew/bin/zstd", "/usr/local/bin/zstd"]) { + if (existsSync(candidate)) { + return candidate; + } + } + + return null; +} + function decompressTarZst(inputPath, outputPath) { - const systemZstd = spawnSync("zstd", ["--version"], { encoding: "utf8" }); - if (systemZstd.status === 0) { - return spawnSync("zstd", ["-d", "-f", "-o", outputPath, inputPath], { + const zstd = resolveZstdCommand(); + if (zstd) { + return spawnSync(zstd, ["-d", "-f", "-o", outputPath, inputPath], { stdio: "inherit", }); } - const hostArch = process.arch === "arm64" ? "arm64" : "x64"; - const zigZstd = path.join( - rootDir, - "node_modules/electrobun/dist-macos-" + hostArch, - "zig-zstd", - ); - if (existsSync(zigZstd)) { - return spawnSync( - zigZstd, - ["decompress", "-i", inputPath, "-o", outputPath, "--no-timing"], - { stdio: "inherit" }, - ); - } - console.error( - "expand-macos-bundle: zstd not found (install zstd or use electrobun dist binaries)", + "expand-macos-bundle: zstd not found. Install it with `brew install zstd`.", ); process.exit(1); } diff --git a/scripts/expand-windows-installer.mjs b/scripts/expand-windows-installer.mjs index 1061c9bd..13527a82 100644 --- a/scripts/expand-windows-installer.mjs +++ b/scripts/expand-windows-installer.mjs @@ -8,43 +8,8 @@ import { } from "node:fs"; import path from "node:path"; import { spawnSync } from "node:child_process"; -import { fileURLToPath } from "node:url"; - -const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); -const electrobunDir = path.join(rootDir, "node_modules/electrobun"); function findZstdDecompressCommand() { - const hostArch = process.arch === "arm64" ? "arm64" : "x64"; - const zigCandidates = [ - path.join(electrobunDir, `dist-win-${hostArch}`, "zig-zstd.exe"), - path.join(electrobunDir, "dist-win-x64", "zig-zstd.exe"), - path.join(electrobunDir, `dist-macos-${hostArch}`, "zig-zstd"), - path.join(electrobunDir, "dist-macos-x64", "zig-zstd"), - path.join(electrobunDir, "dist-win-x64", "zig-zstd", "x64", "zig-zstd.exe"), - path.join(electrobunDir, "dist-win-x64", "zig-zstd", "arm64", "zig-zstd.exe"), - path.join(electrobunDir, "vendors", "zig-zstd", "x64", "zig-zstd.exe"), - path.join(electrobunDir, "vendors", "zig-zstd", "arm64", "zig-zstd.exe"), - ]; - - for (const candidate of zigCandidates) { - if (!existsSync(candidate)) { - continue; - } - - return { - kind: "zig-zstd", - command: candidate, - args: (inputPath, outputPath) => [ - "decompress", - "-i", - inputPath, - "-o", - outputPath, - "--no-timing", - ], - }; - } - const systemZstd = spawnSync("zstd", ["--version"], { encoding: "utf8", shell: process.platform === "win32", @@ -63,6 +28,35 @@ function findZstdDecompressCommand() { }; } + const extraPaths = [ + "/opt/homebrew/bin/zstd", + "/usr/local/bin/zstd", + path.join(process.env.ProgramFiles || "C:\\Program Files", "zstd", "zstd.exe"), + path.join( + process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)", + "zstd", + "zstd.exe", + ), + ]; + + for (const candidate of extraPaths) { + if (!existsSync(candidate)) { + continue; + } + + return { + kind: "system-zstd", + command: candidate, + args: (inputPath, outputPath) => [ + "-d", + "-f", + "-o", + outputPath, + inputPath, + ], + }; + } + return null; } @@ -70,7 +64,7 @@ function decompressTarZst(inputPath, outputPath) { const zstd = findZstdDecompressCommand(); if (!zstd) { throw new Error( - "expand-windows-installer: zstd not found (install zstd or use electrobun dist binaries)", + "expand-windows-installer: zstd not found. Install zstd and ensure it is on PATH.", ); } diff --git a/scripts/finalize-desktop-artifacts.mjs b/scripts/finalize-desktop-artifacts.mjs index 6b8db204..dd0e503a 100644 --- a/scripts/finalize-desktop-artifacts.mjs +++ b/scripts/finalize-desktop-artifacts.mjs @@ -128,30 +128,35 @@ function findMacDmgSource(arch) { } function findWindowsInstallerFiles() { - const buildRoot = getBuildRoot() - if (!existsSync(buildRoot)) { - return null - } + const searchDirs = [getBuildRoot(), artifactDir].filter((dir) => + existsSync(dir) + ) - for (const entry of readdirSync(buildRoot)) { - if (!entry.startsWith('stable-win-')) { + for (const searchDir of searchDirs) { + const files = walkFiles(searchDir) + const setupArchive = + files.find((filePath) => /-setup\.tar\.zst$/i.test(filePath)) || + files.find((filePath) => /\.tar\.zst$/i.test(filePath)) + + if (!setupArchive) { continue } - const platformDir = path.join(buildRoot, entry) - const files = walkFiles(platformDir) - const setupExe = files.find((filePath) => /-setup\.exe$/i.test(filePath)) - const setupArchive = files.find((filePath) => - /-setup\.tar\.zst$/i.test(filePath) + const setupExe = files.find( + (filePath) => + /-setup\.exe$/i.test(filePath) || + /setup\.exe$/i.test(path.basename(filePath)) ) const setupMetadata = files.find((filePath) => - /-setup\.metadata\.json$/i.test(filePath) + /\.metadata\.json$/i.test(filePath) + ) + const setupZip = files.find( + (filePath) => + /-setup\.zip$/i.test(filePath) || + /setup\.zip$/i.test(path.basename(filePath)) ) - const setupZip = files.find((filePath) => /-setup\.zip$/i.test(filePath)) - if (setupExe && setupArchive && setupMetadata) { - return { setupExe, setupArchive, setupMetadata, setupZip } - } + return { setupExe, setupArchive, setupMetadata, setupZip } } return null diff --git a/scripts/fix-macos-headerpad.mjs b/scripts/fix-macos-headerpad.mjs index cc673c37..3a136ec5 100644 --- a/scripts/fix-macos-headerpad.mjs +++ b/scripts/fix-macos-headerpad.mjs @@ -144,9 +144,10 @@ const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : null; const modulePath = fileURLToPath(import.meta.url); if (invokedPath === modulePath) { - const rootDir = path.resolve(path.dirname(modulePath), ".."); - const target = - process.argv[2] || - path.join(rootDir, "node_modules/electrobun/dist-macos-x64"); + const target = process.argv[2]; + if (!target) { + console.error("Usage: bun scripts/fix-macos-headerpad.mjs "); + process.exit(1); + } fixMacosHeaderpad(path.resolve(target)); } diff --git a/scripts/patch-electrobun-src.mjs b/scripts/patch-electrobun-src.mjs deleted file mode 100644 index 06568232..00000000 --- a/scripts/patch-electrobun-src.mjs +++ /dev/null @@ -1,350 +0,0 @@ -import { - cpSync, - existsSync, - mkdirSync, - readFileSync, - writeFileSync -} from 'node:fs' -import path from 'node:path' -import { fileURLToPath } from 'node:url' - -const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') -const electrobunDir = path.join(rootDir, 'node_modules/electrobun') -const sharedSrcDir = path.join(electrobunDir, 'src/shared') -const sharedDistDir = path.join(electrobunDir, 'dist/api/shared') - -if (!existsSync(sharedDistDir)) { - console.error('patch-electrobun-src: electrobun dist/api/shared not found') - process.exit(1) -} - -mkdirSync(sharedSrcDir, { recursive: true }) - -for (const fileName of [ - 'cef-version.ts', - 'bun-version.ts', - 'electrobun-version.ts', - 'naming.ts', - 'rpc.ts' -]) { - const source = path.join(sharedDistDir, fileName) - const destination = path.join(sharedSrcDir, fileName) - if (existsSync(source)) { - cpSync(source, destination) - } -} - -const platformPatch = `import { platform, arch } from "os"; - -export type SupportedOS = "macos" | "win" | "linux"; -export type SupportedArch = "arm64" | "x64"; - -const platformName = platform(); -const archName = arch(); - -export const OS: SupportedOS = (() => { - switch (platformName) { - case "win32": - return "win"; - case "darwin": - return "macos"; - case "linux": - return "linux"; - default: - throw new Error(\`Unsupported platform: \${platformName}\`); - } -})(); - -function normalizeForcedArch(value) { - if (value === "arm64" || value === "aarch64") { - return "arm64"; - } - if (value === "x64" || value === "amd64") { - return "x64"; - } - return null; -} - -export const ARCH: SupportedArch = (() => { - const forcedArch = normalizeForcedArch( - process.env.ELECTROBUN_FORCE_ARCH || process.env.ELECTROBUN_TARGET_ARCH, - ); - if (forcedArch) { - return forcedArch; - } - - if (OS === "win") { - return "x64"; - } - - switch (archName) { - case "arm64": - return "arm64"; - case "x64": - return "x64"; - default: - throw new Error(\`Unsupported architecture: \${archName}\`); - } -})(); - -export const HOST_ARCH: SupportedArch = (() => { - if (OS === "win") { - return "x64"; - } - - switch (archName) { - case "arm64": - return "arm64"; - case "x64": - return "x64"; - default: - throw new Error(\`Unsupported architecture: \${archName}\`); - } -})(); - -export function getPlatformOS(): SupportedOS { - return OS; -} - -export function getPlatformArch(): SupportedArch { - return ARCH; -} -` - -writeFileSync(path.join(sharedSrcDir, 'platform.ts'), platformPatch) - -const templatesDir = path.join(electrobunDir, 'src/cli/templates') -mkdirSync(templatesDir, { recursive: true }) -writeFileSync( - path.join(templatesDir, 'embedded.ts'), - `export function getTemplateNames() { - return []; -} - -export function getTemplate(name: string) { - throw new Error(\`Template not available in patched electrobun CLI: \${name}\`); -} -` -) - -const RCEDIT_RESOLVER_FN = `function resolveProjectRceditPkgPath(projectRoot) { - const candidates = [ - join(projectRoot, "node_modules/rcedit/package.json"), - join(projectRoot, "node_modules/electrobun/node_modules/rcedit/package.json"), - ]; - for (const candidate of candidates) { - if (existsSync(candidate)) { - return candidate; - } - } - throw new Error( - "rcedit not found under " + projectRoot + ". Install rcedit in the project (bun add -d rcedit).", - ); -}` - -const cliPath = path.join(electrobunDir, 'src/cli/index.ts') -let cliSource = readFileSync(cliPath, 'utf8') -if (!cliSource.includes('HOST_ARCH')) { - cliSource = cliSource.replace( - 'import { OS, ARCH } from "../shared/platform";', - 'import { OS, ARCH, HOST_ARCH } from "../shared/platform";' - ) - cliSource = cliSource.replace( - 'const hostPaths = getPlatformPaths(OS, ARCH);', - 'const hostPaths = getPlatformPaths(OS, HOST_ARCH);' - ) -} -if (!cliSource.includes('toolPaths')) { - cliSource = cliSource.replace( - 'const targetPaths = getPlatformPaths(currentTarget.os, currentTarget.arch);', - 'const targetPaths = getPlatformPaths(currentTarget.os, currentTarget.arch);\n\t\tconst toolPaths = getPlatformPaths(currentTarget.os, ARCH !== HOST_ARCH ? HOST_ARCH : ARCH);' - ) - cliSource = cliSource.replaceAll( - 'const zstdPath = targetPaths.ZSTD;', - 'const zstdPath = toolPaths.ZSTD;' - ) - cliSource = cliSource.replaceAll( - 'const bsdiffpath = targetPaths.BSDIFF;', - 'const bsdiffpath = toolPaths.BSDIFF;' - ) - cliSource = cliSource.replace( - 'zigAsarCli = join(targetPaths.BSPATCH).replace("bspatch", "zig-asar");', - 'zigAsarCli = join(toolPaths.BSPATCH).replace("bspatch", "zig-asar");' - ) - writeFileSync(cliPath, cliSource) - cliSource = readFileSync(cliPath, 'utf8') -} -if (!cliSource.includes('hookBunBinary')) { - cliSource = cliSource.replace( - `const hostPaths = getPlatformPaths(OS, HOST_ARCH); - - const result = Bun.spawnSync([hostPaths.BUN_BINARY, hookScript],`, - `const hostPaths = getPlatformPaths(OS, HOST_ARCH); - const hookBunBinary = existsSync(hostPaths.BUN_BINARY) - ? hostPaths.BUN_BINARY - : process.execPath; - - const result = Bun.spawnSync([hookBunBinary, hookScript],` - ) - cliSource = cliSource.replace( - 'console.error("Tried to run with bun at:", hostPaths.BUN_BINARY);', - 'console.error("Tried to run with bun at:", hookBunBinary);' - ) - writeFileSync(cliPath, cliSource) - cliSource = readFileSync(cliPath, 'utf8') -} - -if (!cliSource.includes('resolveProjectRceditPkgPath')) { - cliSource = cliSource.replaceAll( - 'const rceditPkgPath = require.resolve("rcedit/package.json");', - 'const rceditPkgPath = resolveProjectRceditPkgPath(projectRoot);' - ) - cliSource = cliSource.replace( - 'function getPlatformPaths(', - `${RCEDIT_RESOLVER_FN} - -function getPlatformPaths(` - ) - writeFileSync(cliPath, cliSource) - cliSource = readFileSync(cliPath, 'utf8') -} else { - cliSource = cliSource.replace( - /function resolveProjectRceditPkgPath\(projectRoot\) \{[\s\S]*?\n\}/m, - RCEDIT_RESOLVER_FN - ) - writeFileSync(cliPath, cliSource) -} - -const electrobunCjsPath = path.join(electrobunDir, 'bin/electrobun.cjs') -let electrobunCjs = readFileSync(electrobunCjsPath, 'utf8') - -if (!electrobunCjs.includes('farmcontrol-use-patched-cli')) { - electrobunCjs = electrobunCjs.replace( - `async function main() { - try { - const args = process.argv.slice(2); - const cliPath = await ensureCliBinary(); - - // Replace this process with the actual CLI - const child = spawn(cliPath, args, { - stdio: 'inherit', - cwd: process.cwd() - });`, - `async function main() { - try { - const args = process.argv.slice(2); - const patchedCliPath = join(electrobunDir, 'src', 'cli', 'index.ts'); - - if (existsSync(patchedCliPath)) { - // farmcontrol-use-patched-cli: bundled electrobun.exe cannot resolve project rcedit - const bunBinary = process.env.BUN_INSTALL - ? join(process.env.BUN_INSTALL, 'bin', 'bun' + binExt) - : 'bun'; - const child = spawn(bunBinary, [patchedCliPath, ...args], { - stdio: 'inherit', - cwd: process.cwd(), - env: process.env, - shell: platform === 'win', - }); - - child.on('exit', (code) => { - process.exit(code || 0); - }); - - child.on('error', (error) => { - console.error('Failed to start electrobun patched CLI:', error.message); - process.exit(1); - }); - - return; - } - - const cliPath = await ensureCliBinary(); - - // Replace this process with the actual CLI - const child = spawn(cliPath, args, { - stdio: 'inherit', - cwd: process.cwd() - });` - ) - writeFileSync(electrobunCjsPath, electrobunCjs) -} - -const rceditSrc = path.join(rootDir, 'node_modules/rcedit') -const rceditDest = path.join(electrobunDir, 'node_modules/rcedit') -if (existsSync(rceditSrc)) { - mkdirSync(path.join(electrobunDir, 'node_modules'), { recursive: true }) - cpSync(rceditSrc, rceditDest, { recursive: true, force: true }) -} - -function patchNativeWrapperPath(nativeTsPath) { - if (!existsSync(nativeTsPath)) { - return - } - - let source = readFileSync(nativeTsPath, 'utf8') - - if (source.includes('function resolveNativeWrapperPath()')) { - return - } - - if (!source.includes('existsSync')) { - if (source.includes('import { dirname, join } from "path";')) { - source = source.replace( - 'import { dirname, join } from "path";', - 'import { existsSync } from "fs";\nimport { dirname, join } from "path";' - ) - } else { - source = source.replace( - 'import { join } from "path";', - 'import { existsSync } from "fs";\nimport { dirname, join } from "path";' - ) - } - } else if (!source.includes('dirname')) { - source = source.replace( - 'import { join } from "path";', - 'import { dirname, join } from "path";' - ) - } - - const helper = ` -function resolveNativeWrapperPath() { -\tconst fileName = \`libNativeWrapper.\${suffix}\`; -\tconst candidates = [ -\t\tjoin(dirname(process.execPath), fileName), -\t\tjoin(process.cwd(), fileName), -\t]; -\tfor (const candidate of candidates) { -\t\tif (existsSync(candidate)) { -\t\t\treturn candidate; -\t\t} -\t} -\treturn candidates[0]!; -} -` - - source = source.replace( - 'export const native = (() => {', - `${helper}\nexport const native = (() => {` - ) - - source = source.replace( - /const nativeWrapperPath = join\((?:dirname\(process\.execPath\)|process\.cwd\(\)), `libNativeWrapper\.\$\{suffix\}`\);/, - 'const nativeWrapperPath = resolveNativeWrapperPath();' - ) - - writeFileSync(nativeTsPath, source) -} - -for (const distDir of ['dist', 'dist-macos-arm64', 'dist-win-x64']) { - patchNativeWrapperPath( - path.join(electrobunDir, distDir, 'api/bun/proc/native.ts') - ) -} - -const markerPath = path.join(electrobunDir, '.farmcontrol-electrobun-patched') -writeFileSync(markerPath, `patched-at=${new Date().toISOString()}\n`) - -console.log( - 'patch-electrobun-src: electrobun src/shared ready for cross-arch builds' -) diff --git a/scripts/patch-windows-binaries.mjs b/scripts/patch-windows-binaries.mjs index cc245505..8eb4fa68 100644 --- a/scripts/patch-windows-binaries.mjs +++ b/scripts/patch-windows-binaries.mjs @@ -3,7 +3,7 @@ import path from 'node:path' import { fileURLToPath } from 'node:url' export const WINDOWS_LAUNCHER_EXE = 'FarmControl.exe' -const SOURCE_LAUNCHER_EXE = 'launcher.exe' +const SOURCE_LAUNCHER_NAMES = ['launcher.exe', 'Farm Control.exe'] export function patchWindowsBinaries(appDir) { const binDir = path.join(appDir, 'bin') @@ -11,27 +11,33 @@ export function patchWindowsBinaries(appDir) { throw new Error(`patch-windows-binaries: bin directory not found at ${binDir}`) } - const sourcePath = path.join(binDir, SOURCE_LAUNCHER_EXE) const destPath = path.join(binDir, WINDOWS_LAUNCHER_EXE) + const sourcePath = SOURCE_LAUNCHER_NAMES.map((name) => + path.join(binDir, name) + ).find((candidate) => existsSync(candidate)) - if (existsSync(destPath) && !existsSync(sourcePath)) { + if (existsSync(destPath) && !sourcePath) { console.log(`patch-windows-binaries: ${WINDOWS_LAUNCHER_EXE} already present`) return } - if (!existsSync(sourcePath)) { - console.warn(`patch-windows-binaries: skipping missing ${sourcePath}`) + if (!sourcePath) { + console.warn( + `patch-windows-binaries: skipping; no launcher.exe or Farm Control.exe in ${binDir}` + ) return } - if (existsSync(destPath)) { + if (existsSync(destPath) && destPath !== sourcePath) { renameSync(destPath, `${destPath}.old`) } - renameSync(sourcePath, destPath) - console.log( - `patch-windows-binaries: renamed ${SOURCE_LAUNCHER_EXE} -> ${WINDOWS_LAUNCHER_EXE}` - ) + if (sourcePath !== destPath) { + renameSync(sourcePath, destPath) + console.log( + `patch-windows-binaries: renamed ${path.basename(sourcePath)} -> ${WINDOWS_LAUNCHER_EXE}` + ) + } } if (process.argv[1] === fileURLToPath(import.meta.url)) { diff --git a/scripts/pre-build.mjs b/scripts/pre-build.mjs index c756a7a2..56742fe3 100644 --- a/scripts/pre-build.mjs +++ b/scripts/pre-build.mjs @@ -12,6 +12,25 @@ const requiredFiles = [ "package.json", ]; +if (buildEnv !== "dev") { + const devkitDir = path.join(rootDir, ".hutch/devkit"); + if (!existsSync(devkitDir)) { + console.error( + "pre-build: .hutch/devkit is missing. Run `bunx electrobun sync` first.", + ); + process.exit(1); + } +} + +if (process.platform === "darwin" && buildEnv === "stable") { + const zstd = spawnSync("zstd", ["--version"], { encoding: "utf8" }); + if (zstd.status !== 0) { + console.warn( + "pre-build: zstd not found on PATH; macOS wrapper expansion may fail. Install with: brew install zstd", + ); + } +} + for (const relativePath of requiredFiles) { const filePath = path.join(rootDir, relativePath); if (!existsSync(filePath)) { diff --git a/scripts/run-electrobun-build.mjs b/scripts/run-electrobun-build.mjs index 53737d02..f15c5c37 100644 --- a/scripts/run-electrobun-build.mjs +++ b/scripts/run-electrobun-build.mjs @@ -1,15 +1,18 @@ +import { existsSync } from "node:fs"; import { spawnSync } from "node:child_process"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; import { getReleaseArch, isBundleCefEnabled } from "./release-artifact-utils.mjs"; const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); -const electrobunCli = path.join( +const electrobunBin = path.join( rootDir, - "node_modules/electrobun/src/cli/index.ts", + "node_modules/.bin", + process.platform === "win32" ? "electrobun.cmd" : "electrobun", ); const buildEnv = process.env.ELECTROBUN_BUILD_ENV || "stable"; +const hostArch = getReleaseArch(process.arch); const targetArch = getReleaseArch( process.env.ELECTROBUN_TARGET_ARCH || process.env.ELECTROBUN_FORCE_ARCH || @@ -17,14 +20,18 @@ const targetArch = getReleaseArch( ); const bundleCef = isBundleCefEnabled(); -const patchResult = spawnSync("bun", [path.join(rootDir, "scripts/patch-electrobun-src.mjs")], { - cwd: rootDir, - stdio: "inherit", - env: process.env, -}); +if (targetArch !== hostArch) { + console.error( + `run-electrobun-build: Electrobun 2 builds only for the current host (${hostArch}); cannot target ${targetArch}. Electrobun 2.0.1 does not publish macOS x64 cores.`, + ); + process.exit(1); +} -if (patchResult.status !== 0) { - process.exit(patchResult.status ?? 1); +if (!existsSync(electrobunBin)) { + console.error( + "run-electrobun-build: electrobun CLI not found. Run `bun install`.", + ); + process.exit(1); } const macosEffectsResult = spawnSync( @@ -52,26 +59,6 @@ if (process.platform === "darwin") { } } -const ensureCoreEnv = { - ...process.env, - ELECTROBUN_TARGET_ARCH: targetArch, - ELECTROBUN_FORCE_ARCH: targetArch, -}; - -const ensureCoreResult = spawnSync( - "bun", - [path.join(rootDir, "scripts/ensure-electrobun-core.mjs")], - { - cwd: rootDir, - stdio: "inherit", - env: ensureCoreEnv, - }, -); - -if (ensureCoreResult.status !== 0) { - process.exit(ensureCoreResult.status ?? 1); -} - const env = { ...process.env, ELECTROBUN_BUILD_ENV: buildEnv, @@ -83,16 +70,17 @@ const env = { }; console.log( - `run-electrobun-build: env=${buildEnv} os=macos arch=${targetArch} cef=${bundleCef} (host ${getReleaseArch(process.arch)})`, + `run-electrobun-build: env=${buildEnv} os=macos arch=${targetArch} cef=${bundleCef} (host ${hostArch})`, ); const result = spawnSync( - "bun", - [electrobunCli, "build", `--env=${buildEnv}`], + electrobunBin, + ["build", `--env=${buildEnv}`], { cwd: rootDir, stdio: "inherit", env, + shell: process.platform === "win32", }, ); diff --git a/src/desktop/appupdate.js b/src/desktop/appupdate.js index c37765df..3938b55a 100644 --- a/src/desktop/appupdate.js +++ b/src/desktop/appupdate.js @@ -4,7 +4,7 @@ import https from 'node:https' import os from 'node:os' import path from 'node:path' import process from 'node:process' -import { Utils } from 'electrobun/bun' +import { Utils } from 'electrobun/main' import { launchMacInstaller } from './macappupdate.js' import { launchWindowsInstaller } from './winappupdate.js' import { checkForDuplicateInstallations } from './check-duplicate-installations.js' diff --git a/src/desktop/menu.js b/src/desktop/menu.js index 277a7147..c26b8bce 100644 --- a/src/desktop/menu.js +++ b/src/desktop/menu.js @@ -1,4 +1,4 @@ -import { ApplicationMenu } from "electrobun/bun"; +import { ApplicationMenu } from "electrobun/main"; const SIDEBAR_MENU_ACTION_PREFIX = "sidebar-nav:"; diff --git a/src/desktop/rpc.js b/src/desktop/rpc.js index d495cd8a..33482ae2 100644 --- a/src/desktop/rpc.js +++ b/src/desktop/rpc.js @@ -1,4 +1,4 @@ -import { BrowserView } from 'electrobun/bun' +import { BrowserView } from 'electrobun/main' import { checkForCompletedUpdate, getRunningAppVersion, diff --git a/src/desktop/spotlight.js b/src/desktop/spotlight.js index 106624f0..1f0787c0 100644 --- a/src/desktop/spotlight.js +++ b/src/desktop/spotlight.js @@ -1,6 +1,6 @@ import path from 'node:path' import { fileURLToPath } from 'node:url' -import { BrowserWindow, GlobalShortcut } from 'electrobun/bun' +import { BrowserWindow, GlobalShortcut } from 'electrobun/main' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) diff --git a/src/desktop/store.js b/src/desktop/store.js index 0d7e790a..6294af32 100644 --- a/src/desktop/store.js +++ b/src/desktop/store.js @@ -1,7 +1,7 @@ import { existsSync } from "node:fs"; import path from "node:path"; import { mkdir, readFile, writeFile } from "node:fs/promises"; -import { Utils } from "electrobun/bun"; +import { Utils } from "electrobun/main"; const AUTH_SERVICE = "com.tombutcher.farmcontrol"; const AUTH_SECRET_NAME = "authSession"; diff --git a/src/desktop/window.js b/src/desktop/window.js index 8d07c83b..926fabaf 100644 --- a/src/desktop/window.js +++ b/src/desktop/window.js @@ -1,4 +1,4 @@ -import Electrobun, { BrowserWindow, Updater, Utils } from 'electrobun/bun' +import Electrobun, { BrowserWindow, Updater, Utils } from 'electrobun/main' import { applyApplicationMenu, setupApplicationMenuEvents } from './menu.js' import { applyMacOSWindowEffects, diff --git a/src/desktop/windows-work-area.js b/src/desktop/windows-work-area.js index 27143151..3734e5ec 100644 --- a/src/desktop/windows-work-area.js +++ b/src/desktop/windows-work-area.js @@ -1,4 +1,4 @@ -import { Screen } from 'electrobun/bun' +import { Screen } from 'electrobun/main' const FRAME_TOLERANCE_PX = 4 // Win32 DWM invisible borders sit outside the client work area; Electrobun's diff --git a/src/shims/electrobun-view.js b/src/shims/electrobun-view.js new file mode 100644 index 00000000..ada061a7 --- /dev/null +++ b/src/shims/electrobun-view.js @@ -0,0 +1,15 @@ +class Electroview { + static defineRPC() { + return { + request: async () => {}, + send() {}, + } + } + + constructor() {} +} + +const Electrobun = { Electroview } + +export { Electroview } +export default Electrobun diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..dfcb3ac2 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "bundler", + "allowJs": true, + "checkJs": false, + "noEmit": true, + "skipLibCheck": true, + "strict": false, + "baseUrl": ".", + "paths": { + "electrobun": [".hutch/devkit/api/index.d.ts"], + "electrobun/*": [".hutch/devkit/api/*"] + } + }, + "include": ["src", "electrobun.config.ts", "hutch.config.ts"] +} diff --git a/vite.config.js b/vite.config.js index 2594c1e5..b734933e 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,4 +1,6 @@ +import { existsSync } from 'node:fs' import { createRequire } from 'node:module' +import { pathToFileURL } from 'node:url' import react from '@vitejs/plugin-react' import { defineConfig } from 'vite' import eslintPlugin from 'vite-plugin-eslint' @@ -12,9 +14,32 @@ const svgo = require('vite-plugin-svgo') const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) +const electrobunViewShim = path.resolve(__dirname, 'src/shims/electrobun-view.js') const isCloudflare = process.env.VITE_DEPLOY_TARGET === 'cloudflare' +async function electrobunAliases() { + const devkit = path.resolve(__dirname, '.hutch/devkit') + const helpers = [ + path.join(devkit, 'api/config/electrobun-vite.ts'), + path.join(devkit, 'api/config/electrobun-vite.js') + ] + const helper = helpers.find((filePath) => existsSync(filePath)) + if (helper) { + const mod = await import(pathToFileURL(helper).href) + const createAliases = mod.electrobunViteAliases || mod.default + if (typeof createAliases === 'function') { + return createAliases(devkit) + } + } + + return { + 'electrobun/view': electrobunViewShim, + 'electrobun/main': electrobunViewShim, + 'electrobun/bun': electrobunViewShim + } +} + /** Resolve a package's ESM entry to an absolute path (pnpm-safe single instance). */ function esmEntry(id) { const cjs = require.resolve(id) @@ -42,12 +67,16 @@ const codemirrorSingletons = { '@lezer/highlight': esmEntry('@lezer/highlight') } -export default defineConfig({ +export default defineConfig(async () => { + const electrobun = await electrobunAliases() + + return { base: isCloudflare ? '/' : './', // Cloudflare Pages needs absolute paths; Electron needs relative for file:// resolve: { alias: { three: path.resolve(__dirname, 'node_modules/three'), - ...codemirrorSingletons + ...codemirrorSingletons, + ...electrobun }, dedupe: Object.keys(codemirrorSingletons) }, @@ -82,7 +111,10 @@ export default defineConfig({ '@lezer/lr', '@lezer/highlight', '@lezer/javascript', - '@lezer/xml' + '@lezer/xml', + 'electrobun/view', + 'electrobun/main', + 'electrobun/bun' ] }, plugins: [ @@ -174,4 +206,5 @@ export default defineConfig({ port: 5173, open: false } + } })