فهرست منبع

Update to eslint 10.0.0

Lutz Roeder 1 ماه پیش
والد
کامیت
5d66a92538
13فایلهای تغییر یافته به همراه201 افزوده شده و 323 حذف شده
  1. 9 9
      eslint.config.js
  2. 61 215
      package-lock.json
  3. 4 4
      package.js
  4. 1 1
      package.json
  5. 0 9
      source/base.js
  6. 66 48
      source/browser.js
  7. 5 3
      source/desktop.mjs
  8. 5 3
      source/index.js
  9. 35 24
      source/view.js
  10. 2 2
      test/desktop.spec.js
  11. 8 0
      test/mock.js
  12. 3 3
      test/worker.js
  13. 2 2
      tools/mlir-script.js

+ 9 - 9
eslint.config.js

@@ -1,6 +1,4 @@
 
-import globals from 'globals';
-
 export default [
     {
         ignores: [
@@ -11,9 +9,15 @@ export default [
     {
         languageOptions: {
             globals: {
-                ...globals.es2020,
-                ...globals.browser,
-                ...globals.node,
+                atob: 'readonly',
+                BigInt: 'readonly',
+                console: 'readonly',
+                global: 'readonly',
+                process: 'readonly',
+                self: 'readonly',
+                TextDecoder: 'readonly',
+                TextEncoder: 'readonly',
+                window: 'readonly',
             },
             sourceType: 'module'
         },
@@ -237,10 +241,6 @@ export default [
     {
         files: ['source/index.js'],
         languageOptions: {
-            globals: {
-                ...globals.es2015,
-                ...globals.browser,
-            },
             sourceType: 'script',
             ecmaVersion: 2015
         },

+ 61 - 215
package-lock.json

@@ -17,7 +17,7 @@
                 "@playwright/test": "1.58.2",
                 "electron": "40.2.1",
                 "electron-builder": "26.7.0",
-                "eslint": "9.39.2"
+                "eslint": "10.0.0"
             }
         },
         "node_modules/@develar/schema-utils": {
@@ -465,131 +465,68 @@
             }
         },
         "node_modules/@eslint/config-array": {
-            "version": "0.21.1",
-            "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
-            "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
+            "version": "0.23.1",
+            "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.1.tgz",
+            "integrity": "sha512-uVSdg/V4dfQmTjJzR0szNczjOH/J+FyUMMjYtr07xFRXR7EDf9i1qdxrD0VusZH9knj1/ecxzCQQxyic5NzAiA==",
             "dev": true,
             "license": "Apache-2.0",
             "dependencies": {
-                "@eslint/object-schema": "^2.1.7",
+                "@eslint/object-schema": "^3.0.1",
                 "debug": "^4.3.1",
-                "minimatch": "^3.1.2"
+                "minimatch": "^10.1.1"
             },
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-            }
-        },
-        "node_modules/@eslint/config-array/node_modules/minimatch": {
-            "version": "3.1.2",
-            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-            "dev": true,
-            "license": "ISC",
-            "dependencies": {
-                "brace-expansion": "^1.1.7"
-            },
-            "engines": {
-                "node": "*"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             }
         },
         "node_modules/@eslint/config-helpers": {
-            "version": "0.4.2",
-            "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
-            "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz",
+            "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==",
             "dev": true,
             "license": "Apache-2.0",
             "dependencies": {
-                "@eslint/core": "^0.17.0"
+                "@eslint/core": "^1.1.0"
             },
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             }
         },
         "node_modules/@eslint/core": {
-            "version": "0.17.0",
-            "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
-            "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz",
+            "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==",
             "dev": true,
             "license": "Apache-2.0",
             "dependencies": {
                 "@types/json-schema": "^7.0.15"
             },
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-            }
-        },
-        "node_modules/@eslint/eslintrc": {
-            "version": "3.3.3",
-            "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
-            "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
-            "dev": true,
-            "license": "MIT",
-            "dependencies": {
-                "ajv": "^6.12.4",
-                "debug": "^4.3.2",
-                "espree": "^10.0.1",
-                "globals": "^14.0.0",
-                "ignore": "^5.2.0",
-                "import-fresh": "^3.2.1",
-                "js-yaml": "^4.1.1",
-                "minimatch": "^3.1.2",
-                "strip-json-comments": "^3.1.1"
-            },
-            "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-            },
-            "funding": {
-                "url": "https://opencollective.com/eslint"
-            }
-        },
-        "node_modules/@eslint/eslintrc/node_modules/minimatch": {
-            "version": "3.1.2",
-            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-            "dev": true,
-            "license": "ISC",
-            "dependencies": {
-                "brace-expansion": "^1.1.7"
-            },
-            "engines": {
-                "node": "*"
-            }
-        },
-        "node_modules/@eslint/js": {
-            "version": "9.39.2",
-            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz",
-            "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==",
-            "dev": true,
-            "license": "MIT",
-            "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-            },
-            "funding": {
-                "url": "https://eslint.org/donate"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             }
         },
         "node_modules/@eslint/object-schema": {
-            "version": "2.1.7",
-            "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
-            "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.1.tgz",
+            "integrity": "sha512-P9cq2dpr+LU8j3qbLygLcSZrl2/ds/pUpfnHNNuk5HW7mnngHs+6WSq5C9mO3rqRX8A1poxqLTC9cu0KOyJlBg==",
             "dev": true,
             "license": "Apache-2.0",
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             }
         },
         "node_modules/@eslint/plugin-kit": {
-            "version": "0.4.1",
-            "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
-            "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.0.tgz",
+            "integrity": "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==",
             "dev": true,
             "license": "Apache-2.0",
             "dependencies": {
-                "@eslint/core": "^0.17.0",
+                "@eslint/core": "^1.1.0",
                 "levn": "^0.4.1"
             },
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             }
         },
         "node_modules/@humanfs/core": {
@@ -987,6 +924,13 @@
                 "@types/ms": "*"
             }
         },
