From bbefc3f73b84861e80ffdecb973cea15582efd27 Mon Sep 17 00:00:00 2001 From: juner Date: Thu, 4 Dec 2025 13:29:45 +0900 Subject: [PATCH] =?UTF-8?q?lint=20=E5=91=A8=E3=82=8A=E3=81=AE=E3=81=86?= =?UTF-8?q?=E3=81=BE=E3=81=8F=E9=81=A9=E7=94=A8=E3=81=95=E3=82=8C=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=E5=95=8F=E9=A1=8C?= =?UTF-8?q?=E3=81=AE=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 11 +++++++ eslint.config.mts | 25 +++++++++------ src/index.ts | 2 +- src/lock.test.ts | 61 +++++++++++++++++++------------------ src/lock.ts | 4 +-- src/request.ts | 4 +-- src/requiredAsyncDispose.ts | 2 +- src/types/InnerLock.ts | 2 +- src/types/Releasable.ts | 2 +- src/types/index.ts | 2 +- utils/copy.ts | 6 ++-- utils/remove.ts | 8 ++--- vite.config.js | 6 ++-- vitest.config.ts | 8 ++--- 14 files changed, 80 insertions(+), 63 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d1d6315 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}] +charset = utf-8 +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +end_of_line = lf +max_line_length = 100 \ No newline at end of file diff --git a/eslint.config.mts b/eslint.config.mts index 3cba84c..4294763 100644 --- a/eslint.config.mts +++ b/eslint.config.mts @@ -6,22 +6,27 @@ import markdown from "@eslint/markdown"; import { defineConfig } from "eslint/config"; import stylistic from "@stylistic/eslint-plugin"; - export default defineConfig([ { ignores: [ - `dist/**.*` - ] + `dist/**.*`, + ], }, { files: [`**/*.{js,mjs,cjs,ts,mts,cts}`], plugins: { js }, extends: [`js/recommended`] }, { files: [`**/*.{js,mjs,cjs,ts,mts,cts}`], languageOptions: { globals: { ...globals.browser, ...globals.node } } }, - tseslint.configs.recommended as unknown as Parameters, { + files: [`**/*.{js,mjs,cjs,ts,mts,cts}`], plugins: { "@stylistic": stylistic, + "tseslint": tseslint, }, + extends: [ + "@stylistic/recommended", + "tseslint/recommended", + ], rules: { "semi": [`error`], + "@stylistic/semi": ["error", "always"], "no-unused-vars": [`off`], "@typescript-eslint/no-unused-vars": [`error`, { argsIgnorePattern: `^_`, @@ -30,18 +35,18 @@ export default defineConfig([ destructuredArrayIgnorePattern: `^_`, varsIgnorePattern: `^_`, }], - "@stylistic/quotes": [`error`, "double", { "allowTemplateLiterals": "always" }], - } + "@stylistic/quotes": [`error`, "double", { allowTemplateLiterals: "always" }], + }, }, - { files: [`**/*.json`], ignores: [`**/tsconfig.json`, `package-lock.json`,`**/.vscode/*.json`], plugins: { json }, language: `json/json`, extends: [`json/recommended`] }, + { files: [`**/*.json`], ignores: [`**/tsconfig.json`, `package-lock.json`, `**/.vscode/*.json`], plugins: { json }, language: `json/json`, extends: [`json/recommended`] }, { files: [ `**/tsconfig.json`, `**/*.code-workspace`, `**/.vscode/*.json`, - ], - plugins: {json}, - language: "json/jsonc", + ], + plugins: { json }, + language: "json/jsonc", languageOptions: { allowTrailingCommas: true, }, diff --git a/src/index.ts b/src/index.ts index c3c14ec..bff6c08 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,3 @@ import "./requiredAsyncDispose.ts"; export * from "./lock.ts"; -export type { ReleasableLock } from "./types/index.ts"; \ No newline at end of file +export type { ReleasableLock } from "./types/index.ts"; diff --git a/src/lock.test.ts b/src/lock.test.ts index c1b6955..7c232be 100644 --- a/src/lock.test.ts +++ b/src/lock.test.ts @@ -25,7 +25,7 @@ describe("simple use", (args) => { clientId: expect.any(String), mode: "exclusive", name, - } + }, ], }); } @@ -54,7 +54,7 @@ describe("simple use", (args) => { clientId: expect.any(String), mode: "exclusive", name, - } + }, ], pending: undefined, }); @@ -68,14 +68,14 @@ describe("simple use", (args) => { clientId: expect.any(String), mode: "exclusive", name, - } + }, ], pending: [ { clientId: expect.any(String), mode: "exclusive", name, - } + }, ], }); lock2Wait.finally(() => expect(counter++).toEqual(2)); @@ -120,14 +120,14 @@ describe("simple use", (args) => { clientId: expect.any(String), mode: "shared", name, - } + }, ], pending: [ { clientId: expect.any(String), mode: "exclusive", name, - } + }, ], }); await expect(lock1.release()).resolves.toBeUndefined(); @@ -139,7 +139,7 @@ describe("simple use", (args) => { clientId: expect.any(String), mode: "exclusive", name, - } + }, ], pending: undefined, }); @@ -152,7 +152,7 @@ describe("simple use", (args) => { clientId: expect.any(String), mode: "exclusive", name, - } + }, ], pending: undefined, }); @@ -197,7 +197,7 @@ describe("simple use", (args) => { { await using _ = await request(); await using lock2 = await request({ - ifAvailable: true + ifAvailable: true, }); expect(lock2).toBeNull(); } @@ -236,7 +236,7 @@ describe("simple use", (args) => { }); await expect(lockWait).rejects.toThrowError(expect.objectContaining({ message: "ifAvailable and steal are mutually exclusive", - name: "NotSupportedError" + name: "NotSupportedError", })); } }); @@ -253,7 +253,7 @@ describe("hard error pattern", (args) => { }); try { expect(() => lock(name)).toThrowError(expect.objectContaining({ - message: "navigator.locks is not found. required options.locks argument." + message: "navigator.locks is not found. required options.locks argument.", })); const { request, query } = lock(name, { locks }); @@ -265,7 +265,7 @@ describe("hard error pattern", (args) => { clientId: expect.any(String), mode: "exclusive", name, - } + }, ], pending: undefined, }); @@ -274,7 +274,8 @@ describe("hard error pattern", (args) => { held: undefined, pending: undefined, }); - } finally { + } + finally { Object.defineProperty(globalThis.navigator, "locks", { writable: true, value: locks, @@ -285,9 +286,9 @@ describe("hard error pattern", (args) => { /** * Promise base setTimeout with abort signal - * @param ms - * @param options - * @returns + * @param ms + * @param options + * @returns */ async function timeout(ms?: number, options?: { signal?: AbortSignal }) { const { resolve, promise } = Promise.withResolvers(); @@ -297,7 +298,8 @@ async function timeout(ms?: number, options?: { signal?: AbortSignal }) { } try { return await promise; - } finally { + } + finally { if (options?.signal) { options.signal.removeEventListener("abort", abort); } @@ -310,8 +312,8 @@ async function timeout(ms?: number, options?: { signal?: AbortSignal }) { /** * Handle unhandledRejection event and return disposable to off the event. - * @param onUnhandledRejection - * @returns + * @param onUnhandledRejection + * @returns */ function unhandleRejection(onUnhandledRejection?: (reason: unknown, promise: Promise) => void) { onUnhandledRejection ??= () => undefined; @@ -326,7 +328,7 @@ function unhandleRejection(onUnhandledRejection?: (reason: unknown, promise: Pro /** * use fake timer and return async disposable to restore real timer. - * @returns + * @returns */ function fakeTimeer() { vi.useFakeTimers(); @@ -345,17 +347,16 @@ function fakeTimeer() { /** * describe unhandledRejection logging utility - * @param param0 + * @param param0 */ -function useUnhandleRejectionLogging({ beforeEach, afterEach } - : { - beforeEach: (fn: BeforeEachListener, timeout?: number) => void, - afterEach: (fn: AfterEachListener, timeout?: number) => void - }) { +function useUnhandleRejectionLogging({ beforeEach, afterEach }: { + beforeEach: (fn: BeforeEachListener, timeout?: number) => void + afterEach: (fn: AfterEachListener, timeout?: number) => void +}) { type HandlerInstance = { - [Symbol.dispose]: () => void, - reasones?: unknown[] | undefined, - } + [Symbol.dispose]: () => void + reasones?: unknown[] | undefined + }; const handles = new Map(); beforeEach(({ task: { id } }) => { const instance = {} as HandlerInstance; @@ -377,4 +378,4 @@ function useUnhandleRejectionLogging({ beforeEach, afterEach } function callback(this: HandlerInstance, reason: unknown) { (this.reasones ??= []).push(reason); } -} \ No newline at end of file +} diff --git a/src/lock.ts b/src/lock.ts index a01fc24..3d7a8a6 100644 --- a/src/lock.ts +++ b/src/lock.ts @@ -23,8 +23,8 @@ export function lock(name: string, options?: { locks?: LockManager }) { } const thisArgs: InnerLock = { locks, name }; const request = originalRequest.bind(thisArgs) as { - (options: Omit & { ifAvailable: true }): Promise; - (options?: Omit & { ifAvailable?: false }): Promise; + (options: Omit & { ifAvailable: true }): Promise + (options?: Omit & { ifAvailable?: false }): Promise }; return { request, diff --git a/src/request.ts b/src/request.ts index 63f45b0..455a436 100644 --- a/src/request.ts +++ b/src/request.ts @@ -19,7 +19,7 @@ export async function request(this: InnerLock, options?: Omit { // #region Create resolvers to coordinate async lock lifecycle - // case1: called callback + // case1: called callback const { resolve: callbackResolve, promise: callbackPromise } = Promise.withResolvers(); // case2: called release @@ -39,7 +39,7 @@ export async function request(this: InnerLock, options?: LockOptions): Promise null, - reason => ({ reason }) + reason => ({ reason }), ), ]); diff --git a/src/requiredAsyncDispose.ts b/src/requiredAsyncDispose.ts index c00a788..b0949c9 100644 --- a/src/requiredAsyncDispose.ts +++ b/src/requiredAsyncDispose.ts @@ -1,3 +1,3 @@ if (typeof Symbol.asyncDispose !== "symbol") { (Symbol as { asyncDispose: symbol }).asyncDispose = Symbol.for("Symbol.asyncDispose"); -} \ No newline at end of file +} diff --git a/src/types/InnerLock.ts b/src/types/InnerLock.ts index 764816a..e4cf2aa 100644 --- a/src/types/InnerLock.ts +++ b/src/types/InnerLock.ts @@ -2,4 +2,4 @@ * Internal type used to bind LockManager context with the lock name. */ -export type InnerLock = { locks: LockManager; name: string; }; +export type InnerLock = { locks: LockManager, name: string }; diff --git a/src/types/Releasable.ts b/src/types/Releasable.ts index a1f80de..183abed 100644 --- a/src/types/Releasable.ts +++ b/src/types/Releasable.ts @@ -1,4 +1,4 @@ /** * A type representing an object that can release a lock asynchronously. */ -export type Releasable = { release(): Promise; }; +export type Releasable = { release(): Promise }; diff --git a/src/types/index.ts b/src/types/index.ts index fc866ce..f9e9d24 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,3 +1,3 @@ export type * from "./InnerLock.ts"; export type * from "./Releasable.ts"; -export type * from "./ReleasableLock.ts"; \ No newline at end of file +export type * from "./ReleasableLock.ts"; diff --git a/utils/copy.ts b/utils/copy.ts index 6cd25bb..3bfd037 100644 --- a/utils/copy.ts +++ b/utils/copy.ts @@ -21,10 +21,10 @@ const parsed = util.parseArgs({ short: "f", multiple: true, }, - } + }, }); -const {values: {output, file}} = parsed; +const { values: { output, file } } = parsed; if (!file || file.length <= 0) { process.exit(0); @@ -34,7 +34,7 @@ if (!output || output.length <= 0) { throw new Error("required -o or --output"); } -for(const f of file) { +for (const f of file) { const src = path.join("./", f); const dest = path.join(output, f); diff --git a/utils/remove.ts b/utils/remove.ts index ecb8ff2..00591d4 100644 --- a/utils/remove.ts +++ b/utils/remove.ts @@ -15,18 +15,18 @@ const parsed = util.parseArgs({ short: "f", multiple: true, }, - } + }, }); -const {values: {file}} = parsed; +const { values: { file } } = parsed; if (!file || file.length <= 0) { process.exit(0); } -for(const f of file) { +for (const f of file) { const exist = await fse.pathExists(f); if (!exist) continue; await fse.remove(f); console.log("remove:", f); -} \ No newline at end of file +} diff --git a/vite.config.js b/vite.config.js index d673ccb..db0048e 100644 --- a/vite.config.js +++ b/vite.config.js @@ -6,6 +6,6 @@ export default defineConfig({ entry: resolve(__dirname, "src/index.ts"), name: "index", fileName: "index", - } - } -}); \ No newline at end of file + }, + }, +}); diff --git a/vitest.config.ts b/vitest.config.ts index 54f99d7..a641821 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ ...coverageConfigDefaults.exclude, "src/requiredAsyncDispose.ts", "utils/**/*.ts", - ] - } - } -}); \ No newline at end of file + ], + }, + }, +});