11import type { CommandsSchema , Files } from '@tutorialkit/types' ;
22import type { IFSWatcher , WebContainer , WebContainerProcess } from '@webcontainer/api' ;
3+ import picomatch from 'picomatch' ;
34import { newTask , type Task , type TaskCancelled } from '../tasks.js' ;
45import { MultiCounter } from '../utils/multi-counter.js' ;
56import { clearTerminal , escapeCodes , type ITerminal } from '../utils/terminal.js' ;
@@ -65,7 +66,7 @@ export class TutorialRunner {
6566
6667 private _ignoreFileEvents = new MultiCounter ( ) ;
6768 private _watcher : IFSWatcher | undefined ;
68- private _watchContentFromWebContainer = false ;
69+ private _watchContentFromWebContainer : string [ ] | boolean = false ;
6970 private _readyToWatch = false ;
7071
7172 private _packageJsonDirty = false ;
@@ -82,7 +83,7 @@ export class TutorialRunner {
8283 private _stepController : StepsController ,
8384 ) { }
8485
85- setWatchFromWebContainer ( value : boolean ) {
86+ setWatchFromWebContainer ( value : boolean | string [ ] ) {
8687 this . _watchContentFromWebContainer = value ;
8788
8889 if ( this . _readyToWatch && this . _watchContentFromWebContainer ) {
@@ -654,19 +655,39 @@ export class TutorialRunner {
654655 return ;
655656 }
656657
657- // for now we only care about 'change' event
658- if ( eventType !== 'change' ) {
658+ if (
659+ Array . isArray ( this . _watchContentFromWebContainer ) &&
660+ ! this . _watchContentFromWebContainer . some ( ( pattern ) => picomatch . isMatch ( filePath , pattern ) )
661+ ) {
659662 return ;
660663 }
661664
662- // we ignore all paths that aren't exposed in the `_editorStore`
663- const file = this . _editorStore . documents . get ( ) [ filePath ] ;
665+ if ( eventType === 'change' ) {
666+ // we ignore all paths that aren't exposed in the `_editorStore`
667+ const file = this . _editorStore . documents . get ( ) [ filePath ] ;
664668
665- if ( ! file ) {
666- return ;
667- }
669+ if ( ! file ) {
670+ return ;
671+ }
672+
673+ scheduleReadFor ( filePath , typeof file . value === 'string' ? 'utf-8' : null ) ;
674+ } else if ( eventType === 'rename' && Array . isArray ( this . _watchContentFromWebContainer ) ) {
675+ const segments = filePath . split ( '/' ) ;
676+ segments . forEach ( ( _ , index ) => {
677+ if ( index == segments . length - 1 ) {
678+ return ;
679+ }
668680
669- scheduleReadFor ( filePath , typeof file . value === 'string' ? 'utf-8' : null ) ;
681+ const folderPath = segments . slice ( 0 , index + 1 ) . join ( '/' ) ;
682+
683+ if ( ! this . _editorStore . documents . get ( ) [ folderPath ] ) {
684+ this . _editorStore . addFileOrFolder ( { path : folderPath , type : 'folder' } ) ;
685+ }
686+ } ) ;
687+ this . _editorStore . addFileOrFolder ( { path : filePath , type : 'file' } ) ;
688+ this . _updateCurrentFiles ( { [ filePath ] : 'test' } ) ;
689+ scheduleReadFor ( filePath , 'utf-8' ) ;
690+ }
670691 } ) ;
671692 }
672693
0 commit comments