@@ -61,6 +61,7 @@ var cami = (() => {
61
61
// src/cami.js
62
62
var cami_exports = { } ;
63
63
__export ( cami_exports , {
64
+ DependencyTracker : ( ) => DependencyTracker ,
64
65
Observable : ( ) => Observable ,
65
66
ObservableState : ( ) => ObservableState ,
66
67
ObservableStore : ( ) => ObservableStore ,
@@ -2012,61 +2013,67 @@ var cami = (() => {
2012
2013
static detectCycles ( ) {
2013
2014
const visited = /* @__PURE__ */ new Set ( ) ;
2014
2015
const recursionStack = /* @__PURE__ */ new Set ( ) ;
2015
- const cyclePath = [ ] ;
2016
2016
function dfs ( node ) {
2017
2017
visited . add ( node ) ;
2018
2018
recursionStack . add ( node ) ;
2019
- cyclePath . push ( node ) ;
2020
2019
const neighbors = _DependencyTracker . dependencyGraph . get ( node ) || /* @__PURE__ */ new Set ( ) ;
2021
2020
for ( const neighbor of neighbors ) {
2022
2021
if ( ! visited . has ( neighbor ) ) {
2023
2022
if ( dfs ( neighbor ) )
2024
- return true ;
2023
+ return [ node , neighbor ] ;
2025
2024
} 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 ] ;
2029
2026
}
2030
2027
}
2031
2028
recursionStack . delete ( node ) ;
2032
- cyclePath . pop ( ) ;
2033
- return false ;
2029
+ return null ;
2034
2030
}
2035
2031
for ( const node of _DependencyTracker . dependencyGraph . keys ( ) ) {
2036
2032
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 ] } ` ) ;
2046
2036
}
2047
2037
}
2048
2038
}
2049
- return false ;
2050
2039
}
2051
2040
static clearGraph ( ) {
2052
2041
_DependencyTracker . dependencyGraph . clear ( ) ;
2053
2042
}
2054
2043
static topologicalSort ( ) {
2055
2044
const visited = /* @__PURE__ */ new Set ( ) ;
2056
2045
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 = [ ] ;
2067
2048
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
+ }
2070
2077
}
2071
2078
}
2072
2079
return stack . reverse ( ) ;
0 commit comments