7
7
*/
8
8
9
9
import { FSWatcher } from 'chokidar' ;
10
- import { normalize } from 'node:path' ;
11
10
12
11
export class ChangedFiles {
13
12
readonly added = new Set < string > ( ) ;
@@ -52,65 +51,19 @@ export function createWatcher(options?: {
52
51
let currentChanges : ChangedFiles | undefined ;
53
52
let nextWaitTimeout : NodeJS . Timeout | undefined ;
54
53
55
- /**
56
- * We group the current events in a map as on Windows with certain IDE a file contents change can trigger multiple events.
57
- *
58
- * Example:
59
- * rename | 'C:/../src/app/app.component.css'
60
- * rename | 'C:/../src/app/app.component.css'
61
- * change | 'C:/../src/app/app.component.css'
62
- *
63
- */
64
- let currentEvents : Map < /* Event name */ string , /* File path */ string > | undefined ;
65
-
66
- /**
67
- * Using `watcher.on('all')` does not capture some of events fired when using Visual studio and this does not happen all the time,
68
- * but only after a file has been changed 3 or more times.
69
- *
70
- * Also, some IDEs such as Visual Studio (not VS Code) will fire a rename event instead of unlink when a file is renamed or changed.
71
- *
72
- * Example:
73
- * ```
74
- * watcher.on('raw')
75
- * Change 1
76
- * rename | 'C:/../src/app/app.component.css'
77
- * rename | 'C:/../src/app/app.component.css'
78
- * change | 'C:/../src/app/app.component.css'
79
- *
80
- * Change 2
81
- * rename | 'C:/../src/app/app.component.css'
82
- * rename | 'C:/../src/app/app.component.css'
83
- * change | 'C:/../src/app/app.component.css'
84
- *
85
- * Change 3
86
- * rename | 'C:/../src/app/app.component.css'
87
- * rename | 'C:/../src/app/app.component.css'
88
- * change | 'C:/../src/app/app.component.css'
89
- *
90
- * watcher.on('all')
91
- * Change 1
92
- * change | 'C:\\..\\src\\app\\app.component.css'
93
- *
94
- * Change 2
95
- * unlink | 'C:\\..\\src\\app\\app.component.css'
96
- *
97
- * Change 3
98
- * ... (Nothing)
99
- * ```
100
- */
101
- watcher . on ( 'raw' , ( event , path , { watchedPath } ) => {
54
+ watcher . on ( 'all' , ( event , path ) => {
102
55
switch ( event ) {
103
56
case 'add' :
57
+ currentChanges ??= new ChangedFiles ( ) ;
58
+ currentChanges . added . add ( path ) ;
59
+ break ;
104
60
case 'change' :
105
- // When using Visual Studio the rename event is fired before a change event when the contents of the file changed
106
- // or instead of `unlink` when the file has been renamed.
61
+ currentChanges ??= new ChangedFiles ( ) ;
62
+ currentChanges . modified . add ( path ) ;
63
+ break ;
107
64
case 'unlink' :
108
- case 'rename' :
109
- // When polling is enabled `watchedPath` can be undefined.
110
- // `path` is always normalized unlike `watchedPath`.
111
- const changedPath = watchedPath ? normalize ( watchedPath ) : path ;
112
- currentEvents ??= new Map ( ) ;
113
- currentEvents . set ( changedPath , event ) ;
65
+ currentChanges ??= new ChangedFiles ( ) ;
66
+ currentChanges . removed . add ( path ) ;
114
67
break ;
115
68
default :
116
69
return ;
@@ -121,27 +74,10 @@ export function createWatcher(options?: {
121
74
nextWaitTimeout = setTimeout ( ( ) => {
122
75
nextWaitTimeout = undefined ;
123
76
const next = nextQueue . shift ( ) ;
124
- if ( next && currentEvents ) {
125
- const events = currentEvents ;
126
- currentEvents = undefined ;
127
-
128
- const currentChanges = new ChangedFiles ( ) ;
129
- for ( const [ path , event ] of events ) {
130
- switch ( event ) {
131
- case 'add' :
132
- currentChanges . added . add ( path ) ;
133
- break ;
134
- case 'change' :
135
- currentChanges . modified . add ( path ) ;
136
- break ;
137
- case 'unlink' :
138
- case 'rename' :
139
- currentChanges . removed . add ( path ) ;
140
- break ;
141
- }
142
- }
143
-
144
- next ( currentChanges ) ;
77
+ if ( next ) {
78
+ const value = currentChanges ;
79
+ currentChanges = undefined ;
80
+ next ( value ) ;
145
81
}
146
82
} , 250 ) ;
147
83
nextWaitTimeout ?. unref ( ) ;
0 commit comments