@dartess/eslint-plugin 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  [//]: # (https://keepachangelog.com/en/1.1.0/)
4
4
 
5
+ ## [0.4.0] - 2026-01-15
6
+ - add rule `@dartess/mobx-sync-autorun`
7
+ - add `@dartess/mobx-sync-autorun` to `mobx` config
8
+
9
+ ## [0.3.0] - 2026-01-12
10
+
11
+ - add `eslint-plugin-react-hooks:recommended` config to `react` config
12
+
5
13
  ## [0.2.1] - 2026-01-10
6
14
 
7
15
  - add `recommended-post-format` config for using after formatting tools
package/README.md CHANGED
@@ -11,13 +11,12 @@ Also extends
11
11
 
12
12
  Also can extends (if it is applicable)
13
13
  * `eslint-plugin-react` — `recommended` & `jsx-runtime`
14
+ * `eslint-plugin-react-hooks` — `recommended`
14
15
  * `@next/eslint-plugin-next` — `recommended` & `core-web-vitals`
15
16
  * `eslint-config-next`
16
17
  * `eslint-plugin-mobx` — `recommended`
17
18
  * `eslint-plugin-storybook` — `recommended` & `csf-strict`
18
19
 
19
- _(We also use `eslint-plugin-unicorn` and `eslint-plugin-decorator-position` but only special rules, without `recommended` config)_
20
-
21
20
  All of it pinched with extra configs, setups and extra rules. Just take it and use it!
22
21
 
23
22
  ### Notes
@@ -168,6 +167,7 @@ Each rule has emojis denoting:
168
167
  | [stories-export-typed](docs/rules/stories-export-typed.md) | Storybook's Stories should be typed | ✅ | | |
169
168
  | [max-parent-import-depth](docs/rules/max-parent-import-depth.md) | Limit relative imports to a maximum parent depth. | ✅ | | |
170
169
  | [ts-named-tuple-elements](docs/rules/ts-named-tuple-elements.md) | Enforce (or forbid) named tuple elements | ✅ | | |
170
+ | [mobx-sync-autorun](docs/rules/mobx-sync-autorun.md) | Enforce synchronous autorun callback | ✅ | | |
171
171
 
172
172
  ## Code Reuse Policy
173
173
 
@@ -8,6 +8,7 @@ const config = [
8
8
  'mobx/missing-make-observable': 'off', // useless with modern decorators syntax
9
9
  '@dartess/strict-observable-components-declaration': 'error',
10
10
  '@dartess/require-observer': 'error',
11
+ '@dartess/mobx-sync-autorun': 'error',
11
12
  },
12
13
  },
13
14
  ];
@@ -5,7 +5,6 @@ import reactPlugin from 'eslint-plugin-react';
5
5
  import reactHooksPlugin from 'eslint-plugin-react-hooks';
6
6
  import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
7
7
  import vendorRulesReact from "./vendor-rules/react.js";
8
- import vendorRulesReactHooks from "./vendor-rules/react-hooks.js";
9
8
  const config = [
10
9
  {
11
10
  name: '@dartess/react-setup',
@@ -19,6 +18,7 @@ const config = [
19
18
  },
20
19
  },
21
20
  },
21
+ reactHooksPlugin.configs.flat.recommended,
22
22
  {
23
23
  name: 'react/recommended', // missed name, @see e.g. https://github.com/jsx-eslint/eslint-plugin-react/pull/3882
24
24
  ...reactPlugin.configs.flat.recommended,
@@ -71,11 +71,5 @@ const config = [
71
71
  'react/jsx-no-undef': 'off', // checked by typescript
72
72
  },
73
73
  },
74
- {
75
- name: '@dartess/react-hooks',
76
- rules: {
77
- ...vendorRulesReactHooks,
78
- },
79
- },
80
74
  ];
81
75
  export default config;
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import ruleStrictObservableComponentsDeclaration from "./rules/strict-observable
7
7
  import ruleRequireObserver from "./rules/require-observer.js";
8
8
  import ruleMaxParentImportDepth from "./rules/max-parent-import-depth.js";
9
9
  import ruleTsNamedTupleElements from "./rules/ts-named-tuple-elements.js";
