From 3dec49374b51d67fecdf93aec957f79504d4a76d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2026 23:29:08 +0000 Subject: [PATCH 1/3] build(deps): bump electron-store from 8.2.0 to 11.0.2 Bumps [electron-store](https://github.com/sindresorhus/electron-store) from 8.2.0 to 11.0.2. - [Release notes](https://github.com/sindresorhus/electron-store/releases) - [Commits](https://github.com/sindresorhus/electron-store/compare/v8.2.0...v11.0.2) --- updated-dependencies: - dependency-name: electron-store dependency-version: 11.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 248 +++++++++++++++++----------------------------- package.json | 2 +- 2 files changed, 93 insertions(+), 157 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c2e8df..35769ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "auto-launch": "^5.0.6", "electron-squirrel-startup": "^1.0.0", - "electron-store": "^8.1.0", + "electron-store": "^11.0.2", "node-hid": "3.4.0", "usb": "^2.11.0" }, @@ -1033,9 +1033,9 @@ } }, "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -1097,12 +1097,13 @@ "integrity": "sha512-yvtNHdWvtbYEiIazXAdp/NY+BBb65/DAseqlNiJQjOx9DynuzOYDbVLBJvuc0ve0VL9x6B3OHF6eH52y9hCBtQ==" }, "node_modules/atomically": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", - "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.1.1.tgz", + "integrity": "sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==", "license": "MIT", - "engines": { - "node": ">=10.12.0" + "dependencies": { + "stubborn-fs": "^2.0.0", + "when-exit": "^2.1.4" } }, "node_modules/auto-bind": { @@ -1300,24 +1301,35 @@ "optional": true }, "node_modules/conf": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", - "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", - "license": "MIT", - "dependencies": { - "ajv": "^8.6.3", - "ajv-formats": "^2.1.1", - "atomically": "^1.7.0", - "debounce-fn": "^4.0.0", - "dot-prop": "^6.0.1", - "env-paths": "^2.2.1", - "json-schema-typed": "^7.0.3", - "onetime": "^5.1.2", - "pkg-up": "^3.1.0", - "semver": "^7.3.5" + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-15.1.0.tgz", + "integrity": "sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==", + "license": "MIT", + "dependencies": { + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "atomically": "^2.0.3", + "debounce-fn": "^6.0.0", + "dot-prop": "^10.0.0", + "env-paths": "^3.0.0", + "json-schema-typed": "^8.0.1", + "semver": "^7.7.2", + "uint8array-extras": "^1.5.0" }, "engines": { - "node": ">=12" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conf/node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1380,15 +1392,15 @@ } }, "node_modules/debounce-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", - "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-6.0.0.tgz", + "integrity": "sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==", "license": "MIT", "dependencies": { - "mimic-fn": "^3.0.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1420,15 +1432,15 @@ "license": "ISC" }, "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-10.2.0.tgz", + "integrity": "sha512-BTJ9aZYL3vCfZlZOBLy9v8TUqWGQ0pzFnygKwFZt5udj6viBoFIBviKPUoZLDCPn1FoXffv6McQFDenrm5Krfw==", "license": "MIT", "dependencies": { - "is-obj": "^2.0.0" + "type-fest": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1478,25 +1490,16 @@ "license": "MIT" }, "node_modules/electron-store": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz", - "integrity": "sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-11.0.2.tgz", + "integrity": "sha512-4VkNRdN+BImL2KcCi41WvAYbh6zLX5AUTi4so68yPqiItjbgTjqpEnGAqasgnG+lB6GuAyUltKwVopp6Uv+gwQ==", "license": "MIT", "dependencies": { - "conf": "^10.2.0", - "type-fest": "^2.17.0" + "conf": "^15.0.2", + "type-fest": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-store/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=12.20" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1583,6 +1586,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -1901,15 +1905,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/isbinaryfile": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", @@ -1950,9 +1945,9 @@ "license": "MIT" }, "node_modules/json-schema-typed": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", - "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", "license": "BSD-2-Clause" }, "node_modules/jsonfile": { @@ -2121,20 +2116,10 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -2333,6 +2318,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -2348,15 +2334,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2449,79 +2427,6 @@ "node": ">= 14.15.0" } }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "license": "MIT", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/plist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz", @@ -2802,6 +2707,21 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/stubborn-fs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-2.0.0.tgz", + "integrity": "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==", + "license": "MIT", + "dependencies": { + "stubborn-utils": "^1.0.1" + } + }, + "node_modules/stubborn-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stubborn-utils/-/stubborn-utils-1.0.2.tgz", + "integrity": "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==", + "license": "MIT" + }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -2819,7 +2739,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", - "dev": true, "license": "MIT", "engines": { "node": ">=20" @@ -2909,7 +2828,6 @@ "version": "5.10.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.10.0.tgz", "integrity": "sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==", - "dev": true, "license": "(MIT OR CC0-1.0)", "dependencies": { "tagged-tag": "^1.0.0" @@ -2921,6 +2839,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/uint8array-extras": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.6.0.tgz", + "integrity": "sha512-8iAasVS4wUx0gPLjH8Xtz2PeDzTSiy8QiLGu2DT3X5GU+egFEQhpnbtkehbAwjvDcxIERmCYcysiODFmE3Ud0Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/undici": { "version": "7.29.1", "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.1.tgz", @@ -2974,6 +2904,12 @@ "node": ">=12.22.0 <13.0 || >=14.17.0" } }, + "node_modules/when-exit": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.5.tgz", + "integrity": "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==", + "license": "MIT" + }, "node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", diff --git a/package.json b/package.json index 63b84ac..a070f39 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "auto-launch": "^5.0.6", "electron-squirrel-startup": "^1.0.0", - "electron-store": "^8.1.0", + "electron-store": "^11.0.2", "node-hid": "3.4.0", "usb": "^2.11.0" }, From 8951525d00a28e643dfde0ba295e1f063d727754 Mon Sep 17 00:00:00 2001 From: marcmy <21000174+marcmy@users.noreply.github.com> Date: Sun, 11 Oct 2026 21:10:59 -0400 Subject: [PATCH 2/3] fix: initialize ESM-only electron-store before CommonJS app startup --- src/lib/legacyStore.js | 15 +++++++++++++ src/main.js | 14 +++++++++--- test/legacyStore.test.js | 35 +++++++++++++++++++++++++++++ test/mainBackendIntegration.test.js | 7 ++++++ test/run-tests.js | 1 + 5 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/lib/legacyStore.js create mode 100644 test/legacyStore.test.js diff --git a/src/lib/legacyStore.js b/src/lib/legacyStore.js new file mode 100644 index 0000000..053d247 --- /dev/null +++ b/src/lib/legacyStore.js @@ -0,0 +1,15 @@ +'use strict'; + +// Loading the ESM-only package during Electron's ready phase avoids forcing +// the rest of the CommonJS main process and preload scripts into ESM. +// Keep the default config.json location and key names unchanged. +async function loadLegacyStore(loadModule = () => import('electron-store')) { + const module = await loadModule(); + const Store = module && module.default; + if (typeof Store !== 'function') { + throw new TypeError('electron-store did not provide a default constructor'); + } + return new Store(); +} + +module.exports = { loadLegacyStore }; diff --git a/src/main.js b/src/main.js index 469a323..1047eb1 100644 --- a/src/main.js +++ b/src/main.js @@ -13,7 +13,7 @@ const { } = require('electron'); const fs = require('fs'); -const Store = require('electron-store'); +const { loadLegacyStore } = require('./lib/legacyStore'); const path = require('path'); const AutoLaunch = require('auto-launch'); const { execFile, spawn } = require('child_process'); @@ -93,7 +93,8 @@ const { } = require('./lib/updateInstaller'); const appPath = app.getAppPath(); -const legacyStore = new Store(); +// Initialized before any startup reads; the import is native ESM from a CommonJS main process. +let legacyStore; const assetsFolder = 'src/assets/'; const checkGuard = createCheckGuard(); const readMouseTelemetry = createMouseTelemetryReader({ @@ -1351,7 +1352,10 @@ function setupSettingsIpc() { }); } -app.whenReady().then(() => { +app.whenReady().then(async () => { + // electron-store v11 is ESM-only. Wait for the store before config migration, + // telemetry, update bookkeeping or any user-facing windows can access it. + legacyStore = await loadLegacyStore(); autolaunch = new AutoLaunch({ name: 'Razer Auto Polling Rate' }); const { settings, gameFolders } = loadConfig((message) => log(message, true)); @@ -1369,6 +1373,10 @@ app.whenReady().then(() => { scheduleUpdateChecks(); showPendingUpdateChangelog().catch((error) => log(`failed to show update changelog: ${error.message}`, true)); runLoop(); +}).catch((error) => { + // Never launch with an uninitialized store or overwrite legacy user settings. + console.error('Unable to initialize persisted settings:', error); + app.quit(); }); setupSettingsIpc(); diff --git a/test/legacyStore.test.js b/test/legacyStore.test.js new file mode 100644 index 0000000..1096eaf --- /dev/null +++ b/test/legacyStore.test.js @@ -0,0 +1,35 @@ +'use strict'; + +const test = require('node:test'); +const assert = require('node:assert/strict'); +const { loadLegacyStore } = require('../src/lib/legacyStore'); + +test('awaits the native ESM store constructor before returning', async () => { + let resolveImport; + const pending = new Promise((resolve) => { resolveImport = resolve; }); + const result = loadLegacyStore(() => pending); + let initialized = false; + result.then(() => { initialized = true; }); + await Promise.resolve(); + assert.equal(initialized, false); + resolveImport({ default: class Store { + constructor() { this.values = new Map([['autostart', true], ['mouseBatteryHistory', { mouse: 80 }]]); } + get(key, fallback) { return this.values.has(key) ? this.values.get(key) : fallback; } + set(key, value) { this.values.set(key, value); } + delete(key) { this.values.delete(key); } + has(key) { return this.values.has(key); } + } }); + const store = await result; + assert.equal(store.has('autostart'), true); + assert.equal(store.get('autostart'), true); + assert.deepEqual(store.get('mouseBatteryHistory', {}), { mouse: 80 }); + store.set('updates.lastCheckedAt', 1234); + assert.equal(store.get('updates.lastCheckedAt'), 1234); + store.delete('updates.lastCheckedAt'); + assert.equal(store.has('updates.lastCheckedAt'), false); +}); + +test('rejects module load errors and missing constructor instead of resetting settings', async () => { + await assert.rejects(loadLegacyStore(async () => { throw new Error('module missing'); }), /module missing/); + await assert.rejects(loadLegacyStore(async () => ({})), /default constructor/); +}); diff --git a/test/mainBackendIntegration.test.js b/test/mainBackendIntegration.test.js index f4e8027..af45a7a 100644 --- a/test/mainBackendIntegration.test.js +++ b/test/mainBackendIntegration.test.js @@ -27,6 +27,13 @@ test('main delegates mouse transport lifecycle to the preferred backend', () => assert.doesNotMatch(main, /getRazerReport\s*\(/); }); +test('main initializes electron-store v11 before consuming saved settings', () => { + const main = source(mainPath); + assert.doesNotMatch(main, /require\(['"]electron-store['"]\)/); + assert.match(main, /app\.whenReady\(\)\.then\(async\s*\(\)\s*=>\s*\{[\s\S]*?legacyStore\s*=\s*await loadLegacyStore\(\);[\s\S]*?loadConfig\(/); + assert.match(main, /Unable to initialize persisted settings/); +}); + test('bootstrap no longer launches an independent CrazyLight startup probe', () => { const bootstrap = source(bootstrapPath); diff --git a/test/run-tests.js b/test/run-tests.js index b85da58..0685486 100644 --- a/test/run-tests.js +++ b/test/run-tests.js @@ -8,6 +8,7 @@ require('./gameLibraries.test'); require('./gameActivity.test'); require('./githubReleaseClient.test'); require('./mainBackendIntegration.test'); +require('./legacyStore.test'); require('./mouseBackendRuntime.test'); require('./mouseStatusPresentation.test'); require('./mouseTelemetry.test'); From 15895625d82cf027c62e6958b7e0e66dc19b922b Mon Sep 17 00:00:00 2001 From: marcmy <21000174+marcmy@users.noreply.github.com> Date: Sun, 11 Oct 2026 21:13:01 -0400 Subject: [PATCH 3/3] ci: smoke-test electron-store ESM using real Electron and persisted settings --- .github/workflows/ci.yml | 2 ++ scripts/smoke-electron-store.cjs | 44 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 scripts/smoke-electron-store.cjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 800c3d7..3d9c54d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,8 @@ jobs: node --check src/bootstrap.js node --check src/main.js - run: npm test + - name: Smoke-test electron-store ESM with real Electron + run: npx --no-install electron scripts/smoke-electron-store.cjs build-windows: if: github.event_name == 'workflow_dispatch' || github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main') diff --git a/scripts/smoke-electron-store.cjs b/scripts/smoke-electron-store.cjs new file mode 100644 index 0000000..f98aaec --- /dev/null +++ b/scripts/smoke-electron-store.cjs @@ -0,0 +1,44 @@ +'use strict'; + +// Run with Electron, not node: verifies the ESM package can initialize in +// the real main process without changing an existing on-disk config.json. +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const os = require('node:os'); +const path = require('node:path'); +const { app } = require('electron'); +const { loadLegacyStore } = require('../src/lib/legacyStore'); + +const temp = fs.mkdtempSync(path.join(os.tmpdir(), 'razer-electron-store-smoke-')); +const seeded = { + autostart: true, + detection_mode: 'running', + lower_rate: 500, + mouseBatteryHistory: { 'mouse-A': 77 }, + updates: { pendingRelease: { tag_name: 'v1.2.3' } }, +}; +fs.writeFileSync(path.join(temp, 'config.json'), JSON.stringify(seeded), 'utf8'); +app.setPath('userData', temp); + +app.whenReady().then(async () => { + const store = await loadLegacyStore(); + assert.equal(store.get('autostart'), true); + assert.equal(store.get('detection_mode'), 'running'); + assert.equal(store.get('lower_rate'), 500); + assert.deepEqual(store.get('mouseBatteryHistory'), seeded.mouseBatteryHistory); + assert.deepEqual(store.get('updates.pendingRelease'), seeded.updates.pendingRelease); + // The same JSON path/key format must still be readable and writable. + store.set('updates.lastCheckedAt', 42); + assert.equal(store.get('updates.lastCheckedAt'), 42); + const disk = JSON.parse(fs.readFileSync(path.join(temp, 'config.json'), 'utf8')); + assert.equal(disk.autostart, true); + assert.deepEqual(disk.updates.pendingRelease, seeded.updates.pendingRelease); + assert.equal(disk.updates.lastCheckedAt, 42); + console.log('electron-store v11 startup and existing config migration OK'); + app.exit(0); +}).catch((error) => { + console.error('electron-store startup smoke test failed:', error); + app.exit(1); +}).finally(() => { + fs.rmSync(temp, { recursive: true, force: true }); +});