From 7892e86731d05cc8ec9c401dfd1ae4b359224a4e Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 27 Jul 2024 18:26:52 +0200 Subject: [PATCH] Move to TypeScript (#3830) This moves our JS file to use TS instead, which allows us to use a proper linter to check the code. All related files where moved out from the root in a dedicated folder to avoid polluting the Rust environment. --- .github/dependabot.yaml | 11 +++++++ .github/workflows/ci.yml | 21 +++++++++++- .gitignore | 3 ++ .swcrc => src/platform_impl/web/script/.swcrc | 7 ++++ .../web/script/eslint.config.mjs | 32 +++++++++++++++++++ src/platform_impl/web/script/package.json | 9 ++++++ src/platform_impl/web/script/scheduler.d.ts | 12 +++++++ src/platform_impl/web/script/tsconfig.json | 14 ++++++++ src/platform_impl/web/script/worker.min.js | 1 + src/platform_impl/web/script/worker.ts | 10 ++++++ src/platform_impl/web/web_sys/schedule.rs | 2 +- src/platform_impl/web/web_sys/worker.js | 10 ------ src/platform_impl/web/web_sys/worker.min.js | 1 - 13 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 .github/dependabot.yaml rename .swcrc => src/platform_impl/web/script/.swcrc (58%) create mode 100644 src/platform_impl/web/script/eslint.config.mjs create mode 100644 src/platform_impl/web/script/package.json create mode 100644 src/platform_impl/web/script/scheduler.d.ts create mode 100644 src/platform_impl/web/script/tsconfig.json create mode 100644 src/platform_impl/web/script/worker.min.js create mode 100644 src/platform_impl/web/script/worker.ts delete mode 100644 src/platform_impl/web/web_sys/worker.js delete mode 100644 src/platform_impl/web/web_sys/worker.min.js diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 00000000..e12272ce --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,11 @@ +version: 2 + +updates: + - package-ecosystem: npm + directory: src/platform_impl/web/script + schedule: + interval: daily + groups: + github-actions: + patterns: + - '*' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae77befd..9e9eb323 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -243,9 +243,28 @@ jobs: log-level: error arguments: --all-features --target ${{ matrix.platform.target }} + eslint: + name: ESLint + + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./src/platform_impl/web/script + + steps: + - uses: taiki-e/checkout-action@v1 + - name: Setup NPM + run: npm install + - name: Run ESLint + run: npx eslint + swc: name: Minimize JavaScript + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./src/platform_impl/web/script steps: - uses: taiki-e/checkout-action@v1 @@ -253,7 +272,7 @@ jobs: run: sudo npm i -g @swc/cli - name: Run SWC run: | - swc src/platform_impl/web/web_sys/worker.js -o src/platform_impl/web/web_sys/worker.min.js + swc . --ignore node_modules,**/*.d.ts --only **/*.ts -d . --out-file-extension min.js - name: Check for diff run: | [[ -z $(git status -s) ]] diff --git a/.gitignore b/.gitignore index 2caffd82..05c70e9c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ rls/ *~ #*# .DS_Store +# NPM package used to run ESLint. +/src/platform_impl/web/script/node_modules +/src/platform_impl/web/script/package-lock.json diff --git a/.swcrc b/src/platform_impl/web/script/.swcrc similarity index 58% rename from .swcrc rename to src/platform_impl/web/script/.swcrc index 1d7eccb9..6118c52b 100644 --- a/.swcrc +++ b/src/platform_impl/web/script/.swcrc @@ -1,6 +1,13 @@ { + "module": { + "type": "es6" + }, + "isModule": true, "minify": true, "jsc": { + "parser": { + "syntax": "typescript" + }, "target": "es2022", "minify": { "compress": { diff --git a/src/platform_impl/web/script/eslint.config.mjs b/src/platform_impl/web/script/eslint.config.mjs new file mode 100644 index 00000000..6bba0753 --- /dev/null +++ b/src/platform_impl/web/script/eslint.config.mjs @@ -0,0 +1,32 @@ +import eslint from '@eslint/js' +import tseslint from 'typescript-eslint' +import globals from 'globals' + +export default tseslint.config( + { + ignores: ['**/*.min.js', 'eslint.config.mjs'], + }, + eslint.configs.recommended, + ...tseslint.configs.strictTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + { + languageOptions: { + parserOptions: { + ecmaVersion: 'latest', + project: ['tsconfig.json'], + sourceType: 'module', + }, + globals: { + ...globals.browser, + }, + }, + rules: { + '@typescript-eslint/no-confusing-void-expression': [ + 'error', + { + ignoreArrowShorthand: true, + }, + ], + }, + } +) diff --git a/src/platform_impl/web/script/package.json b/src/platform_impl/web/script/package.json new file mode 100644 index 00000000..75e57a40 --- /dev/null +++ b/src/platform_impl/web/script/package.json @@ -0,0 +1,9 @@ +{ + "devDependencies": { + "@eslint/js": "^9", + "@types/eslint__js": "^8", + "eslint": "^8", + "typescript": "^5", + "typescript-eslint": "^7" + } +} diff --git a/src/platform_impl/web/script/scheduler.d.ts b/src/platform_impl/web/script/scheduler.d.ts new file mode 100644 index 00000000..2fe30a1d --- /dev/null +++ b/src/platform_impl/web/script/scheduler.d.ts @@ -0,0 +1,12 @@ +declare global { + // eslint-disable-next-line no-var + var scheduler: Scheduler +} + +export interface Scheduler { + postTask(callback: () => T | PromiseLike, options?: SchedulerPostTaskOptions): Promise +} + +export interface SchedulerPostTaskOptions { + delay?: number +} diff --git a/src/platform_impl/web/script/tsconfig.json b/src/platform_impl/web/script/tsconfig.json new file mode 100644 index 00000000..1578d841 --- /dev/null +++ b/src/platform_impl/web/script/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ESNext", + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "exactOptionalPropertyTypes": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "strict": true, + } +} diff --git a/src/platform_impl/web/script/worker.min.js b/src/platform_impl/web/script/worker.min.js new file mode 100644 index 00000000..8b72384e --- /dev/null +++ b/src/platform_impl/web/script/worker.min.js @@ -0,0 +1 @@ +onmessage=e=>{let[s,a]=e.data,l=()=>s.postMessage(void 0);"scheduler"in globalThis?globalThis.scheduler.postTask(l,{delay:a}):setTimeout(l,a)}; \ No newline at end of file diff --git a/src/platform_impl/web/script/worker.ts b/src/platform_impl/web/script/worker.ts new file mode 100644 index 00000000..d22df194 --- /dev/null +++ b/src/platform_impl/web/script/worker.ts @@ -0,0 +1,10 @@ +onmessage = (event) => { + const [port, timeout] = event.data as [MessagePort, number] + const f = () => port.postMessage(undefined) + + if ('scheduler' in globalThis) { + void globalThis.scheduler.postTask(f, { delay: timeout }) + } else { + setTimeout(f, timeout) + } +} diff --git a/src/platform_impl/web/web_sys/schedule.rs b/src/platform_impl/web/web_sys/schedule.rs index 259be3dd..9cc22cb2 100644 --- a/src/platform_impl/web/web_sys/schedule.rs +++ b/src/platform_impl/web/web_sys/schedule.rs @@ -175,7 +175,7 @@ impl Schedule { F: 'static + FnMut(), { thread_local! { - static URL: ScriptUrl = ScriptUrl::new(include_str!("worker.min.js")); + static URL: ScriptUrl = ScriptUrl::new(include_str!("../script/worker.min.js")); static WORKER: Worker = URL.with(|url| Worker::new(&url.0)).expect("`new Worker()` is not expected to fail with a local script"); } diff --git a/src/platform_impl/web/web_sys/worker.js b/src/platform_impl/web/web_sys/worker.js deleted file mode 100644 index 5a8411ef..00000000 --- a/src/platform_impl/web/web_sys/worker.js +++ /dev/null @@ -1,10 +0,0 @@ -onmessage = event => { - const [port, timeout] = event.data - const f = () => port.postMessage(undefined) - - if ('scheduler' in this) { - scheduler.postTask(f, { delay: timeout }) - } else { - setTimeout(f, timeout) - } -} diff --git a/src/platform_impl/web/web_sys/worker.min.js b/src/platform_impl/web/web_sys/worker.min.js deleted file mode 100644 index fd394a73..00000000 --- a/src/platform_impl/web/web_sys/worker.min.js +++ /dev/null @@ -1 +0,0 @@ -onmessage=e=>{let[s,t]=e.data,a=()=>s.postMessage(void 0);"scheduler"in this?scheduler.postTask(a,{delay:t}):setTimeout(a,t)};