@groma/scanner-react 0.1.2 → 0.1.3

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 CHANGED
@@ -68,16 +68,19 @@ direct bindings produce `unsupported-react-binding` diagnostics and no certain
68
68
  claim. Components that cannot resolve to a supported source function do not
69
69
  establish a callback interaction.
70
70
 
71
- TSX and TypeScript edits use the existing watch lifecycle. All enabled scanners
72
- must complete before architecture changes. See [validation](validation.md) for
71
+ TSX and TypeScript edits use the existing watch lifecycle. Healthy scanners update the architecture while failed scanners keep their saved evidence. See [validation](validation.md) for
73
72
  the executed artifact checks and remaining release gates.
74
73
 
75
74
  ## Nested projects
76
75
 
77
76
  Run Groma from the repository root. The scanner finds package declarations in
78
77
  tracked and unignored files, including nested apps and libraries. Dependencies,
79
- dev dependencies, peer dependencies and optional dependencies identify framework
80
- projects. Each compiler uses that project's configuration and installed dependencies;
78
+ dev dependencies, peer dependencies and optional dependencies identify candidates.
79
+ A candidate also needs a tracked or unignored `tsconfig.json` and TSX source
80
+ files belonging to that package, outside nested packages. Declaration files and
81
+ inactive fixtures with a `.fixture` suffix do not qualify. Packages with only
82
+ framework tooling dependencies are skipped. No matching project produces no evidence. Each compiler uses that project's configuration and installed dependencies;
81
83
  imported source in sibling repository libraries keeps its original source path.
82
- Readiness checks all selected projects. A project error fails the complete scan.
84
+ Readiness checks all selected projects. An invalid selected project fails this scanner's observation; other scanners
85
+ can still update the architecture.
83
86
  Source and nested package/configuration changes use the shared scanner watch flow.
package/dist/index.js CHANGED
@@ -199,9 +199,22 @@ async function projectFiles(root, matches) {
199
199
  function hasDependency(manifest, dependency) {
200
200
  return ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"].some((section) => typeof manifest[section]?.[dependency] === "string");
201
201
  }
202
- async function frameworkProjects(root, dependency) {
202
+ async function frameworkProjects(root, dependency, extensions) {
203
+ const files = await projectFiles(root, () => true);
204
+ const manifests = files.filter((file) => path.posix.basename(file) === "package.json");
205
+ const directories = new Set(manifests.map((file) => path.posix.dirname(file)));
206
+ const sources = new Set;
207
+ for (const file of files.filter((file) => extensions.some((extension) => file.endsWith(extension)) && !file.endsWith(".d.ts"))) {
208
+ let directory = path.posix.dirname(file);
209
+ while (directory !== "." && !directories.has(directory))
210
+ directory = path.posix.dirname(directory);
211
+ sources.add(directory);
212
+ }
203
213
  const projects = [];
204
- for (const file of await projectFiles(root, (file) => path.posix.basename(file) === "package.json")) {
214
+ for (const file of manifests) {
215
+ const directory = path.posix.dirname(file);
216
+ if (!sources.has(directory) || !files.includes(path.posix.join(directory, "tsconfig.json")))
217
+ continue;
205
218
  const manifest = JSON.parse(await readFile(path.join(root, file), "utf8"));
206
219
  if (hasDependency(manifest, dependency))
207
220
  projects.push(path.dirname(path.join(root, file)));
@@ -435,15 +448,13 @@ class Evidence {
435
448
  }
436
449
  }
437
450
  async function checkReactReadiness(root) {
438
- const projects = await frameworkProjects(root, "react");
439
- if (!projects.length)
440
- throw new Error("REACT_PROJECT_REQUIRED: No React project declaration was found.");
451
+ const projects = await frameworkProjects(root, "react", [".tsx"]);
441
452
  for (const project of projects)
442
453
  reactProject(project, root);
443
454
  }
444
455
  async function scanReact(root) {
445
456
  const parts = [];
446
- for (const project of await frameworkProjects(root, "react")) {
457
+ for (const project of await frameworkProjects(root, "react", [".tsx"])) {
447
458
  const observation = await scanReactProject(project, root);
448
459
  if (observation)
449
460
  parts.push({ key: relative(root, project), observation });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groma/scanner-react",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Complementary React framework evidence; a dependency declaration does not verify runtime use.",
5
5
  "private": false,
6
6
  "type": "module",