Compare commits
No commits in common. "e3f79cfd004d83fa5aa82023db5da536b905cb7b" and "bcb7460bf2e9feea81f4f6331cea811e9acbc513" have entirely different histories.
e3f79cfd00
...
bcb7460bf2
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,7 +2,6 @@
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.hutch
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
|
||||
3
Jenkinsfile
vendored
3
Jenkinsfile
vendored
@ -182,9 +182,6 @@ 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),
|
||||
|
||||
60
bun.lock
60
bun.lock
@ -84,7 +84,7 @@
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@vitejs/plugin-react": "^5.0.2",
|
||||
"concurrently": "^9.2.1",
|
||||
"electrobun": "2.0.1",
|
||||
"electrobun": "1.18.1",
|
||||
"electron": "^38.7.1",
|
||||
"electron-builder": "^26.0.12",
|
||||
"electron-packager": "^17.1.2",
|
||||
@ -187,6 +187,8 @@
|
||||
|
||||
"@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=="],
|
||||
@ -769,6 +771,8 @@
|
||||
|
||||
"@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=="],
|
||||
@ -875,6 +879,8 @@
|
||||
|
||||
"@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=="],
|
||||
@ -1025,6 +1031,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -1057,6 +1065,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -1091,6 +1101,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -1245,7 +1257,7 @@
|
||||
|
||||
"d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="],
|
||||
|
||||
"data-uri-to-buffer": ["data-uri-to-buffer@2.0.2", "", {}, "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA=="],
|
||||
"data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="],
|
||||
|
||||
"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=="],
|
||||
|
||||
@ -1279,6 +1291,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -1327,7 +1341,7 @@
|
||||
|
||||
"ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
|
||||
|
||||
"electrobun": ["electrobun@2.0.1", "", { "bin": { "electrobun": "bin/electrobun.cjs" } }, "sha512-1+OjJ0tMemjVrUEsh/AhmxnqUNpyCfJslCbcWOvkogFJuNVMmTlWMzyZem/Ts/7lg8f7ULWu8uuQBsKeGQsu7A=="],
|
||||
"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=="],
|
||||
|
||||
"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=="],
|
||||
|
||||
@ -1391,6 +1405,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -1427,6 +1443,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -1551,6 +1569,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -1643,6 +1663,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -1809,7 +1831,7 @@
|
||||
|
||||
"lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="],
|
||||
|
||||
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "3.1.1" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||
"lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
|
||||
|
||||
"magic-string": ["magic-string@0.25.9", "", { "dependencies": { "sourcemap-codec": "1.4.8" } }, "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ=="],
|
||||
|
||||
@ -1967,6 +1989,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -2035,6 +2059,10 @@
|
||||
|
||||
"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=="],
|
||||
@ -2165,6 +2193,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -2435,12 +2465,18 @@
|
||||
|
||||
"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=="],
|
||||
@ -2743,6 +2779,8 @@
|
||||
|
||||
"@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=="],
|
||||
@ -2853,6 +2891,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -2875,6 +2915,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -2885,6 +2927,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -2913,6 +2957,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -2927,8 +2973,6 @@
|
||||
|
||||
"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=="],
|
||||
@ -3063,6 +3107,8 @@
|
||||
|
||||
"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=="],
|
||||
@ -3187,6 +3233,8 @@
|
||||
|
||||
"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=="],
|
||||
|
||||
@ -14,6 +14,13 @@ 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: {
|
||||
@ -27,9 +34,18 @@ 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",
|
||||
},
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
export default {
|
||||
packageManager: "bun",
|
||||
};
|
||||
@ -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/build-macos-effects.mjs",
|
||||
"postinstall": "bun scripts/patch-electrobun-src.mjs && 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": "2.0.1",
|
||||
"electrobun": "1.18.1",
|
||||
"electron": "^38.7.1",
|
||||
"electron-builder": "^26.0.12",
|
||||
"electron-packager": "^17.1.2",
|
||||
|
||||
166
pnpm-lock.yaml
generated
166
pnpm-lock.yaml
generated
@ -249,8 +249,8 @@ importers:
|
||||
specifier: ^9.2.1
|
||||
version: 9.2.1
|
||||
electrobun:
|
||||
specifier: 2.0.1
|
||||
version: 2.0.1
|
||||
specifier: 1.18.1
|
||||
version: 1.18.1
|
||||
electron:
|
||||
specifier: ^38.7.1
|
||||
version: 38.8.0
|
||||
@ -517,6 +517,9 @@ 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==}
|
||||
|
||||
@ -2037,6 +2040,9 @@ 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'}
|
||||
@ -2245,6 +2251,9 @@ 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==}
|
||||
|
||||
@ -2613,6 +2622,10 @@ 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'}
|
||||
@ -2671,6 +2684,10 @@ 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==}
|
||||
|
||||
@ -2739,6 +2756,9 @@ 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'}
|
||||
@ -3110,6 +3130,10 @@ 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'}
|
||||
@ -3193,6 +3217,10 @@ 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'}
|
||||
@ -3292,9 +3320,8 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
hasBin: true
|
||||
|
||||
electrobun@2.0.1:
|
||||
resolution: {integrity: sha512-1+OjJ0tMemjVrUEsh/AhmxnqUNpyCfJslCbcWOvkogFJuNVMmTlWMzyZem/Ts/7lg8f7ULWu8uuQBsKeGQsu7A==}
|
||||
engines: {node: '>=18'}
|
||||
electrobun@1.18.1:
|
||||
resolution: {integrity: sha512-tgZ+WKGskn/1/Y5i1mpVCCkgRa1O31Tz7MIArBTK44GfPzT43uOq9c/HvxdQGrLeZV8ZvjK1lQrwqSXCgh6tvA==}
|
||||
hasBin: true
|
||||
|
||||
electron-builder-squirrel-windows@26.7.0:
|
||||
@ -3438,6 +3465,11 @@ 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
|
||||
@ -3600,6 +3632,11 @@ 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'}
|
||||
@ -3892,6 +3929,10 @@ 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==}
|
||||
|
||||
@ -4462,6 +4503,10 @@ 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==}
|
||||
|
||||
@ -4813,6 +4858,10 @@ 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==}
|
||||
|
||||
@ -4968,6 +5017,14 @@ 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==}
|
||||
|
||||
@ -5246,6 +5303,10 @@ 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==}
|
||||
|
||||
@ -6199,6 +6260,9 @@ 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==}
|
||||
|
||||
@ -6926,6 +6990,8 @@ 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':
|
||||
@ -8611,6 +8677,8 @@ snapshots:
|
||||
|
||||
'@tokenizer/token@0.3.0': {}
|
||||
|
||||
'@tootallnate/quickjs-emscripten@0.23.0': {}
|
||||
|
||||
'@trysound/sax@0.2.0': {}
|
||||
|
||||
'@tsparticles/basic@3.9.1':
|
||||
@ -8862,6 +8930,10 @@ 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
|
||||
@ -9360,6 +9432,10 @@ 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
|
||||
|
||||
@ -9408,6 +9484,8 @@ snapshots:
|
||||
|
||||
baseline-browser-mapping@2.11.4: {}
|
||||
|
||||
basic-ftp@5.3.1: {}
|
||||
|
||||
bl@4.1.0:
|
||||
dependencies:
|
||||
buffer: 5.7.1
|
||||
@ -9516,6 +9594,10 @@ 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: {}
|
||||
@ -9892,6 +9974,8 @@ 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
|
||||
@ -9964,6 +10048,12 @@ 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: {}
|
||||
@ -10077,7 +10167,16 @@ snapshots:
|
||||
dependencies:
|
||||
jake: 10.9.4
|
||||
|
||||
electrobun@2.0.1: {}
|
||||
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
|
||||
|
||||
electron-builder-squirrel-windows@26.7.0(dmg-builder@26.7.0):
|
||||
dependencies:
|
||||
@ -10379,6 +10478,14 @@ 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)
|
||||
@ -10646,6 +10753,8 @@ 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
|
||||
@ -10997,6 +11106,14 @@ 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
|
||||
@ -11607,6 +11724,8 @@ snapshots:
|
||||
dependencies:
|
||||
yallist: 4.0.0
|
||||
|
||||
lru-cache@7.18.3: {}
|
||||
|
||||
magic-string@0.25.9:
|
||||
dependencies:
|
||||
sourcemap-codec: 1.4.8
|
||||
@ -12149,6 +12268,8 @@ snapshots:
|
||||
|
||||
negotiator@1.0.0: {}
|
||||
|
||||
netmask@2.1.1: {}
|
||||
|
||||
no-case@3.0.4:
|
||||
dependencies:
|
||||
lower-case: 2.0.2
|
||||
@ -12336,6 +12457,24 @@ 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: {}
|
||||
@ -12645,6 +12784,19 @@ 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:
|
||||
@ -13896,6 +14048,8 @@ snapshots:
|
||||
|
||||
three@0.159.0: {}
|
||||
|
||||
three@0.165.0: {}
|
||||
|
||||
three@0.176.0: {}
|
||||
|
||||
three@0.179.1: {}
|
||||
|
||||
@ -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/main";
|
||||
import { Utils } from "electrobun/bun";
|
||||
import { launchMacInstaller } from "./macappupdate.js";
|
||||
import { launchWindowsInstaller } from "./winappupdate.js";
|
||||
import { scheduleAppRestart } from "./updater-runner.js";
|
||||
|
||||
@ -5,49 +5,107 @@ import { getReleaseArch, isBundleCefEnabled } from "./release-artifact-utils.mjs
|
||||
|
||||
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const hostArch = getReleaseArch(process.arch);
|
||||
const requestedArch = process.env.ELECTROBUN_TARGET_ARCH
|
||||
? getReleaseArch(process.env.ELECTROBUN_TARGET_ARCH)
|
||||
: hostArch;
|
||||
const targetArchs = process.env.ELECTROBUN_TARGET_ARCH
|
||||
? [getReleaseArch(process.env.ELECTROBUN_TARGET_ARCH)]
|
||||
: ["arm64", "x64"];
|
||||
const bundleCef = isBundleCefEnabled();
|
||||
|
||||
if (requestedArch !== hostArch) {
|
||||
function canRunUnderArch(archFlag) {
|
||||
const result = spawnSync("arch", [archFlag, "true"], {
|
||||
encoding: "utf8",
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
return result.status === 0;
|
||||
}
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
console.log(`Host architecture: ${hostArch}`);
|
||||
console.log(`CEF bundling: ${bundleCef ? "enabled" : "disabled"}`);
|
||||
console.log(`Build order: ${orderedTargets.join(", ")}`);
|
||||
|
||||
let builtCount = 0;
|
||||
|
||||
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 (builtCount === 0) {
|
||||
console.error("No macOS architectures were built.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (builtCount < targetArchs.length) {
|
||||
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.`,
|
||||
`Built ${builtCount}/${targetArchs.length} macOS architectures.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
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(
|
||||
`\n=== Building macOS ${hostArch} (cef=${bundleCef}) ===`,
|
||||
);
|
||||
console.log(
|
||||
`ELECTROBUN_BUILD_ENV=stable ELECTROBUN_OS=macos ELECTROBUN_ARCH=${hostArch} ELECTROBUN_BUNDLE_CEF=${bundleCef}\n`,
|
||||
);
|
||||
|
||||
const result = spawnSync(
|
||||
"bun",
|
||||
[path.join(rootDir, "scripts/run-electrobun-build.mjs")],
|
||||
{
|
||||
cwd: rootDir,
|
||||
stdio: "inherit",
|
||||
env,
|
||||
},
|
||||
);
|
||||
|
||||
if (result.status !== 0) {
|
||||
process.exit(result.status ?? 1);
|
||||
}
|
||||
|
||||
console.log(`\nBuilt macOS architecture: ${hostArch}`);
|
||||
console.log(`\nBuilt macOS architectures: ${orderedTargets.join(", ")}`);
|
||||
|
||||
131
scripts/ensure-electrobun-core.mjs
Normal file
131
scripts/ensure-electrobun-core.mjs
Normal file
@ -0,0 +1,131 @@
|
||||
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);
|
||||
}
|
||||
@ -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 ||
|
||||
process.env.ELECTROBUN_WRAPPER_PATH;
|
||||
const wrapperPath = process.env.ELECTROBUN_WRAPPER_BUNDLE_PATH;
|
||||
|
||||
if (buildEnv === "dev" || targetOs !== "macos") {
|
||||
console.log("expand-macos-bundle: skipping (dev or non-macOS build)");
|
||||
@ -21,9 +21,7 @@ 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);
|
||||
}
|
||||
|
||||
@ -47,31 +45,30 @@ 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 zstd = resolveZstdCommand();
|
||||
if (zstd) {
|
||||
return spawnSync(zstd, ["-d", "-f", "-o", outputPath, inputPath], {
|
||||
const systemZstd = spawnSync("zstd", ["--version"], { encoding: "utf8" });
|
||||
if (systemZstd.status === 0) {
|
||||
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 it with `brew install zstd`.",
|
||||
"expand-macos-bundle: zstd not found (install zstd or use electrobun dist binaries)",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -8,8 +8,43 @@ 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",
|
||||
@ -28,35 +63,6 @@ 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;
|
||||
}
|
||||
|
||||
@ -64,7 +70,7 @@ function decompressTarZst(inputPath, outputPath) {
|
||||
const zstd = findZstdDecompressCommand();
|
||||
if (!zstd) {
|
||||
throw new Error(
|
||||
"expand-windows-installer: zstd not found. Install zstd and ensure it is on PATH.",
|
||||
"expand-windows-installer: zstd not found (install zstd or use electrobun dist binaries)",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -128,35 +128,30 @@ function findMacDmgSource(arch) {
|
||||
}
|
||||
|
||||
function findWindowsInstallerFiles() {
|
||||
const searchDirs = [getBuildRoot(), artifactDir].filter((dir) =>
|
||||
existsSync(dir)
|
||||
)
|
||||
const buildRoot = getBuildRoot()
|
||||
if (!existsSync(buildRoot)) {
|
||||
return null
|
||||
}
|
||||
|
||||
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) {
|
||||
for (const entry of readdirSync(buildRoot)) {
|
||||
if (!entry.startsWith('stable-win-')) {
|
||||
continue
|
||||
}
|
||||
|
||||
const setupExe = files.find(
|
||||
(filePath) =>
|
||||
/-setup\.exe$/i.test(filePath) ||
|
||||
/setup\.exe$/i.test(path.basename(filePath))
|
||||
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 setupMetadata = files.find((filePath) =>
|
||||
/\.metadata\.json$/i.test(filePath)
|
||||
)
|
||||
const setupZip = files.find(
|
||||
(filePath) =>
|
||||
/-setup\.zip$/i.test(filePath) ||
|
||||
/setup\.zip$/i.test(path.basename(filePath))
|
||||
/-setup\.metadata\.json$/i.test(filePath)
|
||||
)
|
||||
const setupZip = files.find((filePath) => /-setup\.zip$/i.test(filePath))
|
||||
|
||||
return { setupExe, setupArchive, setupMetadata, setupZip }
|
||||
if (setupExe && setupArchive && setupMetadata) {
|
||||
return { setupExe, setupArchive, setupMetadata, setupZip }
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
@ -144,10 +144,9 @@ const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : null;
|
||||
const modulePath = fileURLToPath(import.meta.url);
|
||||
|
||||
if (invokedPath === modulePath) {
|
||||
const target = process.argv[2];
|
||||
if (!target) {
|
||||
console.error("Usage: bun scripts/fix-macos-headerpad.mjs <directory>");
|
||||
process.exit(1);
|
||||
}
|
||||
const rootDir = path.resolve(path.dirname(modulePath), "..");
|
||||
const target =
|
||||
process.argv[2] ||
|
||||
path.join(rootDir, "node_modules/electrobun/dist-macos-x64");
|
||||
fixMacosHeaderpad(path.resolve(target));
|
||||
}
|
||||
|
||||
350
scripts/patch-electrobun-src.mjs
Normal file
350
scripts/patch-electrobun-src.mjs
Normal file
@ -0,0 +1,350 @@
|
||||
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'
|
||||
)
|
||||
@ -3,7 +3,7 @@ import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
export const WINDOWS_LAUNCHER_EXE = 'FarmControl.exe'
|
||||
const SOURCE_LAUNCHER_NAMES = ['launcher.exe', 'Farm Control.exe']
|
||||
const SOURCE_LAUNCHER_EXE = 'launcher.exe'
|
||||
|
||||
export function patchWindowsBinaries(appDir) {
|
||||
const binDir = path.join(appDir, 'bin')
|
||||
@ -11,33 +11,27 @@ 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) && !sourcePath) {
|
||||
if (existsSync(destPath) && !existsSync(sourcePath)) {
|
||||
console.log(`patch-windows-binaries: ${WINDOWS_LAUNCHER_EXE} already present`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!sourcePath) {
|
||||
console.warn(
|
||||
`patch-windows-binaries: skipping; no launcher.exe or Farm Control.exe in ${binDir}`
|
||||
)
|
||||
if (!existsSync(sourcePath)) {
|
||||
console.warn(`patch-windows-binaries: skipping missing ${sourcePath}`)
|
||||
return
|
||||
}
|
||||
|
||||
if (existsSync(destPath) && destPath !== sourcePath) {
|
||||
if (existsSync(destPath)) {
|
||||
renameSync(destPath, `${destPath}.old`)
|
||||
}
|
||||
|
||||
if (sourcePath !== destPath) {
|
||||
renameSync(sourcePath, destPath)
|
||||
console.log(
|
||||
`patch-windows-binaries: renamed ${path.basename(sourcePath)} -> ${WINDOWS_LAUNCHER_EXE}`
|
||||
)
|
||||
}
|
||||
renameSync(sourcePath, destPath)
|
||||
console.log(
|
||||
`patch-windows-binaries: renamed ${SOURCE_LAUNCHER_EXE} -> ${WINDOWS_LAUNCHER_EXE}`
|
||||
)
|
||||
}
|
||||
|
||||
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||
|
||||
@ -12,25 +12,6 @@ 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)) {
|
||||
|
||||
@ -1,18 +1,15 @@
|
||||
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 electrobunBin = path.join(
|
||||
const electrobunCli = path.join(
|
||||
rootDir,
|
||||
"node_modules/.bin",
|
||||
process.platform === "win32" ? "electrobun.cmd" : "electrobun",
|
||||
"node_modules/electrobun/src/cli/index.ts",
|
||||
);
|
||||
|
||||
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 ||
|
||||
@ -20,18 +17,14 @@ const targetArch = getReleaseArch(
|
||||
);
|
||||
const bundleCef = isBundleCefEnabled();
|
||||
|
||||
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);
|
||||
}
|
||||
const patchResult = spawnSync("bun", [path.join(rootDir, "scripts/patch-electrobun-src.mjs")], {
|
||||
cwd: rootDir,
|
||||
stdio: "inherit",
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
if (!existsSync(electrobunBin)) {
|
||||
console.error(
|
||||
"run-electrobun-build: electrobun CLI not found. Run `bun install`.",
|
||||
);
|
||||
process.exit(1);
|
||||
if (patchResult.status !== 0) {
|
||||
process.exit(patchResult.status ?? 1);
|
||||
}
|
||||
|
||||
const macosEffectsResult = spawnSync(
|
||||
@ -59,6 +52,26 @@ 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,
|
||||
@ -70,17 +83,16 @@ const env = {
|
||||
};
|
||||
|
||||
console.log(
|
||||
`run-electrobun-build: env=${buildEnv} os=macos arch=${targetArch} cef=${bundleCef} (host ${hostArch})`,
|
||||
`run-electrobun-build: env=${buildEnv} os=macos arch=${targetArch} cef=${bundleCef} (host ${getReleaseArch(process.arch)})`,
|
||||
);
|
||||
|
||||
const result = spawnSync(
|
||||
electrobunBin,
|
||||
["build", `--env=${buildEnv}`],
|
||||
"bun",
|
||||
[electrobunCli, "build", `--env=${buildEnv}`],
|
||||
{
|
||||
cwd: rootDir,
|
||||
stdio: "inherit",
|
||||
env,
|
||||
shell: process.platform === "win32",
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
useCallback
|
||||
} from 'react'
|
||||
import io from 'socket.io-client'
|
||||
import { message, Modal, Space, Button, Typography, Flex } from 'antd'
|
||||
import { message, Modal, Space, Button, Typography } from 'antd'
|
||||
import PropTypes from 'prop-types'
|
||||
import { AuthContext } from './AuthContext'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
@ -20,14 +20,12 @@ import LockIcon from '../../Icons/LockIcon'
|
||||
import config from '../../../config'
|
||||
import loglevel from 'loglevel'
|
||||
import { getModelByName } from '../../../database/ObjectModels'
|
||||
import ProgressDisplay from '../common/ProgressDisplay'
|
||||
const logger = loglevel.getLogger('ApiServerContext')
|
||||
logger.setLevel(config.logLevel)
|
||||
|
||||
const { Text } = Typography
|
||||
|
||||
const SPOTLIGHT_CACHE_TTL_MS = 10_000
|
||||
const RECONNECT_DELAYS_MS = [3000, 5000, 10000, 15000]
|
||||
|
||||
const spotlightCache = new Map()
|
||||
const runningSpotlightFetches = new Map()
|
||||
@ -136,22 +134,6 @@ const ApiServerProvider = ({ children }) => {
|
||||
const subscribedActivityServerSubscriptionsRef = useRef(new Set())
|
||||
const notificationListenersRef = useRef(new Set())
|
||||
const completedLaunchSessionsRef = useRef(new Set())
|
||||
const [connectionIssue, setConnectionIssue] = useState(false)
|
||||
const [reconnectProgress, setReconnectProgress] = useState(0)
|
||||
const [reconnectRemainingMs, setReconnectRemainingMs] = useState(
|
||||
RECONNECT_DELAYS_MS[0]
|
||||
)
|
||||
const [isReconnecting, setIsReconnecting] = useState(false)
|
||||
const reconnectAttemptRef = useRef(0)
|
||||
const reconnectTimerRef = useRef(null)
|
||||
const reconnectProgressTimerRef = useRef(null)
|
||||
const reconnectScheduledRef = useRef(false)
|
||||
const isReconnectingRef = useRef(false)
|
||||
const hasConnectedOnceRef = useRef(false)
|
||||
const connectToServerRef = useRef(null)
|
||||
const scheduleReconnectRef = useRef(null)
|
||||
const attemptReconnectRef = useRef(null)
|
||||
const teardownSocketRef = useRef(null)
|
||||
|
||||
const handleActivityUpdate = useCallback(async (data) => {
|
||||
logger.debug('Notifying activity update:', data)
|
||||
@ -317,138 +299,15 @@ const ApiServerProvider = ({ children }) => {
|
||||
[getUserSettings, messageApi]
|
||||
)
|
||||
|
||||
const clearReconnectTimers = useCallback(() => {
|
||||
if (reconnectTimerRef.current) {
|
||||
clearTimeout(reconnectTimerRef.current)
|
||||
reconnectTimerRef.current = null
|
||||
}
|
||||
if (reconnectProgressTimerRef.current) {
|
||||
clearInterval(reconnectProgressTimerRef.current)
|
||||
reconnectProgressTimerRef.current = null
|
||||
}
|
||||
}, [])
|
||||
|
||||
const resetReconnectState = useCallback(() => {
|
||||
clearReconnectTimers()
|
||||
reconnectAttemptRef.current = 0
|
||||
reconnectScheduledRef.current = false
|
||||
isReconnectingRef.current = false
|
||||
setIsReconnecting(false)
|
||||
setReconnectProgress(0)
|
||||
setReconnectRemainingMs(RECONNECT_DELAYS_MS[0])
|
||||
}, [clearReconnectTimers])
|
||||
|
||||
const startReconnectCountdown = useCallback(
|
||||
(delayMs) => {
|
||||
clearReconnectTimers()
|
||||
const startedAt = Date.now()
|
||||
setReconnectRemainingMs(delayMs)
|
||||
setReconnectProgress(0)
|
||||
setIsReconnecting(false)
|
||||
|
||||
reconnectProgressTimerRef.current = setInterval(() => {
|
||||
const elapsed = Date.now() - startedAt
|
||||
const remaining = Math.max(0, delayMs - elapsed)
|
||||
setReconnectRemainingMs(remaining)
|
||||
setReconnectProgress(Math.min(100, (elapsed / delayMs) * 100))
|
||||
}, 100)
|
||||
|
||||
reconnectTimerRef.current = setTimeout(() => {
|
||||
attemptReconnectRef.current?.()
|
||||
}, delayMs)
|
||||
},
|
||||
[clearReconnectTimers]
|
||||
)
|
||||
|
||||
const markConnectionLost = useCallback(() => {
|
||||
isReconnectingRef.current = false
|
||||
setIsReconnecting(false)
|
||||
setConnecting(false)
|
||||
setConnected(false)
|
||||
setConnectionIssue(true)
|
||||
setUserSettings(createEmptyUserSettings())
|
||||
setUserSettingsLoaded(false)
|
||||
clearSubscriptions()
|
||||
scheduleReconnectRef.current?.()
|
||||
}, [clearSubscriptions])
|
||||
|
||||
const scheduleReconnect = useCallback(() => {
|
||||
if (!token || authenticated != true) {
|
||||
return
|
||||
}
|
||||
if (isReconnectingRef.current || reconnectScheduledRef.current) {
|
||||
return
|
||||
}
|
||||
|
||||
reconnectScheduledRef.current = true
|
||||
setConnectionIssue(true)
|
||||
const delayIndex = Math.min(
|
||||
reconnectAttemptRef.current,
|
||||
RECONNECT_DELAYS_MS.length - 1
|
||||
)
|
||||
startReconnectCountdown(RECONNECT_DELAYS_MS[delayIndex])
|
||||
}, [token, authenticated, startReconnectCountdown])
|
||||
|
||||
const attemptReconnect = useCallback(() => {
|
||||
if (!token || authenticated != true) {
|
||||
return
|
||||
}
|
||||
if (isReconnectingRef.current) {
|
||||
return
|
||||
}
|
||||
|
||||
clearReconnectTimers()
|
||||
reconnectScheduledRef.current = false
|
||||
isReconnectingRef.current = true
|
||||
reconnectAttemptRef.current += 1
|
||||
setIsReconnecting(true)
|
||||
setReconnectProgress(100)
|
||||
setConnecting(true)
|
||||
setConnectionIssue(true)
|
||||
|
||||
if (socketRef.current) {
|
||||
if (!socketRef.current.connected) {
|
||||
socketRef.current.connect()
|
||||
}
|
||||
} else {
|
||||
connectToServerRef.current?.()
|
||||
}
|
||||
}, [token, authenticated, clearReconnectTimers])
|
||||
|
||||
const teardownSocket = useCallback(() => {
|
||||
resetReconnectState()
|
||||
setConnectionIssue(false)
|
||||
setConnecting(false)
|
||||
const socket = socketRef.current
|
||||
socketRef.current = null
|
||||
socket?.disconnect()
|
||||
}, [resetReconnectState])
|
||||
|
||||
scheduleReconnectRef.current = scheduleReconnect
|
||||
attemptReconnectRef.current = attemptReconnect
|
||||
teardownSocketRef.current = teardownSocket
|
||||
|
||||
const connectToServer = useCallback(() => {
|
||||
if (token && authenticated == true) {
|
||||
if (socketRef.current) {
|
||||
if (!socketRef.current.connected) {
|
||||
socketRef.current.connect()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
logger.debug('Token is available, connecting to api server...')
|
||||
|
||||
const newSocket = io(config.apiServerUrl, {
|
||||
reconnection: false,
|
||||
reconnectionAttempts: 0,
|
||||
forceNew: true,
|
||||
reconnectionAttempts: 3,
|
||||
timeout: 3000,
|
||||
auth: { type: 'user' }
|
||||
})
|
||||
if (typeof newSocket.io?.reconnection === 'function') {
|
||||
newSocket.io.reconnection(false)
|
||||
}
|
||||
|
||||
setConnecting(true)
|
||||
|
||||
@ -458,13 +317,6 @@ const ApiServerProvider = ({ children }) => {
|
||||
if (result?.valid !== true) {
|
||||
setConnecting(false)
|
||||
setError('Api Server authentication failed')
|
||||
if (hasConnectedOnceRef.current) {
|
||||
markConnectionLost()
|
||||
newSocket.disconnect()
|
||||
return
|
||||
}
|
||||
resetReconnectState()
|
||||
setConnectionIssue(false)
|
||||
newSocket.disconnect()
|
||||
return
|
||||
}
|
||||
@ -475,12 +327,9 @@ const ApiServerProvider = ({ children }) => {
|
||||
if (!newSocket.connected) {
|
||||
return
|
||||
}
|
||||
hasConnectedOnceRef.current = true
|
||||
setConnecting(false)
|
||||
setConnected(true)
|
||||
setError(null)
|
||||
setConnectionIssue(false)
|
||||
resetReconnectState()
|
||||
resubscribeActivityListeners(newSocket)
|
||||
})
|
||||
})
|
||||
@ -510,29 +359,23 @@ const ApiServerProvider = ({ children }) => {
|
||||
})
|
||||
})
|
||||
|
||||
newSocket.on('disconnect', (reason) => {
|
||||
if (socketRef.current !== newSocket) {
|
||||
return
|
||||
}
|
||||
|
||||
logger.debug('Api Server disconnected', reason)
|
||||
newSocket.on('disconnect', () => {
|
||||
logger.debug('Api Server disconnected')
|
||||
setError('Api Server disconnected')
|
||||
|
||||
if (reason === 'io client disconnect') {
|
||||
return
|
||||
}
|
||||
|
||||
markConnectionLost()
|
||||
clearSubscriptions()
|
||||
setConnected(false)
|
||||
setUserSettings(createEmptyUserSettings())
|
||||
setUserSettingsLoaded(false)
|
||||
})
|
||||
|
||||
newSocket.on('connect_error', (err) => {
|
||||
if (socketRef.current !== newSocket) {
|
||||
return
|
||||
}
|
||||
|
||||
logger.error('Api Server connection error:', err)
|
||||
messageApi.error('Api Server connection error: ' + err.message)
|
||||
setError('Api Server connection error')
|
||||
markConnectionLost()
|
||||
clearSubscriptions()
|
||||
setConnected(false)
|
||||
setUserSettings(createEmptyUserSettings())
|
||||
setUserSettingsLoaded(false)
|
||||
})
|
||||
|
||||
newSocket.on('error', (err) => {
|
||||
@ -545,42 +388,33 @@ const ApiServerProvider = ({ children }) => {
|
||||
}, [
|
||||
token,
|
||||
authenticated,
|
||||
messageApi,
|
||||
handleActivityUpdate,
|
||||
clearSubscriptions,
|
||||
getUserSettings,
|
||||
resubscribeActivityListeners,
|
||||
resetReconnectState,
|
||||
markConnectionLost
|
||||
resubscribeActivityListeners
|
||||
])
|
||||
|
||||
connectToServerRef.current = connectToServer
|
||||
|
||||
useEffect(() => {
|
||||
if (token && authenticated == true) {
|
||||
connectToServerRef.current?.()
|
||||
return
|
||||
connectToServer()
|
||||
} else if (!token && socketRef.current) {
|
||||
logger.debug('Token not available, disconnecting api server...')
|
||||
socketRef.current.disconnect()
|
||||
socketRef.current = null
|
||||
setUserSettings(createEmptyUserSettings())
|
||||
setUserSettingsLoaded(false)
|
||||
}
|
||||
|
||||
logger.debug('Token not available, disconnecting api server...')
|
||||
teardownSocketRef.current?.()
|
||||
setUserSettings(createEmptyUserSettings())
|
||||
setUserSettingsLoaded(false)
|
||||
}, [token, authenticated])
|
||||
|
||||
useEffect(() => {
|
||||
// Clean up function
|
||||
return () => {
|
||||
teardownSocketRef.current?.()
|
||||
if (socketRef.current) {
|
||||
logger.debug('Cleaning up api server connection...')
|
||||
socketRef.current.disconnect()
|
||||
socketRef.current = null
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!token || authenticated != true || !connectionIssue) {
|
||||
return
|
||||
}
|
||||
if (!reconnectScheduledRef.current && !isReconnectingRef.current) {
|
||||
scheduleReconnect()
|
||||
}
|
||||
}, [token, authenticated, connectionIssue, scheduleReconnect])
|
||||
}, [token, authenticated, connectToServer])
|
||||
|
||||
useEffect(() => {
|
||||
const handlePageVisible = () => {
|
||||
@ -595,7 +429,7 @@ const ApiServerProvider = ({ children }) => {
|
||||
|
||||
if (!socket.connected) {
|
||||
logger.debug('Page visible with disconnected socket, reconnecting...')
|
||||
attemptReconnect()
|
||||
socket.connect()
|
||||
return
|
||||
}
|
||||
|
||||
@ -614,7 +448,10 @@ const ApiServerProvider = ({ children }) => {
|
||||
logger.debug('Page restored from bfcache, reconnecting socket...')
|
||||
subscribedActivityServerSubscriptionsRef.current.clear()
|
||||
setConnected(false)
|
||||
teardownSocket()
|
||||
if (socketRef.current) {
|
||||
socketRef.current.disconnect()
|
||||
socketRef.current = null
|
||||
}
|
||||
connectToServer()
|
||||
}
|
||||
|
||||
@ -625,14 +462,7 @@ const ApiServerProvider = ({ children }) => {
|
||||
document.removeEventListener('visibilitychange', handlePageVisible)
|
||||
window.removeEventListener('pageshow', handlePageShow)
|
||||
}
|
||||
}, [
|
||||
token,
|
||||
authenticated,
|
||||
connectToServer,
|
||||
resubscribeActivityListeners,
|
||||
attemptReconnect,
|
||||
teardownSocket
|
||||
])
|
||||
}, [token, authenticated, connectToServer, resubscribeActivityListeners])
|
||||
|
||||
const setObjectActivity = (id, type, mode) => {
|
||||
logger.debug('Setting activity for', id, mode)
|
||||
@ -2121,15 +1951,9 @@ const ApiServerProvider = ({ children }) => {
|
||||
|
||||
const tryFetchRenderedFile = async () => {
|
||||
try {
|
||||
const result = await fetchTemplateDownload(
|
||||
id,
|
||||
content,
|
||||
object,
|
||||
type,
|
||||
{
|
||||
renderRequestId
|
||||
}
|
||||
)
|
||||
const result = await fetchTemplateDownload(id, content, object, type, {
|
||||
renderRequestId
|
||||
})
|
||||
finish(result)
|
||||
return true
|
||||
} catch (err) {
|
||||
@ -2636,11 +2460,6 @@ const ApiServerProvider = ({ children }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const reconnectSecondsRemaining = Math.max(
|
||||
1,
|
||||
Math.ceil(reconnectRemainingMs / 1000)
|
||||
)
|
||||
|
||||
// Sanitize a string so it is safe to use as a filename on most file systems
|
||||
const formatFileName = (name) => {
|
||||
if (!name || typeof name !== 'string') {
|
||||
@ -2734,45 +2553,6 @@ const ApiServerProvider = ({ children }) => {
|
||||
>
|
||||
{contextHolder}
|
||||
{children}
|
||||
<Modal
|
||||
title={
|
||||
<Space size={'middle'}>
|
||||
<ExclamationOctagonIcon />
|
||||
Connection Lost
|
||||
</Space>
|
||||
}
|
||||
open={Boolean(token) && authenticated == true && connectionIssue}
|
||||
style={{ maxWidth: 480 }}
|
||||
zIndex={3000}
|
||||
closable={false}
|
||||
centered
|
||||
maskClosable={false}
|
||||
getContainer={() => document.body}
|
||||
footer={[
|
||||
<Button
|
||||
key='reconnect'
|
||||
loading={isReconnecting}
|
||||
onClick={() => attemptReconnect()}
|
||||
>
|
||||
Reconnect
|
||||
</Button>
|
||||
]}
|
||||
>
|
||||
<Flex vertical gap='middle'>
|
||||
<Text>
|
||||
{isReconnecting
|
||||
? 'Reconnecting to the API server...'
|
||||
: `Lost connection to the API server. Reconnecting in ${reconnectSecondsRemaining} second${
|
||||
reconnectSecondsRemaining === 1 ? '' : 's'
|
||||
}...`}
|
||||
</Text>
|
||||
<ProgressDisplay
|
||||
percent={isReconnecting ? 0 : 100 - reconnectProgress}
|
||||
showInfo={false}
|
||||
status={'exception'}
|
||||
/>
|
||||
</Flex>
|
||||
</Modal>
|
||||
<Modal
|
||||
title={
|
||||
<Space size={'middle'}>
|
||||
|
||||
@ -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/main'
|
||||
import { Utils } from 'electrobun/bun'
|
||||
import { launchMacInstaller } from './macappupdate.js'
|
||||
import { launchWindowsInstaller } from './winappupdate.js'
|
||||
import { checkForDuplicateInstallations } from './check-duplicate-installations.js'
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ApplicationMenu } from "electrobun/main";
|
||||
import { ApplicationMenu } from "electrobun/bun";
|
||||
|
||||
const SIDEBAR_MENU_ACTION_PREFIX = "sidebar-nav:";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { BrowserView } from 'electrobun/main'
|
||||
import { BrowserView } from 'electrobun/bun'
|
||||
import {
|
||||
checkForCompletedUpdate,
|
||||
getRunningAppVersion,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { BrowserWindow, GlobalShortcut } from 'electrobun/main'
|
||||
import { BrowserWindow, GlobalShortcut } from 'electrobun/bun'
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = path.dirname(__filename)
|
||||
|
||||
@ -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/main";
|
||||
import { Utils } from "electrobun/bun";
|
||||
|
||||
const AUTH_SERVICE = "com.tombutcher.farmcontrol";
|
||||
const AUTH_SECRET_NAME = "authSession";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import Electrobun, { BrowserWindow, Updater, Utils } from 'electrobun/main'
|
||||
import Electrobun, { BrowserWindow, Updater, Utils } from 'electrobun/bun'
|
||||
import { applyApplicationMenu, setupApplicationMenuEvents } from './menu.js'
|
||||
import {
|
||||
applyMacOSWindowEffects,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Screen } from 'electrobun/main'
|
||||
import { Screen } from 'electrobun/bun'
|
||||
|
||||
const FRAME_TOLERANCE_PX = 4
|
||||
// Win32 DWM invisible borders sit outside the client work area; Electrobun's
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
class Electroview {
|
||||
static defineRPC() {
|
||||
return {
|
||||
request: async () => {},
|
||||
send() {},
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
const Electrobun = { Electroview }
|
||||
|
||||
export { Electroview }
|
||||
export default Electrobun
|
||||
@ -1,18 +0,0 @@
|
||||
{
|
||||
"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"]
|
||||
}
|
||||
@ -1,6 +1,4 @@
|
||||
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'
|
||||
@ -14,32 +12,9 @@ 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)
|
||||
@ -67,16 +42,12 @@ const codemirrorSingletons = {
|
||||
'@lezer/highlight': esmEntry('@lezer/highlight')
|
||||
}
|
||||
|
||||
export default defineConfig(async () => {
|
||||
const electrobun = await electrobunAliases()
|
||||
|
||||
return {
|
||||
export default defineConfig({
|
||||
base: isCloudflare ? '/' : './', // Cloudflare Pages needs absolute paths; Electron needs relative for file://
|
||||
resolve: {
|
||||
alias: {
|
||||
three: path.resolve(__dirname, 'node_modules/three'),
|
||||
...codemirrorSingletons,
|
||||
...electrobun
|
||||
...codemirrorSingletons
|
||||
},
|
||||
dedupe: Object.keys(codemirrorSingletons)
|
||||
},
|
||||
@ -111,10 +82,7 @@ export default defineConfig(async () => {
|
||||
'@lezer/lr',
|
||||
'@lezer/highlight',
|
||||
'@lezer/javascript',
|
||||
'@lezer/xml',
|
||||
'electrobun/view',
|
||||
'electrobun/main',
|
||||
'electrobun/bun'
|
||||
'@lezer/xml'
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
@ -206,5 +174,4 @@ export default defineConfig(async () => {
|
||||
port: 5173,
|
||||
open: false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user