Skip to content

Commit 146541d

Browse files
committed
perf(shared): replace micro-memoize and fast-equals with builtins
1 parent 17fbc4e commit 146541d

File tree

14 files changed

+132
-90
lines changed

14 files changed

+132
-90
lines changed

apps/website/content/docs/configuration/configure-analyzer.mdx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export default [
3232

3333
Defines the React version for semantic analysis.
3434

35-
- `"detect"`: Auto-detects from project dependencies (defaults to `19.1.0` if undetectable)
35+
- `detect`: Auto-detects from project dependencies (defaults to `19.1.0` if undetectable)
3636
- `string`: Explicit version specification (e.g., `"18.3.1"`)
3737

3838
### `importSource`
@@ -73,10 +73,13 @@ Example with `polymorphicPropName` set to `as`:
7373
### `additionalComponents` (Experimental)
7474

7575
<Callout type="info">
76-
Consider using `polymorphicPropName` instead when possible, as it's simpler and more efficient.
76+
Consider using `polymorphicPropName` instead when possible, as it's simpler
77+
and more efficient.
7778
</Callout>
7879

79-
<Callout type="warn">Experimental feature that may lack stability and documentation.</Callout>
80+
<Callout type="warn">
81+
Experimental feature that may lack stability and documentation.
82+
</Callout>
8083

8184
Maps components and their attributes for comprehensive analysis. Supports default attribute values.
8285

@@ -102,9 +105,10 @@ This makes `<EmbedContent src="https://eslint-react.xyz" />{:tsx}` evaluate as `
102105
### `additionalHooks` (Experimental)
103106

104107
<Callout type="warn">
105-
Intended for edge cases. We suggest to use this option **very sparingly, if at all**. Generally saying, we recommend
106-
most custom Hooks do not vary the built-in React Hooks, and instead provide a higher-level API that is more focused
107-
around a specific use case.
108+
Intended for edge cases. We suggest to use this option **very sparingly, if at
109+
all**. Generally saying, we recommend most custom Hooks do not vary the
110+
built-in React Hooks, and instead provide a higher-level API that is more
111+
focused around a specific use case.
108112
</Callout>
109113

110114
Alias variants to built-in React Hooks for rule compatibility:

apps/website/content/docs/presets.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ title: Presets
55
The following presets are available in `@eslint-react/eslint-plugin`:
66

77
<Callout type="info">
8-
For ESLint Legacy Config (`.eslintrc.*`), add a `-legacy` suffix to the preset name (e.g. `recommended-legacy`).
8+
For ESLint Legacy Config (`.eslintrc.*`), add a `-legacy` suffix to the preset
9+
name (e.g. `recommended-legacy`).
910
</Callout>
1011

1112
## Bare Bones

apps/website/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
"@chevrotain/regexp-to-ast": "^11.0.3",
1414
"bsky-react-post": "^0.1.7",
1515
"clsx": "^2.1.1",
16-
"fumadocs-core": "15.2.6",
16+
"fumadocs-core": "15.2.7",
1717
"fumadocs-docgen": "2.0.0",
18-
"fumadocs-mdx": "11.5.8",
19-
"fumadocs-twoslash": "3.1.0",
18+
"fumadocs-mdx": "11.6.0",
19+
"fumadocs-twoslash": "3.1.1",
2020
"fumadocs-typescript": "4.0.2",
21-
"fumadocs-ui": "15.2.6",
21+
"fumadocs-ui": "15.2.7",
2222
"lucide-react": "^0.488.0",
2323
"next": "^15.3.0",
2424
"next-view-transitions": "^0.3.4",

apps/website/source.config.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import { remarkMermaid } from "@theguild/remark-mermaid";
12
import { rehypeCodeDefaultOptions } from "fumadocs-core/mdx-plugins";
23
import { remarkDocGen, remarkInstall } from "fumadocs-docgen";
34
import { defineConfig, defineDocs } from "fumadocs-mdx/config";
45
import { transformerTwoslash } from "fumadocs-twoslash";
5-
import { remarkMermaid } from "@theguild/remark-mermaid";
66

77
export const docs = defineDocs({
88
dir: "content/docs",
@@ -14,7 +14,25 @@ export default defineConfig({
1414
rehypeCodeOptions: {
1515
experimentalJSEngine: true,
1616
inline: "tailing-curly-colon",
17-
langs: ["js", "ts", "jsx", "tsx", "html", "md", "mdx", "css", "json", "yaml"],
17+
langs: [
18+
"bash",
19+
"css",
20+
"html",
21+
"js",
22+
"json",
23+
"jsx",
24+
"lisp",
25+
"log",
26+
"md",
27+
"mdx",
28+
"regexp",
29+
"sh",
30+
"shell",
31+
"ts",
32+
"tsx",
33+
"yaml",
34+
"diff",
35+
],
1836
lazy: true,
1937
themes: {
2038
dark: "github-dark",

eslint.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import url from "node:url";
33
import markdown from "@eslint/markdown";
44
import * as configs from "@local/configs/eslint";
55
import pluginLocal from "@local/eslint-plugin-local";
6-
import configFlatGitignore from "eslint-config-flat-gitignore";
6+
import gitIgnores from "eslint-config-flat-gitignore";
77
import pluginVitest from "eslint-plugin-vitest";
88
import { globalIgnores } from "eslint/config";
99
import tseslint from "typescript-eslint";
@@ -22,7 +22,6 @@ const GLOB_TEST = [
2222
const GLOB_CONFIG = ["*.config.{ts,tsx,cts,mts}", "**/*.config.{ts,tsx,cts,mts}"];
2323
const GLOB_SCRIPT = ["scripts/**/*.{ts,cts,mts}"];
2424
const GLOB_IGNORES = [
25-
...configFlatGitignore().ignores,
2625
"apps",
2726
"docs",
2827
"test",
@@ -36,6 +35,7 @@ const packagesTsConfigs = [
3635
];
3736

3837
export default tseslint.config(
38+
gitIgnores(),
3939
globalIgnores(GLOB_IGNORES),
4040
{
4141
extends: [

packages/core/src/hook/hook-is.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { RuleContext } from "@eslint-react/kit";
33
import type { TSESTree } from "@typescript-eslint/types";
44
import * as AST from "@eslint-react/ast";
55
import { constFalse, flip } from "@eslint-react/eff";
6-
import { unsafeDecodeSettings } from "@eslint-react/shared";
6+
import { coerceSettings } from "@eslint-react/shared";
77
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
88

99
import { DEFAULT_ESLINT_REACT_SETTINGS } from "../../../shared/src/schemas";
@@ -41,7 +41,7 @@ export function isReactHookCallWithName(context: RuleContext, node: TSESTree.Nod
4141
const {
4242
importSource = DEFAULT_ESLINT_REACT_SETTINGS.importSource,
4343
skipImportCheck = true,
44-
} = unsafeDecodeSettings(context.settings);
44+
} = coerceSettings(context.settings);
4545
const initialScope = context.sourceCode.getScope(node);
4646
return (name: string) => {
4747
switch (true) {
@@ -77,7 +77,7 @@ export function isReactHookCallWithNameAlias(context: RuleContext, name: string,
7777
const {
7878
importSource = DEFAULT_ESLINT_REACT_SETTINGS.importSource,
7979
skipImportCheck = true,
80-
} = unsafeDecodeSettings(context.settings);
80+
} = coerceSettings(context.settings);
8181
return (node: TSESTree.CallExpression) => {
8282
const initialScope = context.sourceCode.getScope(node);
8383
switch (true) {

packages/core/src/utils/is-from-react.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { RuleContext } from "@eslint-react/kit";
33
import type { Scope } from "@typescript-eslint/scope-manager";
44
import type { TSESTree } from "@typescript-eslint/types";
55
import { type _, dual } from "@eslint-react/eff";
6-
import { DEFAULT_ESLINT_REACT_SETTINGS, unsafeDecodeSettings } from "@eslint-react/shared";
6+
import { coerceSettings, DEFAULT_ESLINT_REACT_SETTINGS } from "@eslint-react/shared";
77
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
88

99
import { isInitializedFromReact } from "./is-initialized-from-react";
@@ -59,7 +59,7 @@ export function isFromReact(name: string): isFromReact.ReturnType {
5959
// dprint-ignore
6060
return dual(2, (context: RuleContext, node: TSESTree.Node | _): node is TSESTree.Identifier | TSESTree.MemberExpression => {
6161
if (node == null) return false;
62-
const { importSource = defaultImportSource, skipImportCheck = true } = unsafeDecodeSettings(context.settings);
62+
const { importSource = defaultImportSource, skipImportCheck = true } = coerceSettings(context.settings);
6363
if (skipImportCheck) return isFromReactLoose(node, name);
6464
return isFromReactStrict(node, name, importSource, context.sourceCode.getScope(node));
6565
});
@@ -70,7 +70,7 @@ export function isFromReactObject(objectName: string, propertyName: string): isF
7070
// dprint-ignore
7171
return dual(2, (context: RuleContext, node: TSESTree.Node | _): node is TSESTree.Identifier | TSESTree.MemberExpression => {
7272
if (node?.type !== T.MemberExpression) return false;
73-
const { importSource = defaultImportSource, skipImportCheck = true } = unsafeDecodeSettings(context.settings);
73+
const { importSource = defaultImportSource, skipImportCheck = true } = coerceSettings(context.settings);
7474
const { object, property } = node;
7575
if (skipImportCheck) return isFromReactLoose(object, objectName) && isFromReactLoose(property, propertyName);
7676
return isFromReactStrict(

packages/plugins/eslint-plugin-react-x/src/rules/jsx-no-duplicate-props.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ Disallow duplicate props in JSX elements.
2828
### Failing
2929

3030
```tsx
31-
<Hello name="John" name="Doe" />
31+
<Hello name="John" name="Doe" />;
3232
```
3333

3434
### Passing
3535

3636
```tsx
37-
<Hello name="John" />
37+
<Hello name="John" />;
3838
```
3939

4040
## Implementation

packages/plugins/eslint-plugin-react-x/src/rules/no-array-index-key.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as AST from "@eslint-react/ast";
55
import * as ER from "@eslint-react/core";
66
import { _ } from "@eslint-react/eff";
77
import { Reporter as RPT, type RuleContext, type RuleFeature } from "@eslint-react/kit";
8-
import { unsafeDecodeSettings } from "@eslint-react/shared";
8+
import { coerceSettings } from "@eslint-react/shared";
99
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
1010
import { isMatching } from "ts-pattern";
1111

@@ -24,7 +24,7 @@ function isReactChildrenMethod(name: string): name is typeof reactChildrenMethod
2424
}
2525

2626
function isUsingReactChildren(context: RuleContext, node: TSESTree.CallExpression) {
27-
const { importSource = "react" } = unsafeDecodeSettings(context.settings);
27+
const { importSource = "react" } = coerceSettings(context.settings);
2828
const { callee } = node;
2929
if (!("property" in callee) || !("object" in callee) || !("name" in callee.property)) {
3030
return false;

packages/shared/docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
## Functions
3232

33+
- [coerceSettings](functions/coerceSettings.md)
3334
- [getId](functions/getId.md)
3435
- [getReactVersion](functions/getReactVersion.md)
3536
- [getSettingsFromContext](functions/getSettingsFromContext.md)

0 commit comments

Comments
 (0)