@@ -61,6 +61,7 @@ var cami = (() => {
6161 // src/cami.js
6262 var cami_exports = { } ;
6363 __export ( cami_exports , {
64+ DependencyTracker : ( ) => DependencyTracker ,
6465 Observable : ( ) => Observable ,
6566 ObservableState : ( ) => ObservableState ,
6667 ObservableStore : ( ) => ObservableStore ,
@@ -2012,61 +2013,67 @@ var cami = (() => {
20122013 static detectCycles ( ) {
20132014 const visited = /* @__PURE__ */ new Set ( ) ;
20142015 const recursionStack = /* @__PURE__ */ new Set ( ) ;
2015- const cyclePath = [ ] ;
20162016 function dfs ( node ) {
20172017 visited . add ( node ) ;
20182018 recursionStack . add ( node ) ;
2019- cyclePath . push ( node ) ;
20202019 const neighbors = _DependencyTracker . dependencyGraph . get ( node ) || /* @__PURE__ */ new Set ( ) ;
20212020 for ( const neighbor of neighbors ) {
20222021 if ( ! visited . has ( neighbor ) ) {
20232022 if ( dfs ( neighbor ) )
2024- return true ;
2023+ return [ node , neighbor ] ;
20252024 } else if ( recursionStack . has ( neighbor ) ) {
2026- const cycleStart = cyclePath . indexOf ( neighbor ) ;
2027- const cycle = cyclePath . slice ( cycleStart ) ;
2028- console . warn ( `Cyclic dependency detected: ${ cycle . map ( ( n ) => n . __name || "unnamed" ) . join ( " -> " ) } ` ) ;
2025+ return [ node , neighbor ] ;
20292026 }
20302027 }
20312028 recursionStack . delete ( node ) ;
2032- cyclePath . pop ( ) ;
2033- return false ;
2029+ return null ;
20342030 }
20352031 for ( const node of _DependencyTracker . dependencyGraph . keys ( ) ) {
20362032 if ( ! visited . has ( node ) ) {
2037- try {
2038- if ( dfs ( node ) )
2039- return true ;
2040- } catch ( error ) {
2041- if ( error . message . startsWith ( "Cyclic dependency detected:" ) ) {
2042- console . warn ( error . message ) ;
2043- } else {
2044- throw error ;
2045- }
2033+ const cycle = dfs ( node ) ;
2034+ if ( cycle ) {
2035+ throw new Error ( `Dependency cycle detected: ${ cycle [ 0 ] } <-> ${ cycle [ 1 ] } ` ) ;
20462036 }
20472037 }
20482038 }
2049- return false ;
20502039 }
20512040 static clearGraph ( ) {
20522041 _DependencyTracker . dependencyGraph . clear ( ) ;
20532042 }
20542043 static topologicalSort ( ) {
20552044 const visited = /* @__PURE__ */ new Set ( ) ;
20562045 const stack = [ ] ;
2057- function dfs ( node ) {
2058- visited . add ( node ) ;
2059- const neighbors = _DependencyTracker . dependencyGraph . get ( node ) || /* @__PURE__ */ new Set ( ) ;
2060- for ( const neighbor of neighbors ) {
2061- if ( ! visited . has ( neighbor ) ) {
2062- dfs ( neighbor ) ;
2063- }
2064- }
2065- stack . push ( node ) ;
2066- }
2046+ const tempMark = /* @__PURE__ */ new Set ( ) ;
2047+ const nodeStack = [ ] ;
20672048 for ( const node of _DependencyTracker . dependencyGraph . keys ( ) ) {
2068- if ( ! visited . has ( node ) ) {
2069- dfs ( node ) ;
2049+ if ( visited . has ( node ) )
2050+ continue ;
2051+ nodeStack . push ( node ) ;
2052+ while ( nodeStack . length > 0 ) {
2053+ const current2 = nodeStack [ nodeStack . length - 1 ] ;
2054+ if ( tempMark . has ( current2 ) ) {
2055+ throw new Error ( "Graph has a cycle" ) ;
2056+ }
2057+ if ( ! visited . has ( current2 ) ) {
2058+ tempMark . add ( current2 ) ;
2059+ const neighbors = _DependencyTracker . dependencyGraph . get ( current2 ) || /* @__PURE__ */ new Set ( ) ;
2060+ let allVisited = true ;
2061+ for ( const neighbor of neighbors ) {
2062+ if ( ! visited . has ( neighbor ) ) {
2063+ nodeStack . push ( neighbor ) ;
2064+ allVisited = false ;
2065+ break ;
2066+ }
2067+ }
2068+ if ( allVisited ) {
2069+ visited . add ( current2 ) ;
2070+ tempMark . delete ( current2 ) ;
2071+ stack . push ( current2 ) ;
2072+ nodeStack . pop ( ) ;
2073+ }
2074+ } else {
2075+ nodeStack . pop ( ) ;
2076+ }
20702077 }
20712078 }
20722079 return stack . reverse ( ) ;
0 commit comments