10
+ import ruleMobxSyncAutorun from "./rules/mobx-sync-autorun.js";
10
11
  const plugin = {
11
12
  meta: {
12
13
  name: packageJson.name,
@@ -22,6 +23,7 @@ const plugin = {
22
23
  'require-observer': ruleRequireObserver,
23
24
  'max-parent-import-depth': ruleMaxParentImportDepth,
24
25
  'ts-named-tuple-elements': ruleTsNamedTupleElements,
26
+ 'mobx-sync-autorun': ruleMobxSyncAutorun,
25
27
  },
26
28
  };
27
29
  export default plugin;
@@ -0,0 +1,3 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ declare const _default: ESLintUtils.RuleModule<"requireSyncAutorun", [], unknown, ESLintUtils.RuleListener>;
3
+ export default _default;
@@ -0,0 +1,26 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export default ESLintUtils.RuleCreator(() => '')({
3
+ name: 'mobx-sync-autorun',
4
+ defaultOptions: [],
5
+ meta: {
6
+ type: 'problem',
7
+ docs: {
8
+ description: "Autorun tracks only the observables that are read during the synchronous execution of the provided function, but it won't track anything that happens asynchronously.",
9
+ },
10
+ messages: {
11
+ requireSyncAutorun: '`effect` must be synchronous function',
12
+ },
13
+ schema: [],
14
+ },
15
+ create(context) {
16
+ const selector = [
17
+ 'CallExpression[callee.name="autorun"] > ArrowFunctionExpression[async="true"]',
18
+ 'CallExpression[callee.name="autorun"] > FunctionExpression[async="true"]',
19
+ ].join(', ');
20
+ return {
21
+ [selector]: node => {
22
+ context.report({ node, messageId: 'requireSyncAutorun' });
23
+ },
24
+ };
25
+ },
26
+ });
@@ -0,0 +1,29 @@
1
+ # Enforce synchronous autorun callback
2
+
3
+ Mobx `autorun` function must accept only synchronous `effect` callback.
4
+ This follows from the rules from official documentation, https://mobx.js.org/reactions.html#rules #2:
5
+
6
+ ```
7
+ Autorun tracks only the observables that are read during the synchronous execution of the provided function, but it won't track anything that happens asynchronously.
8
+ ```
9
+
10
+ It would be nice to track this at the type level, but that doesn't happen at the moment.
11
+
12
+ ## Rule Details
13
+
14
+ Examples of **incorrect** code for this rule:
15
+
16
+ ```ts
17
+ autorun(async () => {
18
+ await sleep(1);
19
+ console.log(store.value)
20
+ })
21
+ ```
22
+
23
+ Examples of **correct** code for this rule:
24
+
25
+ ```ts
26
+ autorun(() => {
27
+ console.log(store.value)
28
+ })
29
+ ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dartess/eslint-plugin",
3
3
  "type": "module",
4
- "version": "0.2.1",
4
+ "version": "0.4.0",
5
5
  "description": "A set of rules and configs for various TypeScript projects",
6
6
  "keywords": [
7
7
  "eslint",
@@ -83,7 +83,7 @@
83
83
  }
84
84
  },
85
85
  "devDependencies": {
86
- "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
86
+ "@eslint-community/eslint-plugin-eslint-comments": "^4.6.0",
87
87
  "@eslint/js": "^9.39.2",
88
88
  "@types/confusing-browser-globals": "^1.0.3",
89
89
  "@types/eslint-plugin-jsx-a11y": "^6.10.1",
@@ -1,10 +0,0 @@
1
- declare const rules: {
2
- /**
3
- * react-hooks
4
- * copied from
5
- * https://github.com/airbnb/javascript/blob/c25bce83be4db06e6a221d79686c485cd2ed5d5d/packages/eslint-config-airbnb/rules/react-hooks.js
6
- * */
7
- 'react-hooks/rules-of-hooks': "error";
8
- 'react-hooks/exhaustive-deps': "error";
9
- };
10
- export default rules;
@@ -1,17 +0,0 @@
1
- // This file contains code from the `eslint-config-airbnb` project
2
- // Original author: Jake Teton-Landis (https://twitter.com/@jitl)
3
- // License: MIT (see LICENSE-eslint-config-airbnb.md file)
4
- const rules = {
5
- /**
6
- * react-hooks
7
- * copied from
8
- * https://github.com/airbnb/javascript/blob/c25bce83be4db06e6a221d79686c485cd2ed5d5d/packages/eslint-config-airbnb/rules/react-hooks.js
9
- * */
10
- // Enforce Rules of Hooks
11
- // https://github.com/facebook/react/blob/c11015ff4f610ac2924d1fc6d569a17657a404fd/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js
12
- 'react-hooks/rules-of-hooks': 'error',
13
- // Verify the list of the dependencies for Hooks like useEffect and similar
14
- // https://github.com/facebook/react/blob/1204c789776cb01fbaf3e9f032e7e2ba85a44137/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
15
- 'react-hooks/exhaustive-deps': 'error',
16
- };
17
- export default rules;