@@ -11,6 +11,8 @@ export default function (rootDir, config) {
1111 var agentLog = [ ]
1212 var meshErrors = [ ]
1313 var fs = null
14+ var fsWatchers = [ ]
15+ var fsLastChangeTime = Date . now ( )
1416 var apps = null
1517 var exited = false
1618
@@ -1066,6 +1068,49 @@ export default function (rootDir, config) {
10661068 } )
10671069 }
10681070
1071+ function watchFile ( prefix ) {
1072+ var resolve
1073+ var promise = new Promise ( cb => resolve = cb )
1074+ var isWatching = fsWatchers . length > 0
1075+ var entry = fsWatchers . find ( ( [ k ] ) => k === prefix )
1076+ if ( entry ) {
1077+ entry [ 1 ] . push ( resolve )
1078+ } else {
1079+ fsWatchers . push ( [ prefix , [ resolve ] ] )
1080+ }
1081+ if ( ! isWatching ) startWatchingFiles ( )
1082+ return promise
1083+ }
1084+
1085+ function startWatchingFiles ( ) {
1086+ new Timeout ( 5 ) . wait ( ) . then (
1087+ ( ) => discoverFiles ( fsLastChangeTime )
1088+ ) . then ( files => {
1089+ var paths = Object . keys ( files )
1090+ if ( paths . length > 0 ) {
1091+ fsLastChangeTime = Object . values ( files ) . map ( f => f . since ) . reduce (
1092+ ( max , t ) => ( t > max ? t : max ) , fsLastChangeTime
1093+ )
1094+ fsWatchers . forEach (
1095+ ( [ prefix , watchers ] ) => {
1096+ var changes = [ ]
1097+ paths . forEach ( path => {
1098+ if ( path . startsWith ( prefix ) ) {
1099+ changes . push ( path )
1100+ }
1101+ } )
1102+ if ( changes . length > 0 ) {
1103+ watchers . forEach ( resolve => resolve ( [ ...changes ] ) )
1104+ watchers . length = 0
1105+ }
1106+ }
1107+ )
1108+ fsWatchers = fsWatchers . filter ( ( [ _ , watchers ] ) => watchers . length > 0 )
1109+ }
1110+ if ( fsWatchers . length > 0 ) startWatchingFiles ( )
1111+ } )
1112+ }
1113+
10691114 //
10701115 // Mesh API exposed to apps
10711116 //
@@ -1086,32 +1131,22 @@ export default function (rootDir, config) {
10861131 }
10871132
10881133 function makeAppFilesystem ( provider , app ) {
1089- var prefixHome = `/home/${ username } /`
1090- var prefixHomeApp = prefixHome + `apps/${ provider } /${ app } /`
1091- var prefixApp = `/apps/${ provider } /${ app } /`
1092- var matchShared = new http . Match ( `/shared/{username}/apps/${ provider } /${ app } /*` )
1093- var matchShared = new http . Match ( '/shared/{username}' + prefixApp + '*' )
1134+ var pathApp = `/apps/${ provider } /${ app } `
1135+ var pathUser = `/users/${ username } /`
1136+ var pathShared = `/shared/`
1137+ var pathLocal = `/local/`
1138+ var pathAppUser = pathApp + pathUser
1139+ var pathAppShared = pathApp + pathShared
10941140
10951141 function pathToLocal ( path ) {
1096- if ( path . startsWith ( prefixHomeApp ) ) {
1097- return prefixHome + path . substring ( prefixHomeApp . length )
1098- }
1099- var params = matchShared ( path )
1100- if ( params ) {
1101- return `/shared/${ params . username } /${ params [ '*' ] } `
1142+ if ( path . startsWith ( pathAppUser ) || path . startsWith ( pathAppShared ) ) {
1143+ return path . substring ( pathApp . length )
11021144 }
11031145 }
11041146
11051147 function pathToGlobal ( path ) {
1106- if ( path . startsWith ( prefixHome ) ) {
1107- return prefixHomeApp + path . substring ( prefixHome . length )
1108- }
1109- if ( path . startsWith ( '/shared/' ) ) {
1110- path = path . substring ( 8 )
1111- var i = path . indexOf ( '/' )
1112- if ( i <= 0 || i + 1 == path . length ) return
1113- var username = path . substring ( 0 , i )
1114- return `/shared/${ username } ` + prefixApp + path . substring ( i + 1 )
1148+ if ( path . startsWith ( pathUser ) || path . startsWith ( pathShared ) ) {
1149+ return pathApp + path
11151150 }
11161151 }
11171152
@@ -1124,11 +1159,13 @@ export default function (rootDir, config) {
11241159 var list = [ ]
11251160 Object . keys ( files ) . forEach ( path => {
11261161 var localPath = pathToLocal ( path )
1127- if ( localPath && localPath . startsWith ( prefix ) ) list . push ( localPath )
1162+ if ( localPath && localPath . startsWith ( prefix ) ) {
1163+ list . push ( path )
1164+ }
11281165 } )
11291166 db . allFiles ( meshName , provider , app ) . forEach (
11301167 path => {
1131- var fullPath = '/local' + path
1168+ var fullPath = os . path . join ( pathLocal , path )
11321169 if ( fullPath . startsWith ( prefix ) ) list . push ( fullPath )
11331170 }
11341171 )
@@ -1139,9 +1176,9 @@ export default function (rootDir, config) {
11391176
11401177 function read ( pathname ) {
11411178 var path = os . path . normalize ( pathname )
1142- if ( path . startsWith ( '/local/' ) ) {
1179+ if ( path . startsWith ( pathLocal ) ) {
11431180 return Promise . resolve (
1144- db . getFile ( meshName , provider , app , path . substring ( 6 ) )
1181+ db . getFile ( meshName , provider , app , path . substring ( pathLocal . length ) )
11451182 )
11461183 } else {
11471184 var globalPath = pathToGlobal ( path )
@@ -1156,8 +1193,8 @@ export default function (rootDir, config) {
11561193 function write ( pathname , data ) {
11571194 if ( typeof data === 'string' ) data = new Data ( data )
11581195 var path = os . path . normalize ( pathname )
1159- if ( path . startsWith ( '/local/' ) ) {
1160- db . setFile ( meshName , provider , app , path . substring ( 6 ) , data )
1196+ if ( path . startsWith ( pathLocal ) ) {
1197+ db . setFile ( meshName , provider , app , path . substring ( pathLocal . length ) , data )
11611198 } else {
11621199 var globalPath = pathToGlobal ( path )
11631200 if ( globalPath ) {
@@ -1167,7 +1204,17 @@ export default function (rootDir, config) {
11671204 }
11681205 }
11691206
1170- return { dir, read, write }
1207+ function watch ( prefix ) {
1208+ if ( ! prefix . endsWith ( '/' ) ) prefix += '/'
1209+ var globalPath = pathToGlobal ( prefix )
1210+ if ( globalPath ) {
1211+ return watchFile ( globalPath ) . then (
1212+ paths => paths . map ( path => pathToLocal ( path ) ) . filter ( p => p )
1213+ )
1214+ }
1215+ }
1216+
1217+ return { dir, read, write, watch }
11711218 }
11721219
11731220 function remoteQueryLog ( ep ) {
0 commit comments