@rayburst/cli 0.4.4 → 0.4.6

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.
@@ -434,15 +434,15 @@ function createRouterDecisionNode(sourceFilePath, gitHash, routeCount) {
434
434
  };
435
435
  }
436
436
  function extractRoutePathFromFile(routeFilePath) {
437
- let path5 = routeFilePath.replace(/^src\/routes\//, "/").replace(/\.(tsx?|jsx?)$/, "").replace(/\/route$/, "").replace(/\/index$/, "");
438
- if (path5 === "/__root") {
437
+ let path6 = routeFilePath.replace(/^src\/routes\//, "/").replace(/\.(tsx?|jsx?)$/, "").replace(/\/route$/, "").replace(/\/index$/, "");
438
+ if (path6 === "/__root") {
439
439
  return "/";
440
440
  }
441
- path5 = path5.replace(/\/\$([^/]+)/g, (_, param) => `/:${param}`);
442
- if (path5 === "" || path5 === "/") {
441
+ path6 = path6.replace(/\/\$([^/]+)/g, (_, param) => `/:${param}`);
442
+ if (path6 === "" || path6 === "/") {
443
443
  return "/";
444
444
  }
445
- return path5;
445
+ return path6;
446
446
  }
447
447
  function createConfigBasedEdges(sourceNode, targetFilePaths, nodeMap, edges, edgeType = "config", useRoutePathLabels = false) {
448
448
  let edgesCreated = 0;
@@ -650,7 +650,7 @@ function traceConfigToComponentPaths(configObject, propertyName, projectPath, pr
650
650
  }
651
651
  return [];
652
652
  }
653
- function detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectPath, project, gitHash, externalNodeMap) {
653
+ function detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectPath, project, gitHash, externalNodeMap, usedIds, idCounters) {
654
654
  let totalEdgesCreated = 0;
655
655
  try {
656
656
  const jsxElements = sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement);
@@ -747,7 +747,18 @@ function detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectP
747
747
  for (const routeFilePath of componentPaths) {
748
748
  const routePath = extractRoutePathFromFile(routeFilePath);
749
749
  const isDynamic = routePath.includes(":");
750
- const decisionNodeId = `${routerNode.id}::decision::${routePath.replace(/[/:]/g, "_")}`;
750
+ const routePathNormalized = routePath.replace(/[/:]/g, "_");
751
+ const decisionNodeName = `RouterDecision::decision::${routePathNormalized}`;
752
+ const routerIdParts = routerNode.id.split("::");
753
+ const sourceFilePath = routerIdParts[0];
754
+ const gitHash2 = routerIdParts[2];
755
+ const decisionNodeId = getUniqueNodeId(
756
+ sourceFilePath,
757
+ decisionNodeName,
758
+ gitHash2,
759
+ usedIds,
760
+ idCounters
761
+ );
751
762
  const decisionNode = {
752
763
  id: decisionNodeId,
753
764
  type: "conditional",
@@ -879,7 +890,7 @@ async function analyzeProject(projectPath, projectId, onLog) {
879
890
  log(` Analyzing config-based components...`);
880
891
  let totalConfigEdges = 0;
881
892
  for (const sourceFile of sourceFiles) {
882
- const configEdges = detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectPath, project, gitHash, externalNodeMap);
893
+ const configEdges = detectConfigBasedComponents(sourceFile, nodes, nodeMap, edges, projectPath, project, gitHash, externalNodeMap, usedIds, idCounters);
883
894
  totalConfigEdges += configEdges;
884
895
  }
885
896
  if (totalConfigEdges > 0) {
@@ -933,8 +944,25 @@ async function analyzeProject(projectPath, projectId, onLog) {
933
944
  edges
934
945
  };
935
946
  log(" Checking for changed files vs remote...");
936
- const changedFiles = getChangedFilesVsRemote(projectPath);
937
- log(` Found ${changedFiles.length} changed files`);
947
+ const allChangedFiles = getChangedFilesVsRemote(projectPath);
948
+ log(` Found ${allChangedFiles.length} changed files`);
949
+ const changedFiles = allChangedFiles.filter((filePath) => {
950
+ return !filePath.includes("node_modules") && !filePath.includes(".test.") && !filePath.includes(".spec.") && (filePath.endsWith(".ts") || filePath.endsWith(".tsx") || filePath.endsWith(".js") || filePath.endsWith(".jsx"));
951
+ });
952
+ log(` Filtered to ${changedFiles.length} analyzed source files`);
953
+ const changedFilesMetadata = [];
954
+ for (const filePath of changedFiles) {
955
+ try {
956
+ const stats = fs.statSync(filePath);
957
+ changedFilesMetadata.push({
958
+ filePath,
959
+ lastModified: stats.mtimeMs
960
+ // Unix timestamp in milliseconds
961
+ });
962
+ } catch (error) {
963
+ log(` Warning: Could not get stats for ${filePath}`);
964
+ }
965
+ }
938
966
  const result = {
939
967
  project: projectMetadata,
940
968
  branches: [branchMetadata],
@@ -945,6 +973,9 @@ async function analyzeProject(projectPath, projectId, onLog) {
945
973
  logs,
946
974
  changedFilesVsRemote: changedFiles.length > 0 ? {
947
975
  [branchId]: changedFiles
976
+ } : void 0,
977
+ changedFilesMetadata: changedFilesMetadata.length > 0 ? {
978
+ [branchId]: changedFilesMetadata
948
979
  } : void 0
949
980
  };
950
981
  return result;
@@ -1893,6 +1924,8 @@ function getEdgeChanges(oldEdge, newEdge) {
1893
1924
 
1894
1925
  // src/vite-plugin.ts
1895
1926
  import chalk2 from "chalk";
1927
+ import * as fs3 from "fs";
1928
+ import * as path5 from "path";
1896
1929
  function rayburstPlugin(options = {}) {
1897
1930
  const {
1898
1931
  enabled = process.env.CI !== "true",
@@ -1902,6 +1935,41 @@ function rayburstPlugin(options = {}) {
1902
1935
  let config;
1903
1936
  let debounceTimer = null;
1904
1937
  let isAnalyzing = false;
1938
+ let lastGitState = null;
1939
+ let gitPollInterval = null;
1940
+ const checkGitState = (projectPath) => {
1941
+ try {
1942
+ const gitDir = path5.join(projectPath, ".git");
1943
+ if (!fs3.existsSync(gitDir)) {
1944
+ return false;
1945
+ }
1946
+ const headPath = path5.join(gitDir, "HEAD");
1947
+ if (!fs3.existsSync(headPath)) {
1948
+ return false;
1949
+ }
1950
+ const headContent = fs3.readFileSync(headPath, "utf-8").trim();
1951
+ let gitState = headContent;
1952
+ if (headContent.startsWith("ref: ")) {
1953
+ const refPath = headContent.substring(5);
1954
+ const fullRefPath = path5.join(gitDir, refPath);
1955
+ if (fs3.existsSync(fullRefPath)) {
1956
+ const refContent = fs3.readFileSync(fullRefPath, "utf-8").trim();
1957
+ gitState = `${headContent}:${refContent}`;
1958
+ }
1959
+ }
1960
+ if (lastGitState === null) {
1961
+ lastGitState = gitState;
1962
+ return false;
1963
+ }
1964
+ if (lastGitState !== gitState) {
1965
+ lastGitState = gitState;
1966
+ return true;
1967
+ }
1968
+ return false;
1969
+ } catch (error) {
1970
+ return false;
1971
+ }
1972
+ };
1905
1973
  const runAnalysis = async (triggerFile) => {
1906
1974
  if (isAnalyzing) return;
1907
1975
  isAnalyzing = true;
@@ -1980,6 +2048,24 @@ function rayburstPlugin(options = {}) {
1980
2048
  server.watcher.on("change", handleFileChange);
1981
2049
  server.watcher.on("add", handleFileChange);
1982
2050
  server.watcher.on("unlink", handleFileChange);
2051
+ const gitHeadPath = path5.join(config.root, ".git", "HEAD");
2052
+ if (fs3.existsSync(gitHeadPath)) {
2053
+ server.watcher.add(gitHeadPath);
2054
+ const handleGitChange = (changedPath) => {
2055
+ if (changedPath === gitHeadPath || changedPath.includes(".git/refs/heads/")) {
2056
+ console.log(chalk2.dim("[Rayburst] Git state changed, re-analyzing..."));
2057
+ runAnalysis("git-event");
2058
+ }
2059
+ };
2060
+ server.watcher.on("change", handleGitChange);
2061
+ checkGitState(config.root);
2062
+ gitPollInterval = setInterval(() => {
2063
+ if (checkGitState(config.root)) {
2064
+ console.log(chalk2.dim("[Rayburst] Git state changed (poll), re-analyzing..."));
2065
+ runAnalysis("git-poll");
2066
+ }
2067
+ }, 5e3);
2068
+ }
1983
2069
  return () => {
1984
2070
  server.watcher.off("change", handleFileChange);
1985
2071
  server.watcher.off("add", handleFileChange);
@@ -1987,6 +2073,9 @@ function rayburstPlugin(options = {}) {
1987
2073
  if (debounceTimer) {
1988
2074
  clearTimeout(debounceTimer);
1989
2075
  }
2076
+ if (gitPollInterval) {
2077
+ clearInterval(gitPollInterval);
2078
+ }
1990
2079
  };
1991
2080
  }
1992
2081
  };
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  readLocalMeta,
10
10
  writeLocalAnalysis,
11
11
  writeLocalMeta
12
- } from "./chunk-HXDPGVSZ.js";
12
+ } from "./chunk-X3T572UU.js";
13
13
  export {
14
14
  addGitignoreEntry,
15
15
  analyzeProject,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rayburstPlugin
3
- } from "./chunk-HXDPGVSZ.js";
3
+ } from "./chunk-X3T572UU.js";
4
4
  export {
5
5
  rayburstPlugin
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayburst/cli",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "Rayburst - Automatic code analysis for TypeScript/JavaScript projects via Vite plugin",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -47,7 +47,7 @@
47
47
  "zod": "^4.2.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@rayburst/types": "^0.1.7",
50
+ "@rayburst/types": "^0.1.8",
51
51
  "@types/node": "^25.0.2",
52
52
  "tsup": "^8.5.1",
53
53
  "typescript": "^5.9.3",