+        "node_modules/@types/esrecurse": {
+            "version": "4.3.1",
+            "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz",
+            "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/@types/estree": {
             "version": "1.0.8",
             "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -1788,16 +1732,6 @@
                 "node": ">= 0.4"
             }
         },
-        "node_modules/callsites": {
-            "version": "3.1.0",
-            "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-            "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-            "dev": true,
-            "license": "MIT",
-            "engines": {
-                "node": ">=6"
-            }
-        },
         "node_modules/chalk": {
             "version": "4.1.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -2749,33 +2683,30 @@
             }
         },
         "node_modules/eslint": {
-            "version": "9.39.2",
-            "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
-            "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
+            "version": "10.0.0",
+            "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.0.tgz",
+            "integrity": "sha512-O0piBKY36YSJhlFSG8p9VUdPV/SxxS4FYDWVpr/9GJuMaepzwlf4J8I4ov1b+ySQfDTPhc3DtLaxcT1fN0yqCg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "@eslint-community/eslint-utils": "^4.8.0",
-                "@eslint-community/regexpp": "^4.12.1",
-                "@eslint/config-array": "^0.21.1",
-                "@eslint/config-helpers": "^0.4.2",
-                "@eslint/core": "^0.17.0",
-                "@eslint/eslintrc": "^3.3.1",
-                "@eslint/js": "9.39.2",
-                "@eslint/plugin-kit": "^0.4.1",
+                "@eslint-community/regexpp": "^4.12.2",
+                "@eslint/config-array": "^0.23.0",
+                "@eslint/config-helpers": "^0.5.2",
+                "@eslint/core": "^1.1.0",
+                "@eslint/plugin-kit": "^0.6.0",
                 "@humanfs/node": "^0.16.6",
                 "@humanwhocodes/module-importer": "^1.0.1",
                 "@humanwhocodes/retry": "^0.4.2",
                 "@types/estree": "^1.0.6",
                 "ajv": "^6.12.4",
-                "chalk": "^4.0.0",
                 "cross-spawn": "^7.0.6",
                 "debug": "^4.3.2",
                 "escape-string-regexp": "^4.0.0",
-                "eslint-scope": "^8.4.0",
-                "eslint-visitor-keys": "^4.2.1",
-                "espree": "^10.4.0",
-                "esquery": "^1.5.0",
+                "eslint-scope": "^9.1.0",
+                "eslint-visitor-keys": "^5.0.0",
+                "espree": "^11.1.0",
+                "esquery": "^1.7.0",
                 "esutils": "^2.0.2",
                 "fast-deep-equal": "^3.1.3",
                 "file-entry-cache": "^8.0.0",
@@ -2785,8 +2716,7 @@
                 "imurmurhash": "^0.1.4",
                 "is-glob": "^4.0.0",
                 "json-stable-stringify-without-jsonify": "^1.0.1",
-                "lodash.merge": "^4.6.2",
-                "minimatch": "^3.1.2",
+                "minimatch": "^10.1.1",
                 "natural-compare": "^1.4.0",
                 "optionator": "^0.9.3"
             },
@@ -2794,7 +2724,7 @@
                 "eslint": "bin/eslint.js"
             },
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             },
             "funding": {
                 "url": "https://eslint.org/donate"
@@ -2809,61 +2739,50 @@
             }
         },
         "node_modules/eslint-scope": {
-            "version": "8.4.0",
-            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
-            "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+            "version": "9.1.0",
+            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.0.tgz",
+            "integrity": "sha512-CkWE42hOJsNj9FJRaoMX9waUFYhqY4jmyLFdAdzZr6VaCg3ynLYx4WnOdkaIifGfH4gsUcBTn4OZbHXkpLD0FQ==",
             "dev": true,
             "license": "BSD-2-Clause",
             "dependencies": {
+                "@types/esrecurse": "^4.3.1",
+                "@types/estree": "^1.0.8",
                 "esrecurse": "^4.3.0",
                 "estraverse": "^5.2.0"
             },
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             },
             "funding": {
                 "url": "https://opencollective.com/eslint"
             }
         },
         "node_modules/eslint-visitor-keys": {
-            "version": "4.2.1",
-            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
-            "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz",
+            "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==",
             "dev": true,
             "license": "Apache-2.0",
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             },
             "funding": {
                 "url": "https://opencollective.com/eslint"
             }
         },
