@starci/eslint-canon-fe 1.4.5 → 3.0.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/README.md +38 -86
- package/class-names.mjs +145 -0
- package/file-layout.mjs +6 -7
- package/grammar-boundary.mjs +16 -0
- package/index.mjs +19 -4
- package/landmark.mjs +29 -242
- package/package.json +2 -4
- package/props-and-slots.mjs +148 -452
- package/the-split.mjs +17 -10
- package/vendor-boundary.mjs +24 -595
- package/contract.mjs +0 -1387
- package/contracts.ts +0 -312
- package/props.ts +0 -145
package/the-split.mjs
CHANGED
|
@@ -73,8 +73,10 @@ export const connectedBlockHasPresentationalTwin = {
|
|
|
73
73
|
"`{{block}}` reads the world, so it must import exact `{{twin}}` from `./component`. A single leaf, one tree, or no local state is not an exception.",
|
|
74
74
|
bypass:
|
|
75
75
|
"Connected `{{block}}` renders `<{{rendered}}>` directly. Resolve the world here, then render only `<{{twin}}>`; component.tsx owns the complete presentation.",
|
|
76
|
-
unused:
|
|
77
|
-
"Connected `{{block}}` imports `{{twin}}` but never renders it. Every connected render path must cross the pure twin.",
|
|
76
|
+
unused:
|
|
77
|
+
"Connected `{{block}}` imports `{{twin}}` but never renders it. Every connected render path must cross the pure twin.",
|
|
78
|
+
called:
|
|
79
|
+
"Connected `{{block}}` calls `{{twin}}(...)` as an ordinary function. Render `<{{twin}} />` so React owns the twin's hook lifecycle and every render keeps one stable component boundary.",
|
|
78
80
|
},
|
|
79
81
|
},
|
|
80
82
|
create(context) {
|
|
@@ -82,8 +84,9 @@ export const connectedBlockHasPresentationalTwin = {
|
|
|
82
84
|
if (!block) return {}
|
|
83
85
|
|
|
84
86
|
const twin = `${block}Base`
|
|
85
|
-
const worldBindings = new Set()
|
|
86
|
-
const rendered = []
|
|
87
|
+
const worldBindings = new Set()
|
|
88
|
+
const rendered = []
|
|
89
|
+
const calledTwin = []
|
|
87
90
|
let importsTwin = false
|
|
88
91
|
let readsWorld = false
|
|
89
92
|
let rendersTwin = false
|
|
@@ -98,9 +101,10 @@ export const connectedBlockHasPresentationalTwin = {
|
|
|
98
101
|
if (imported && local && REACHES_FOR_THE_WORLD.test(imported)) worldBindings.add(local)
|
|
99
102
|
}
|
|
100
103
|
},
|
|
101
|
-
CallExpression(node) {
|
|
102
|
-
if (node.callee?.type !== "Identifier") return
|
|
103
|
-
if (
|
|
104
|
+
CallExpression(node) {
|
|
105
|
+
if (node.callee?.type !== "Identifier") return
|
|
106
|
+
if (node.callee.name === twin) calledTwin.push(node)
|
|
107
|
+
if (worldBindings.has(node.callee.name) || REACHES_FOR_THE_WORLD.test(node.callee.name)) {
|
|
104
108
|
readsWorld = true
|
|
105
109
|
}
|
|
106
110
|
},
|
|
@@ -115,7 +119,7 @@ export const connectedBlockHasPresentationalTwin = {
|
|
|
115
119
|
context.report({ node, messageId: "missing", data: { block, twin } })
|
|
116
120
|
return
|
|
117
121
|
}
|
|
118
|
-
for (const entry of rendered) {
|
|
122
|
+
for (const entry of rendered) {
|
|
119
123
|
if (entry.name !== twin) {
|
|
120
124
|
context.report({
|
|
121
125
|
node: entry.node,
|
|
@@ -123,8 +127,11 @@ export const connectedBlockHasPresentationalTwin = {
|
|
|
123
127
|
data: { block, rendered: entry.name, twin },
|
|
124
128
|
})
|
|
125
129
|
}
|
|
126
|
-
}
|
|
127
|
-
|
|
130
|
+
}
|
|
131
|
+
for (const call of calledTwin) {
|
|
132
|
+
context.report({ node: call, messageId: "called", data: { block, twin } })
|
|
133
|
+
}
|
|
134
|
+
if (!rendersTwin) context.report({ node, messageId: "unused", data: { block, twin } })
|
|
128
135
|
},
|
|
129
136
|
}
|
|
130
137
|
},
|