1- import type { CommandsSchema , Files } from '@tutorialkit/types' ;
1+ import type { CommandsSchema , Files , FileSystemSchema } from '@tutorialkit/types' ;
22import type { IFSWatcher , WebContainer , WebContainerProcess } from '@webcontainer/api' ;
33import { newTask , type Task , type TaskCancelled } from '../tasks.js' ;
44import { MultiCounter } from '../utils/multi-counter.js' ;
@@ -66,6 +66,7 @@ export class TutorialRunner {
6666 private _ignoreFileEvents = new MultiCounter ( ) ;
6767 private _watcher : IFSWatcher | undefined ;
6868 private _watchContentFromWebContainer = false ;
69+ private _watcherAddNewFilesInPaths : string [ ] | undefined = undefined ;
6970 private _readyToWatch = false ;
7071
7172 private _packageJsonDirty = false ;
@@ -82,8 +83,9 @@ export class TutorialRunner {
8283 private _stepController : StepsController ,
8384 ) { }
8485
85- setWatchFromWebContainer ( value : boolean ) {
86- this . _watchContentFromWebContainer = value ;
86+ setWatchFromWebContainer ( fileSystemConfig ?: FileSystemSchema ) {
87+ this . _watchContentFromWebContainer = fileSystemConfig ?. watch || false ;
88+ this . _watcherAddNewFilesInPaths = fileSystemConfig ?. addNewFilesInPaths ;
8789
8890 if ( this . _readyToWatch && this . _watchContentFromWebContainer ) {
8991 this . _webcontainer . then ( ( webcontainer ) => this . _setupWatcher ( webcontainer ) ) ;
@@ -654,19 +656,36 @@ export class TutorialRunner {
654656 return ;
655657 }
656658
657- // for now we only care about 'change' event
658- if ( eventType !== 'change' ) {
659- return ;
660- }
659+ if ( eventType === 'change' ) {
660+ // we ignore all paths that aren't exposed in the `_editorStore`
661+ const file = this . _editorStore . documents . get ( ) [ filePath ] ;
661662
662- // we ignore all paths that aren't exposed in the `_editorStore`
663- const file = this . _editorStore . documents . get ( ) [ filePath ] ;
663+ if ( ! file ) {
664+ return ;
665+ }
664666
665- if ( ! file ) {
666- return ;
667- }
667+ scheduleReadFor ( filePath , typeof file . value === 'string' ? 'utf-8' : null ) ;
668+ } else if ( eventType === 'rename' && this . _watcherAddNewFilesInPaths ) {
669+ if ( ! this . _watcherAddNewFilesInPaths . some ( ( path ) => filePath . startsWith ( '/' + path ) ) ) {
670+ return ;
671+ }
668672
669- scheduleReadFor ( filePath , typeof file . value === 'string' ? 'utf-8' : null ) ;
673+ const segments = filePath . split ( '/' ) ;
674+ segments . forEach ( ( _ , index ) => {
675+ if ( index == segments . length - 1 ) {
676+ return ;
677+ }
678+
679+ const folderPath = segments . slice ( 0 , index + 1 ) . join ( '/' ) ;
680+
681+ if ( ! this . _editorStore . documents . get ( ) [ folderPath ] ) {
682+ this . _editorStore . addFileOrFolder ( { path : folderPath , type : 'folder' } ) ;
683+ }
684+ } ) ;
685+ this . _editorStore . addFileOrFolder ( { path : filePath , type : 'file' } ) ;
686+ this . _updateCurrentFiles ( { [ filePath ] : 'test' } ) ;
687+ scheduleReadFor ( filePath , 'utf-8' ) ;
688+ }
670689 } ) ;
671690 }
672691
0 commit comments