-        "node_modules/eslint/node_modules/minimatch": {
-            "version": "3.1.2",
-            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-            "dev": true,
-            "license": "ISC",
-            "dependencies": {
-                "brace-expansion": "^1.1.7"
-            },
-            "engines": {
-                "node": "*"
-            }
-        },
         "node_modules/espree": {
-            "version": "10.4.0",
-            "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
-            "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+            "version": "11.1.0",
+            "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.0.tgz",
+            "integrity": "sha512-WFWYhO1fV4iYkqOOvq8FbqIhr2pYfoDY0kCotMkDeNtGpiGGkZ1iov2u8ydjtgM8yF8rzK7oaTbw2NAzbAbehw==",
             "dev": true,
             "license": "BSD-2-Clause",
             "dependencies": {
                 "acorn": "^8.15.0",
                 "acorn-jsx": "^5.3.2",
-                "eslint-visitor-keys": "^4.2.1"
+                "eslint-visitor-keys": "^5.0.0"
             },
             "engines": {
-                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+                "node": "^20.19.0 || ^22.13.0 || >=24"
             },
             "funding": {
                 "url": "https://opencollective.com/eslint"
@@ -3340,19 +3259,6 @@
                 "node": ">=10"
             }
         },
-        "node_modules/globals": {
-            "version": "14.0.0",
-            "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
-            "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
-            "dev": true,
-            "license": "MIT",
-            "engines": {
-                "node": ">=18"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
         "node_modules/globalthis": {
             "version": "1.0.4",
             "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
@@ -3606,23 +3512,6 @@
                 "node": ">= 4"
             }
         },
-        "node_modules/import-fresh": {
-            "version": "3.3.1",
-            "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
-            "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
-            "dev": true,
-            "license": "MIT",
-            "dependencies": {
-                "parent-module": "^1.0.0",
-                "resolve-from": "^4.0.0"
-            },
-            "engines": {
-                "node": ">=6"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
         "node_modules/imurmurhash": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -3915,13 +3804,6 @@
             "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
             "license": "MIT"
         },
-        "node_modules/lodash.merge": {
-            "version": "4.6.2",
-            "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
-            "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
-            "dev": true,
-            "license": "MIT"
-        },
         "node_modules/log-symbols": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
@@ -4525,19 +4407,6 @@
             "dev": true,
             "license": "BlueOak-1.0.0"
         },
-        "node_modules/parent-module": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-            "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
-            "dev": true,
-            "license": "MIT",
-            "dependencies": {
-                "callsites": "^3.0.0"
-            },
-            "engines": {
-                "node": ">=6"
-            }
-        },
         "node_modules/path-exists": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -4864,16 +4733,6 @@
             "dev": true,
             "license": "MIT"
         },
-        "node_modules/resolve-from": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-            "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-            "dev": true,
-            "license": "MIT",
-            "engines": {
-                "node": ">=4"
-            }
-        },
         "node_modules/responselike": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
@@ -5260,19 +5119,6 @@
                 "node": ">=8"
             }
         },
