@ospm/eslint-plugin-react-signals-hooks
Version:
ESLint plugin for React Signals hooks - enforces best practices, performance optimizations, and integration patterns for @preact/signals-react usage in React projects
121 lines • 5.76 kB
JavaScript
/* eslint-disable @typescript-eslint/no-namespace */
import '@total-typescript/ts-reset';
// Core rules
import { exhaustiveDepsRule } from './exhaustive-deps.js';
import { forbidSignalDestructuringRule } from './forbid-signal-destructuring.js';
import { forbidSignalReAssignmentRule } from './forbid-signal-re-assignment.js';
import { forbidSignalUpdateInComputedRule } from './forbid-signal-update-in-computed.js';
import { noMutationInRenderRule } from './no-mutation-in-render.js';
import { noNonSignalWithSignalSuffixRule } from './no-non-signal-with-signal-suffix.js';
import { noSignalAssignmentInEffectRule } from './no-signal-assignment-in-effect.js';
import { noSignalCreationInComponentRule } from './no-signal-creation-in-component.js';
// Performance optimization rules
import { preferBatchUpdatesRule } from './prefer-batch-updates.js';
import { preferComputedRule } from './prefer-computed.js';
import { preferForOverMapRule } from './prefer-for-over-map.js';
import { preferShowOverTernaryRule } from './prefer-show-over-ternary.js';
import { preferSignalEffectRule } from './prefer-signal-effect.js';
import { preferSignalInJsxRule } from './prefer-signal-in-jsx.js';
import { preferSignalMethodsRule } from './prefer-signal-methods.js';
import { preferSignalReadsRule } from './prefer-signal-reads.js';
import { preferUseSignalOverUseStateRule } from './prefer-use-signal-over-use-state.js';
import { preferUseSignalRefOverUseRefRule } from './prefer-use-signal-ref-over-use-ref.js';
import { preferUseComputedInReactComponentRule } from './prefer-use-computed-in-react-component.js';
import { preferUseSignalEffectInReactComponentRule } from './prefer-use-signal-effect-in-react-component.js';
// Code style rules
import { requireUseSignalsRule } from './require-use-signals.js';
import { restrictSignalLocations } from './restrict-signal-locations.js';
import { signalVariableNameRule } from './signal-variable-name.js';
import { warnOnUnnecessaryUntrackedRule } from './warn-on-unnecessary-untracked.js';
const rules = {
// Core rules
'exhaustive-deps': exhaustiveDepsRule,
'no-mutation-in-render': noMutationInRenderRule,
'no-signal-assignment-in-effect': noSignalAssignmentInEffectRule,
'no-non-signal-with-signal-suffix': noNonSignalWithSignalSuffixRule,
'no-signal-creation-in-component': noSignalCreationInComponentRule,
'require-use-signals': requireUseSignalsRule,
'restrict-signal-locations': restrictSignalLocations,
'forbid-signal-destructuring': forbidSignalDestructuringRule,
'forbid-signal-re-assignment': forbidSignalReAssignmentRule,
'forbid-signal-update-in-computed': forbidSignalUpdateInComputedRule,
// Performance optimization rules
'prefer-batch-updates': preferBatchUpdatesRule,
'prefer-computed': preferComputedRule,
'prefer-for-over-map': preferForOverMapRule,
'prefer-signal-effect': preferSignalEffectRule,
'prefer-signal-in-jsx': preferSignalInJsxRule,
'prefer-signal-methods': preferSignalMethodsRule,
'prefer-signal-reads': preferSignalReadsRule,
'prefer-use-signal-over-use-state': preferUseSignalOverUseStateRule,
'prefer-use-signal-ref-over-use-ref': preferUseSignalRefOverUseRefRule,
'prefer-use-computed-in-react-component': preferUseComputedInReactComponentRule,
'prefer-use-signal-effect-in-react-component': preferUseSignalEffectInReactComponentRule,
// Code style rules
'prefer-show-over-ternary': preferShowOverTernaryRule,
'signal-variable-name': signalVariableNameRule,
'warn-on-unnecessary-untracked': warnOnUnnecessaryUntrackedRule,
};
const configRules = {
'react-hooks/exhaustive-deps': 'off',
'exhaustive-deps': 'error',
'no-mutation-in-render': 'error',
'no-signal-assignment-in-effect': 'error',
'no-non-signal-with-signal-suffix': 'error',
'no-signal-creation-in-component': 'error',
'require-use-signals': 'error',
'restrict-signal-locations': 'error',
'forbid-signal-destructuring': 'error',
'forbid-signal-re-assignment': 'error',
'forbid-signal-update-in-computed': 'error',
// Performance optimization rules
'prefer-batch-updates': 'error',
'prefer-computed': 'error',
'prefer-for-over-map': 'error',
'prefer-signal-effect': 'error',
'prefer-signal-in-jsx': 'error',
'prefer-signal-methods': 'error',
'prefer-signal-reads': 'error',
'prefer-use-signal-over-use-state': 'error',
'prefer-use-signal-ref-over-use-ref': 'error',
'prefer-use-computed-in-react-component': 'error',
'prefer-use-signal-effect-in-react-component': 'error',
// Code style rules
'prefer-show-over-ternary': 'error',
'signal-variable-name': 'error',
'warn-on-unnecessary-untracked': 'error',
};
const recommendedConfig = {
name: 'react-signals-hooks/recommended',
plugins: {
get 'react-signals-hooks'() {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return plugin;
},
},
rules: configRules,
};
const plugin = {
meta: { name: 'eslint-plugin-react-signals-hooks' },
rules,
configs: {
'recommended-legacy': {
plugins: ['react-signals-hooks'],
rules: configRules,
},
recommended: recommendedConfig,
'recommended-latest': recommendedConfig,
},
};
// Export for both ESM and CommonJS
const configs = plugin.configs;
const meta = plugin.meta;
// Export for ESLint 9+ (flat config)
export { configs, meta, rules };
// Export for ESLint 8 (legacy config)
export const configsLegacy = configs;
export const metaLegacy = meta;
export const rulesLegacy = rules;
// Default export for backward compatibility
export default plugin;
//# sourceMappingURL=index.js.map