Skip to content

Commit 7673a6f

Browse files
authored
refactor: simplify the data modeling in value construction and web api (#897)
1 parent c3f6f32 commit 7673a6f

File tree

42 files changed

+207
-1582
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+207
-1582
lines changed

eslint.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import eslintConfigFlatGitignore from "eslint-config-flat-gitignore";
1919
import tseslint from "typescript-eslint";
2020

2121
const dirname = url.fileURLToPath(new URL(".", import.meta.url));
22-
2322
const GLOB_JS = ["*.{js,jsx,cjs,mjs}", "**/*.{js,jsx,cjs,mjs}"];
2423
const GLOB_TS = ["*.{ts,tsx,cts,mts}", "**/*.{ts,tsx,cts,mts}"];
2524
const GLOB_MD = ["*.md", "**/*.md"];
Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
11
import type { ERSemanticEntry } from "@eslint-react/core";
22
import type { O } from "@eslint-react/eff";
3-
import { Data } from "@eslint-react/eff";
4-
import type { Pretty } from "@eslint-react/types";
53
import type { TSESTree } from "@typescript-eslint/types";
64

7-
export type EventListenerEntry = Data.TaggedEnum<{
8-
AddEventListener: Pretty<
9-
{
10-
type: TSESTree.Node;
11-
node: TSESTree.CallExpression | TSESTree.Identifier;
12-
callee: TSESTree.Node;
13-
capture: O.Option<boolean>;
14-
listener: TSESTree.Node;
15-
signal: O.Option<TSESTree.Node>;
16-
} & ERSemanticEntry
17-
>;
18-
RemoveEventListener: Pretty<
19-
{
20-
type: TSESTree.Node;
21-
node: TSESTree.CallExpression | TSESTree.Identifier;
22-
callee: TSESTree.Node;
23-
capture: O.Option<boolean>;
24-
listener: TSESTree.Node;
25-
} & ERSemanticEntry
26-
>;
27-
}>;
28-
29-
export const EventListenerEntry = Data.taggedEnum<EventListenerEntry>();
5+
export type EventListenerEntry =
6+
| {
7+
kind: "addEventListener";
8+
type: TSESTree.Node;
9+
node: TSESTree.CallExpression | TSESTree.Identifier;
10+
callee: TSESTree.Node;
11+
capture: O.Option<boolean>;
12+
listener: TSESTree.Node;
13+
signal: O.Option<TSESTree.Node>;
14+
} & ERSemanticEntry
15+
| {
16+
kind: "removeEventListener";
17+
type: TSESTree.Node;
18+
node: TSESTree.CallExpression | TSESTree.Identifier;
19+
callee: TSESTree.Node;
20+
capture: O.Option<boolean>;
21+
listener: TSESTree.Node;
22+
} & ERSemanticEntry;

packages/plugins/eslint-plugin-react-web-api/src/models/EventListener/EventListenerMethod.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
export * from "./EventListenerEntry";
2-
export type * from "./EventListenerMethod";
1+
export type * from "./EventListenerEntry";
Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,30 @@
11
/* eslint-disable perfectionist/sort-object-types */
22
import type { ERSemanticEntry } from "@eslint-react/core";
3-
import { Data } from "@eslint-react/eff";
4-
import type { Pretty } from "@eslint-react/types";
53
import type { TSESTree } from "@typescript-eslint/types";
64

75
import type { ObserverKind } from "./ObserverKind";
86

9-
export type ObserverEntry = Data.TaggedEnum<{
10-
Observe: Pretty<
11-
{
12-
kind: ObserverKind;
13-
node: TSESTree.CallExpression;
14-
element: TSESTree.Node;
15-
callee: TSESTree.Node;
16-
observer: TSESTree.Node;
17-
} & ERSemanticEntry
18-
>;
19-
Unobserve: Pretty<
20-
{
21-
kind: ObserverKind;
22-
node: TSESTree.CallExpression;
23-
element: TSESTree.Node;
24-
callee: TSESTree.Node;
25-
observer: TSESTree.Node;
26-
} & ERSemanticEntry
27-
>;
28-
Disconnect: Pretty<
29-
{
30-
kind: ObserverKind;
31-
node: TSESTree.CallExpression;
32-
callee: TSESTree.Node;
33-
observer: TSESTree.Node;
34-
} & ERSemanticEntry
35-
>;
36-
}>;
37-
38-
export const ObserverEntry = Data.taggedEnum<ObserverEntry>();
7+
export type ObserverEntry =
8+
| {
9+
kind: "disconnect";
10+
node: TSESTree.CallExpression;
11+
callee: TSESTree.Node;
12+
observer: TSESTree.Node;
13+
observerKind: ObserverKind;
14+
} & ERSemanticEntry
15+
| {
16+
kind: "observe";
17+
node: TSESTree.CallExpression;
18+
element: TSESTree.Node;
19+
callee: TSESTree.Node;
20+
observer: TSESTree.Node;
21+
observerKind: ObserverKind;
22+
} & ERSemanticEntry
23+
| {
24+
kind: "unobserve";
25+
node: TSESTree.CallExpression;
26+
element: TSESTree.Node;
27+
callee: TSESTree.Node;
28+
observer: TSESTree.Node;
29+
observerKind: ObserverKind;
30+
} & ERSemanticEntry;

packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-event-listener.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type { ReportDescriptor } from "@typescript-eslint/utils/ts-eslint";
1212
import { isMatching, match, P } from "ts-pattern";
1313

1414
import { createRule, getPhaseKindOfFunction } from "../utils";
15-
import { EventListenerEntry } from "./../models";
15+
import type { EventListenerEntry } from "./../models";
1616

1717
// #region Rule Metadata
1818

@@ -37,9 +37,9 @@ type EventMethodKind = "addEventListener" | "removeEventListener";
3737
type CallKind = EventMethodKind | EREffectMethodKind | ERLifecycleMethodKind | "abort" | "other";
3838
/* eslint-enable perfectionist/sort-union-types */
3939

40-
export type AEntry = EventListenerEntry & { _tag: "AddEventListener" };
40+
export type AEntry = EventListenerEntry & { kind: "addEventListener" };
4141

42-
export type REntry = EventListenerEntry & { _tag: "RemoveEventListener" };
42+
export type REntry = EventListenerEntry & { kind: "removeEventListener" };
4343

4444
// #endregion
4545

@@ -220,29 +220,31 @@ export default createRule<[], MessageID>({
220220
const opts = options ? getOptions(options, context.sourceCode.getScope(options)) : defaultOptions;
221221
const { callee } = node;
222222
O.map(checkInlineFunction(node, callKind, opts), context.report);
223-
aEntries.push(EventListenerEntry.AddEventListener({
223+
aEntries.push({
224224
...opts,
225+
kind: "addEventListener",
225226
type,
226227
node,
227228
callee,
228229
listener,
229230
phase: fKind,
230-
}));
231+
});
231232
})
232233
.with("removeEventListener", (callKind) => {
233234
const [type, listener, options] = node.arguments;
234235
if (!type || !listener) return;
235236
const opts = options ? getOptions(options, context.sourceCode.getScope(options)) : defaultOptions;
236237
const { callee } = node;
237238
O.map(checkInlineFunction(node, callKind, opts), context.report);
238-
rEntries.push(EventListenerEntry.RemoveEventListener({
239+
rEntries.push({
239240
...opts,
241+
kind: "removeEventListener",
240242
type,
241243
node,
242244
callee,
243245
listener,
244246
phase: fKind,
245-
}));
247+
});
246248
})
247249
.with("abort", () => {
248250
abortedSignals.push(node.callee);

packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-resize-observer.ts

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
99
import { isMatching, match, P } from "ts-pattern";
1010

1111
import { createRule, getInstanceID, getPhaseKindOfFunction, isInstanceIDEqual } from "../utils";
12-
import type { ObserverMethod } from "./../models";
13-
import { ObserverEntry } from "./../models";
12+
import type { ObserverEntry, ObserverMethod } from "./../models";
1413

1514
// #region Rule Metadata
1615

@@ -34,9 +33,9 @@ type FunctionKind = ERPhaseKind | "other";
3433
type CallKind = ObserverMethod | EREffectMethodKind | "other";
3534
/* eslint-enable perfectionist/sort-union-types */
3635

37-
export type OEntry = ObserverEntry & { _tag: "Observe" };
38-
export type UEntry = ObserverEntry & { _tag: "Unobserve" };
39-
export type DEntry = ObserverEntry & { _tag: "Disconnect" };
36+
export type OEntry = ObserverEntry & { kind: "observe" };
37+
export type UEntry = ObserverEntry & { kind: "unobserve" };
38+
export type DEntry = ObserverEntry & { kind: "disconnect" };
4039

4140
// #endregion
4241

@@ -132,43 +131,40 @@ export default createRule<[], MessageID>({
132131
const { object } = node.callee;
133132
match(getCallKind(node, context))
134133
.with("disconnect", () => {
135-
dEntries.push(
136-
ObserverEntry.Disconnect({
137-
kind: "ResizeObserver",
138-
node,
139-
callee: node.callee,
140-
observer: object,
141-
phase: fKind,
142-
}),
143-
);
134+
dEntries.push({
135+
kind: "disconnect",
136+
node,
137+
callee: node.callee,
138+
observer: object,
139+
observerKind: "ResizeObserver",
140+
phase: fKind,
141+
});
144142
})
145143
.with("observe", () => {
146144
const [element] = node.arguments;
147145
if (!element) return;
148-
oEntries.push(
149-
ObserverEntry.Observe({
150-
kind: "ResizeObserver",
151-
node,
152-
callee: node.callee,
153-
element,
154-
observer: object,
155-
phase: fKind,
156-
}),
157-
);
146+
oEntries.push({
147+
kind: "observe",
148+
node,
149+
callee: node.callee,
150+
element,
151+
observer: object,
152+
observerKind: "ResizeObserver",
153+
phase: fKind,
154+
});
158155
})
159156
.with("unobserve", () => {
160157
const [element] = node.arguments;
161158
if (!element) return;
162-
uEntries.push(
163-
ObserverEntry.Unobserve({
164-
kind: "ResizeObserver",
165-
node,
166-
callee: node.callee,
167-
element,
168-
observer: object,
169-
phase: fKind,
170-
}),
171-
);
159+
uEntries.push({
160+
kind: "unobserve",
161+
node,
162+
callee: node.callee,
163+
element,
164+
observer: object,
165+
observerKind: "ResizeObserver",
166+
phase: fKind,
167+
});
172168
})
173169
.otherwise(F.constVoid);
174170
},

packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-context-value.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default createRule<[], MessageID>({
3838
name: RULE_NAME,
3939
create(context) {
4040
const { ctx, listeners } = useComponentCollector(context);
41-
const constructions = new Map<AST.TSESTreeFunction, VAR.Construction[]>();
41+
const constructions = new Map<AST.TSESTreeFunction, VAR.ValueConstruction[]>();
4242

4343
return {
4444
...listeners,
@@ -63,11 +63,11 @@ export default createRule<[], MessageID>({
6363
: O.none()),
6464
O.bind("construction", ({ valueExpression }) => {
6565
const initialScope = context.sourceCode.getScope(valueExpression);
66-
return O.some(VAR.inspectConstruction(valueExpression, initialScope));
66+
return O.some(VAR.getValueConstruction(valueExpression, initialScope));
6767
}),
6868
);
6969
for (const { construction, function: [_, fNode] } of O.toArray(constructionEntry)) {
70-
if (construction._tag === "None") continue;
70+
if (construction.kind === "None") continue;
7171
if (isReactHookCall(construction.node)) continue;
7272
constructions.set(fNode, [
7373
...constructions.get(fNode) ?? [],
@@ -79,9 +79,9 @@ export default createRule<[], MessageID>({
7979
const components = ctx.getAllComponents(node).values();
8080
for (const { node: component } of components) {
8181
for (const construction of constructions.get(component) ?? []) {
82-
if (construction._tag === "None") continue;
83-
const { node: constructionNode, _tag } = construction;
84-
const messageId = _tag.startsWith("Function")
82+
if (construction.kind === "None") continue;
83+
const { kind, node: constructionNode } = construction;
84+
const messageId = kind.startsWith("Function")
8585
? "noUnstableContextValueWithFunction"
8686
: "noUnstableContextValueWithIdentifier";
8787
context.report({

packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-default-props.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ export default createRule<[], MessageID>({
6565
const { value } = prop;
6666
const { right } = value;
6767
const initialScope = context.sourceCode.getScope(value);
68-
const construction = VAR.inspectConstruction(
68+
const construction = VAR.getValueConstruction(
6969
value,
7070
initialScope,
71-
VAR.ConstructionHint.StrictCallExpression,
71+
VAR.ValueConstructionHint.StrictCallExpression,
7272
);
73-
if (construction._tag === "None") continue;
73+
if (construction.kind === "None") continue;
7474
if (isReactHookCall(construction.node)) continue;
7575
const forbiddenType = AST.toReadableNodeType(right);
7676
context.report({

packages/utilities/eff/docs/Either.js/interfaces/Left.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
## Extends
1414

15-
- `Pipeable`.`Inspectable`.`Effect`\<`R`, `L`\>.`STM`\<`R`, `L`\>
15+
- `Pipeable`.`Inspectable`.`STM`\<`R`, `L`\>.`Effect`\<`R`, `L`\>
1616

1717
## Type Parameters
1818

0 commit comments

Comments
 (0)