-        "node_modules/strip-json-comments": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
-            "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-            "dev": true,
-            "license": "MIT",
-            "engines": {
-                "node": ">=8"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
         "node_modules/sumchecker": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",

+ 4 - 4
package.js

@@ -102,19 +102,19 @@ const exec = async (command, encoding, cwd) => {
 
 const sleep = (delay) => {
     return new Promise((resolve) => {
-        setTimeout(resolve, delay);
+        global.setTimeout(resolve, delay);
     });
 };
 
 const request = async (url, init, status) => {
-    const response = await fetch(url, init);
+    const response = await global.fetch(url, init);
     if (status !== false && !response.ok) {
         throw new Error(`${response.status.toString()} ${response.statusText}`);
     }
     if (response.body) {
         const reader = response.body.getReader();
         let position = 0;
-        const stream = new ReadableStream({
+        const stream = new global.ReadableStream({
             start(controller) {
                 const read = async () => {
                     try {
@@ -135,7 +135,7 @@ const request = async (url, init, status) => {
                 read();
             }
         });
-        return new Response(stream, {
+        return new global.Response(stream, {
             status: response.status,
             statusText: response.statusText,
             headers: response.headers

+ 1 - 1
package.json

@@ -37,7 +37,7 @@
         "@playwright/test": "1.58.2",
         "electron": "40.2.1",
         "electron-builder": "26.7.0",
-        "eslint": "9.39.2"
+        "eslint": "10.0.0"
     },
     "build": {
         "extends": "publish/electron-builder.json"

+ 0 - 9
source/base.js

@@ -327,15 +327,6 @@ DataView.prototype.setComplexFloat64 = DataView.prototype.setComplexFloat64 || f
     }
 };
 
-if (typeof Element !== 'undefined' && Element.prototype && !Element.prototype.replaceChildren) {
-    Element.prototype.replaceChildren = function(...args) {
-        while (this.lastChild) {
-            this.removeChild(this.lastChild);
-        }
-        this.append(...args);
-    };
-}
-
 /* eslint-enable no-extend-native */
 
 base.BinaryStream = class {

+ 66 - 48
source/browser.js

@@ -53,12 +53,14 @@ browser.Host = class {
     }
 
     async view(view) {
+        const window = this.window;
+        const document = this.document;
         this._view = view;
         const age = async () => {
             const days = (new Date() - new Date(this._environment.date)) / (24 * 60 * 60 * 1000);
             if (days > 180) {
                 const link = this._element('logo-github').href;
-                this.document.body.classList.remove('spinner');
+                document.body.classList.remove('spinner');
                 for (;;) {
                     /* eslint-disable no-await-in-loop */
                     await this.message('Please update to the newest version.', null, 'Update');
@@ -84,15 +86,15 @@ browser.Host = class {
                 // continue regardless of error
             }
             if (consent) {
-                this.document.body.classList.remove('spinner');
+                document.body.classList.remove('spinner');
                 await this.message('This app uses cookies to report errors and anonymous usage information.', null, 'Accept');
             }
             this._setCookie('consent', Date.now().toString(), 30);
         };
         const telemetry = async () => {
             if (this._environment.packaged) {
-                this._window.addEventListener('error', (event) => {
-                    if (event instanceof ErrorEvent && event.error && event.error instanceof Error) {
+                window.addEventListener('error', (event) => {
+                    if (event instanceof window.ErrorEvent && event.error && event.error instanceof Error) {
                         this.exception(event.error, true);
                     } else {
                         const message = event && event.message ? event.message : JSON.stringify(event);
@@ -104,9 +106,9 @@ browser.Host = class {
                 const user = this._getCookie('_ga').replace(/^(GA1\.\d\.)*/, '');
                 const session = this._getCookie(`_ga${measurement_id}`);
                 await this._telemetry.start(`G-${measurement_id}`, user, session);
-                this._telemetry.set('page_location', this._document.location && this._document.location.href ? this._document.location.href : null);
-                this._telemetry.set('page_title', this._document.title ? this._document.title : null);
-                this._telemetry.set('page_referrer', this._document.referrer ? this._document.referrer : null);
+                this._telemetry.set('page_location', document.location && document.location.href ? document.location.href : null);
+                this._telemetry.set('page_title', document.title ? document.title : null);
+                this._telemetry.set('page_referrer', document.referrer ? document.referrer : null);
                 this._telemetry.send('page_view', {
                     app_name: this.type,
                     app_version: this.version,
@@ -124,7 +126,7 @@ browser.Host = class {
             const filter = (list) => {
                 return list.filter((capability) => {
                     const path = capability.split('.').reverse();
-                    let obj = this.window[path.pop()];
+                    let obj = window[path.pop()];
                     while (obj && path.length > 0) {
                         obj = obj[path.pop()];
                     }
@@ -155,9 +157,11 @@ browser.Host = class {
                 }
             }
         }
-        const search = this.window.location.search;
-        const params = new Map(search ? new URLSearchParams(this.window.location.search) : []);
-        const hash = this.window.location.hash ? this.window.location.hash.replace(/^#/, '') : '';
+        const window = this.window;
+        const document = this.document;
+        const search = window.location.search;
+        const params = new Map(search ? new window.URLSearchParams(window.location.search) : []);
+        const hash = window.location.hash ? window.location.hash.replace(/^#/, '') : '';
         const url = hash ? hash : params.get('url');
         if (url) {
             const identifier = params.get('identifier') || null;
@@ -183,7 +187,7 @@ browser.Host = class {
             openFileButton.addEventListener('click', () => {
                 this.execute('open');
             });
-            const mobileSafari = this.environment('platform') === 'darwin' && navigator.maxTouchPoints && navigator.maxTouchPoints > 1;
+            const mobileSafari = this.environment('platform') === 'darwin' && window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1;
             if (!mobileSafari) {
                 const extensions = new base.Metadata().extensions.map((extension) => `.${extension}`);
                 openFileDialog.setAttribute('accept', extensions.join(', '));
@@ -198,13 +202,13 @@ browser.Host = class {
                 }
             });
         }
-        this.document.addEventListener('dragover', (e) => {
+        document.addEventListener('dragover', (e) => {
             e.preventDefault();
         });
-        this.document.addEventListener('drop', (e) => {
+        document.addEventListener('drop', (e) => {
             e.preventDefault();
         });
-        this.document.body.addEventListener('drop', (e) => {
+        document.body.addEventListener('drop', (e) => {
             e.preventDefault();
             if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
                 const files = Array.from(e.dataTransfer.files);
@@ -226,7 +230,8 @@ browser.Host = class {
     }
 
     worker(id) {
-        return new this.window.Worker(`${id}.js`, { type: 'module' });
+        const window = this.window;
+        return new window.Worker(`${id}.js`, { type: 'module' });
     }
 
     async save(name, extension, defaultPath) {
@@ -234,14 +239,16 @@ browser.Host = class {
     }
 
     async export(file, blob) {
-        const element = this.document.createElement('a');
+        const window = this.window;
+        const document = this.document;
+        const element = document.createElement('a');
         element.download = file;
-        const url = URL.createObjectURL(blob);
+        const url = window.URL.createObjectURL(blob);
         element.href = url;
-        this.document.body.appendChild(element);
+        document.body.appendChild(element);
         element.click();
-        this.document.body.removeChild(element);
-        URL.revokeObjectURL(url);
+        document.body.removeChild(element);
+        window.URL.revokeObjectURL(url);
     }
 
     async execute(name /*, value */) {
@@ -283,7 +290,8 @@ browser.Host = class {
     }
 
     openURL(url) {
-        this.window.location = url;
+        const window = this.window;
+        window.location = url;
     }
 
     exception(error, fatal) {
@@ -345,13 +353,14 @@ browser.Host = class {
     }
 
     async _request(url, headers, encoding, callback, timeout) {
+        const window = this.window;
         if (!url.startsWith('data:')) {
             const date = new Date().getTime();
             const separator = (/\?/).test(url) ? '&' : '?';
             url = `${url}${separator}cb=${date}`;
         }
         return new Promise((resolve, reject) => {
-            const request = new XMLHttpRequest();
+            const request = new window.XMLHttpRequest();
             if (!encoding) {
                 request.responseType = 'arraybuffer';
             }
@@ -414,10 +423,9 @@ browser.Host = class {
         } else if (file.startsWith('/')) {
             file = file.substring(1);
         }
-        const location = this.window.location;
-        const pathname = location.pathname.endsWith('/') ?
-            location.pathname :
-            `${location.pathname.split('/').slice(0, -1).join('/')}/`;
+        const window = this.window;
+        const location = window.location;
+        const pathname = location.pathname.endsWith('/') ? location.pathname : `${location.pathname.split('/').slice(0, -1).join('/')}/`;
         return `${location.protocol}//${location.host}${pathname}${file}`;
     }
 
@@ -490,6 +498,7 @@ browser.Host = class {
     }
 
     async _openContext(context) {
+        const document = this.document;
         this._telemetry.set('session_engaged', 1);
         try {
             const attachment = await this._view.attach(context);
@@ -500,10 +509,10 @@ browser.Host = class {
             const model = await this._view.open(context);
             if (model) {
                 this._view.show(null);
-                this.document.title = context.name || context.identifier;
+                document.title = context.name || context.identifier;
                 return '';
             }
-            this.document.title = '';
+            document.title = '';
             return 'context-open-failed';
         } catch (error) {
             await this._view.error(error, error.name);
@@ -512,16 +521,19 @@ browser.Host = class {
     }
 
     _setCookie(name, value, days) {
-        this.document.cookie = `${name}=; Max-Age=0`;
-        const location = this.window.location;
+        const window = this.window;
+        const document = this.document;
+        document.cookie = `${name}=; Max-Age=0`;
+        const location = window.location;
         const domain = location && location.hostname && location.hostname.indexOf('.') !== -1 ? `;domain=.${location.hostname.split('.').slice(-2).join('.')}` : '';
         const date = new Date();
         date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
-        this.document.cookie = `${name}=${value}${domain};path=/;expires=${date.toUTCString()}`;
+        document.cookie = `${name}=${value}${domain};path=/;expires=${date.toUTCString()}`;
     }
 
     _getCookie(name) {
-        for (const cookie of this.document.cookie.split(';')) {
+        const document = this.document;
+        for (const cookie of document.cookie.split(';')) {
             const entry = cookie.split('=');
             if (entry[0].trim() === name) {
                 return entry[1].trim();
@@ -531,9 +543,10 @@ browser.Host = class {
     }
 
     get(name) {
+        const window = this.window;
         try {
-            if (typeof this.window.localStorage !== 'undefined') {
-                const content = this.window.localStorage.getItem(name);
+            if (typeof window.localStorage !== 'undefined') {
+                const content = window.localStorage.getItem(name);
                 return JSON.parse(content);
             }
         } catch {
@@ -543,9 +556,10 @@ browser.Host = class {
     }
 
     set(name, value) {
+        const window = this.window;
         try {
-            if (typeof this.window.localStorage !== 'undefined') {
-                this.window.localStorage.setItem(name, JSON.stringify(value));
+            if (typeof window.localStorage !== 'undefined') {
+                window.localStorage.setItem(name, JSON.stringify(value));
             }
         } catch {
             // continue regardless of error
@@ -553,9 +567,10 @@ browser.Host = class {
     }
 
     delete(name) {
+        const window = this.window;
         try {
-            if (typeof this.window.localStorage !== 'undefined') {
-                this.window.localStorage.removeItem(name);
+            if (typeof window.localStorage !== 'undefined') {
+                window.localStorage.removeItem(name);
             }
         } catch {
             // continue regardless of error
@@ -563,7 +578,8 @@ browser.Host = class {
     }
 
     _element(id) {
-        return this.document.getElementById(id);
+        const document = this.document;
+        return document.getElementById(id);
     }
 
     update() {
@@ -571,7 +587,8 @@ browser.Host = class {
 
     async message(message, alert, action) {
         return new Promise((resolve) => {
-            const type = this.document.body.getAttribute('class');
+            const document = this.document;
+            const type = document.body.getAttribute('class');
             this._element('message-text').innerText = message || '';
             const button = this._element('message-button');
             if (action) {
@@ -579,7 +596,7 @@ browser.Host = class {
                 button.innerText = action;
                 button.onclick = () => {
                     button.onclick = null;
-                    this.document.body.setAttribute('class', type);
+                    document.body.setAttribute('class', type);
                     resolve(0);
                 };
             } else {
@@ -587,10 +604,10 @@ browser.Host = class {
                 button.onclick = null;
             }
             if (alert) {
-                this.document.body.setAttribute('class', 'alert');
+                document.body.setAttribute('class', 'alert');
             } else {
-                this.document.body.classList.add('notification');
-                this.document.body.classList.remove('default');
+                document.body.classList.add('notification');
+                document.body.classList.remove('default');
             }
             if (action) {
                 button.focus();
@@ -627,7 +644,8 @@ browser.BrowserFileContext = class {
             throw new Error(`File not found '${file}'.`);
         }
         return new Promise((resolve, reject) => {
-            const reader = new FileReader();
+            const window = this._host.window;
+            const reader = new window.FileReader();
             const size = 0x10000000;
             let position = 0;
             const chunks = [];
@@ -842,8 +860,8 @@ browser.Context = class {
 };
 
 if (!('scrollBehavior' in window.document.documentElement.style)) {
-    const __scrollTo__ = Element.prototype.scrollTo;
-    Element.prototype.scrollTo = function(...args) {
+    const __scrollTo__ = window.Element.prototype.scrollTo;
+    window.Element.prototype.scrollTo = function(...args) {
         const [options] = args;
         if (options !== undefined) {
             if (options === null || typeof options !== 'object' || options.behavior === undefined || options.behavior === 'auto' || options.behavior === 'instant') {

+ 5 - 3
source/desktop.mjs

@@ -306,7 +306,8 @@ desktop.Host = class {
     }
 
     async export(file, blob) {
-        const reader = new FileReader();
+        const window = this.window;
+        const reader = new window.FileReader();
         reader.onload = (e) => {
             const data = new Uint8Array(e.target.result);
             fs.writeFile(file, data, null, async (error) => {
@@ -318,7 +319,7 @@ desktop.Host = class {
         let error = null;
         if (!blob) {
             error = new Error(`Export blob is '${JSON.stringify(blob)}'.`);
-        } else if (!(blob instanceof Blob)) {
+        } else if (blob instanceof window.Blob === false) {
             error = new Error(`Export blob type is '${typeof blob}'.`);
         }
         if (error) {
@@ -504,8 +505,9 @@ desktop.Host = class {
     }
 
     _request(location, headers, timeout) {
+        const window = this.window;
         return new Promise((resolve, reject) => {
-            const url = new URL(location);
+            const url = new window.URL(location);
             const protocol = url.protocol === 'https:' ? https : http;
             const options = {};
             options.headers = headers;

+ 5 - 3
source/index.js

@@ -4,12 +4,13 @@ window.exports.require = function(id, callback) {
     if (!/^[a-zA-Z0-9_-]+$/.test(id)) {
         throw new Error("Invalid module '" + id + "'.");
     }
-    let base = window.location.href || '';
+    var base = window.location.href || '';
     base = base.split('?')[0].split('#')[0];
     const index = base.lastIndexOf('/');
     base = index > 0 ? base.substring(0, index + 1) : base;
     base = base.lastIndexOf('/') === base.length - 1 ? base : base + '/';
     var url = base + id + '.js';
+    var document = window.document;
     var scripts = document.head.getElementsByTagName('script');
     for (var i = 0; i < scripts.length; i++) {
         if (url === scripts[i].getAttribute('src')) {
@@ -69,6 +70,7 @@ window.exports.preload = function(callback) {
 };
 
 window.exports.terminate = function(message) {
+    var document = window.document;
     document.getElementById('message-text').innerText = message;
     var button = document.getElementById('message-button');
     button.style.display = 'none';
@@ -86,7 +88,7 @@ window.exports.terminate = function(message) {
 };
 
 window.addEventListener('error', function (event) {
-    var error = event instanceof ErrorEvent && event.error && event.error instanceof Error ? event.error : new Error(event && event.message ? event.message : JSON.stringify(event));
+    var error = event instanceof window.ErrorEvent && event.error && event.error instanceof Error ? event.error : new Error(event && event.message ? event.message : JSON.stringify(event));
     window.exports.terminate(error.message);
 });
 
@@ -99,7 +101,7 @@ window.addEventListener('load', function() {
     var chrome = ua.match(/Chrom(e|ium)\/([0-9]+)\./);
     var safari = ua.match(/Version\/(\d+)\.(\d+).*Safari/);
     var firefox = ua.match(/Firefox\/([0-9]+)\./);
-    if ((Array.isArray(chrome) && parseInt(chrome[2], 10) < 80) ||
+    if ((Array.isArray(chrome) && parseInt(chrome[2], 10) < 86) ||
         (Array.isArray(safari) && (parseInt(safari[1], 10) < 16 || (parseInt(safari[1], 10) === 16 && parseInt(safari[2], 10) < 4))) ||
         (Array.isArray(firefox) && parseInt(firefox[1], 10) < 114)) {
         throw new Error('Please update your browser to use this application.');

+ 35 - 24
source/view.js

@@ -386,7 +386,7 @@ view.View = class {
 
     _timeout(delay) {
         return new Promise((resolve) => {
-            setTimeout(resolve, delay);
+            this._host.window.setTimeout(resolve, delay);
         });
     }
 
@@ -558,15 +558,16 @@ view.View = class {
                 back.style.opacity = 1;
                 const last = this._path.length - 2;
                 const count = Math.min(2, last);
+                const document = this.host.document;
                 if (count < last) {
-                    const element = this._host.document.createElement('button');
+                    const element = document.createElement('button');
                     element.setAttribute('class', 'toolbar-path-name-button');
                     element.innerHTML = '&hellip;';
                     path.appendChild(element);
                 }
                 for (let i = count; i >= 0; i--) {
                     const target = this._path[i].target;
-                    const element = this._host.document.createElement('button');
+                    const element = document.createElement('button');
                     element.setAttribute('class', 'toolbar-path-name-button');
                     element.addEventListener('click', async () => {
                         if (i > 0) {
@@ -665,6 +666,7 @@ view.View = class {
     }
 
     async export(file) {
+        const window = this.host.window;
         const lastIndex = file.lastIndexOf('.');
         const extension = lastIndex === -1 ? 'png' : file.substring(lastIndex + 1).toLowerCase();
         if (this.activeTarget && (extension === 'png' || extension === 'svg')) {
@@ -720,16 +722,16 @@ view.View = class {
             background.setAttribute('width', width);
             background.setAttribute('height', height);
             background.setAttribute('fill', '#fff');
-            const data = new XMLSerializer().serializeToString(clone);
+            const data = new window.XMLSerializer().serializeToString(clone);
             if (extension === 'svg') {
-                const blob = new Blob([data], { type: 'image/svg' });
+                const blob = new window.Blob([data], { type: 'image/svg' });
                 await this._host.export(file, blob);
             }
             if (extension === 'png') {
                 const blob = await new Promise((resolve, reject) => {
                     this.show('welcome spinner');
                     this.progress(0);
-                    const image = new Image();
+                    const image = new window.Image();
                     image.onload = async () => {
                         try {
                             let targetWidth = Math.ceil(width * 2);
@@ -747,7 +749,7 @@ view.View = class {
                             }
                             const drawScale = targetWidth / width;
                             const size = Math.min(targetWidth, 4096);
-                            const encoder = new png.Encoder(targetWidth, targetHeight);
+                            const encoder = new png.Encoder(window, targetWidth, targetHeight);
                             const canvas = this._host.document.createElement('canvas');
                             canvas.width = size;
                             canvas.height = 4096;
@@ -773,7 +775,7 @@ view.View = class {
                             const buffer = await encoder.toBuffer();
                             this.progress(0);
                             this.show('default');
-                            resolve(new Blob([buffer], { type: 'image/png' }));
+                            resolve(new window.Blob([buffer], { type: 'image/png' }));
                         } catch (error) {
                             this.progress(0);
                             this.show('default');
@@ -973,6 +975,7 @@ view.Menu = class {
         this.items = [];
         this._darwin = host.environment('platform') === 'darwin';
         this._document = host.document;
+        this._window = host.window;
         this._stack = [];
         this._root = [];
         this._buttons = [];
@@ -1177,6 +1180,7 @@ view.Menu = class {
     }
 
     _execute(action) {
+        const window = this._window;
         if (typeof action === 'function') {
             action();
             return true;
@@ -1194,7 +1198,7 @@ view.Menu = class {
             }
             case 'command': {
                 this.close();
-                setTimeout(() => action.execute(), 10);
+                window.setTimeout(() => action.execute(), 10);
                 return true;
             }
             default: {
@@ -1496,7 +1500,8 @@ view.Worker = class {
             this._reject = reject;
             this._create();
             this._worker.postMessage(message);
-            this._timeout = setTimeout(async () => {
+            const window = this._host.window;
+            this._timeout = window.setTimeout(async () => {
                 await this._host.message(notification, null, 'Cancel');
                 this.cancel(true);
                 delete this._resolve;
@@ -1541,7 +1546,7 @@ view.Worker = class {
             this._worker = null;
         }
         if (this._timeout !== -1) {
-            clearTimeout(this._timeout);
+            this._host.window.clearTimeout(this._timeout);
             this._timeout = -1;
             this._host.message();
         }
@@ -2761,6 +2766,11 @@ view.Control = class {
         return element;
     }
 
+    createTextNode(data) {
+        const node = this._host.document.createTextNode(data);
+        return node;
+    }
+
     on(event, callback) {
         this._events = this._events || {};
         this._events[event] = this._events[event] || [];
@@ -2950,10 +2960,10 @@ view.ObjectSidebar = class extends view.Control {
     error(error, fatal) {
         super.error(error, fatal);
         const element = this.createElement('span');
-        const title = document.createElement('b');
+        const title = this.createElement('b');
         title.textContent = 'ERROR: ';
         element.appendChild(title);
-        const message = document.createTextNode(` ${error.message}`);
+        const message = this.createTextNode(` ${error.message}`);
         element.appendChild(message);
         this.element.appendChild(element);
     }
@@ -3567,15 +3577,16 @@ view.TensorView = class extends view.Expander {
     error(error, fatal) {
         super.error(error, fatal);
         const element = this.createElement('div', 'sidebar-item-value-line');
-        const title = document.createElement('b');
+        const title = this.createElement('b');
         title.textContent = 'ERROR: ';
         element.appendChild(title);
-        const message = document.createTextNode(error.message);
+        const message = this.createTextNode(error.message);
         element.appendChild(message);
         this.element.appendChild(element);
     }
 
     async export() {
+        const window = this._host.window;
         const tensor = this._tensor;
         const defaultPath = tensor.name ? tensor.name.split('/').join('_').split(':').join('_').split('.').join('_') : 'tensor';
         const file = await this._host.save('NumPy Array', 'npy', defaultPath);
@@ -3601,10 +3612,10 @@ view.TensorView = class extends view.Expander {
                 const array = numpy.asarray(tensor.value, dtype);
                 numpy.save(bytes, array);
                 bytes.seek(0);
-                const blob = new Blob([bytes.read()], { type: 'application/octet-stream' });
+                const blob = new window.Blob([bytes.read()], { type: 'application/octet-stream' });
                 await this._host.export(file, blob);
             } catch (error) {
-                this.error(error, 'Error saving NumPy tensor.', null);
+                this._view.error(error, 'Error saving NumPy tensor.', null);
             }
         }
     }
@@ -4099,10 +4110,10 @@ view.DocumentationSidebar = class extends view.Control {
     error(error, fatal) {
         super.error(error, fatal);
         const element = this.createElement('span');
-        const title = document.createElement('b');
+        const title = this.createElement('b');
         title.textContent = 'ERROR: ';
         element.appendChild(title);
-        const message = document.createTextNode(error.message);
+        const message = this.createTextNode(error.message);
         element.appendChild(message);
         this.element.appendChild(element);
     }
@@ -4419,10 +4430,10 @@ view.FindSidebar = class extends view.Control {
     error(error, fatal) {
         super.error(error, fatal);
         const element = this.createElement('li');
-        const title = document.createElement('b');
+        const title = this.createElement('b');
         title.textContent = 'ERROR: ';
         element.appendChild(title);
-        const message = document.createTextNode(` ${error.message}`);
+        const message = this.createTextNode(` ${error.message}`);
         element.appendChild(message);
         this._content.appendChild(element);
     }
@@ -5557,12 +5568,12 @@ markdown.Generator = class {
 
 png.Encoder = class {
 
-    constructor(width, height) {
+    constructor(window, width, height) {
         this.width = width;
         this.height = height;
-        const compressor = new CompressionStream('deflate');
+        const compressor = new window.CompressionStream('deflate');
         this.writer = compressor.writable.getWriter();
-        this.response = new Response(compressor.readable).blob();
+        this.response = new window.Response(compressor.readable).blob();
     }
 
     async write(data, rows) {

+ 2 - 2
test/desktop.spec.js

@@ -33,7 +33,7 @@ playwright.test('desktop', async () => {
     await app.evaluate(async (electron, location) => {
         const windows = electron.BrowserWindow.getAllWindows();
         if (windows.length > 0) {
-            const [window] = windows;
+            const window = windows[0];
             window.webContents.send('open', { path: location });
         }
     }, file);
@@ -46,7 +46,7 @@ playwright.test('desktop', async () => {
     await app.evaluate(async (electron) => {
         const windows = electron.BrowserWindow.getAllWindows();
         if (windows.length > 0) {
-            const [window] = windows;
+            const window = windows[0];
             window.webContents.send('find', {});
         }
     });

+ 8 - 0
test/mock.js

@@ -279,6 +279,14 @@ class Window {
     requestAnimationFrame(callback) {
         callback();
     }
+
+    setTimeout(code, delay) {
+        return global.setTimeout(code, delay);
+    }
+
+    clearTimeout(timeoutID) {
+        global.clearTimeout(timeoutID);
+    }
 }
 
 mock.Host = class {

+ 3 - 3
test/worker.js

@@ -120,7 +120,7 @@ export class Target {
     }
 
     async request(url, init) {
-        const response = await fetch(url, init);
+        const response = await global.fetch(url, init);
         if (!response.ok) {
             throw new Error(response.status.toString());
         }
@@ -131,7 +131,7 @@ export class Target {
             /* eslint-disable consistent-this */
             const target = this;
             /* eslint-enable consistent-this */
-            const stream = new ReadableStream({
+            const stream = new global.ReadableStream({
                 async start(controller) {
                     const read = async () => {
                         try {
@@ -160,7 +160,7 @@ export class Target {
                     return read();
                 }
             });
-            return new Response(stream, {
+            return new global.Response(stream, {
                 status: response.status,
                 statusText: response.statusText,
                 headers: response.headers

+ 2 - 2
tools/mlir-script.js

@@ -1048,10 +1048,10 @@ const test = async (pattern) => {
     ]);
     const readRunHeader = async (filePath) => {
         const handle = await fs.open(filePath, 'r');
-        const buffer = Buffer.alloc(256);
+        const buffer = new Uint8Array(256);
         await handle.read(buffer, 0, 256, 0);
         await handle.close();
-        const content = buffer.toString('utf-8').split('\n')[0];
+        const content = new TextDecoder().decode(buffer).split('\n')[0];
         return content.startsWith('// RUN:') ? content : null;
     };
     for (const file of allFiles) {