@@ -11,6 +11,7 @@ import micromatch from 'micromatch'
1111import type { WebSocket } from 'ws'
1212import { WebSocketServer } from 'ws'
1313import { listen , type Listener } from 'listhen'
14+ import { withTrailingSlash } from 'ufo'
1415import type { ModuleOptions , ResolvedCollection } from '../types'
1516import type { Manifest } from '../types/manifest'
1617import { generateCollectionInsert } from './collection'
@@ -20,23 +21,8 @@ import { parseSourceBase } from './source'
2021
2122export const logger : ConsolaInstance = useLogger ( '@nuxt/content' )
2223
23- export async function watchContents ( nuxt : Nuxt , options : ModuleOptions , manifest : Manifest ) {
24- const cwd = join ( nuxt . options . rootDir , 'content' )
24+ export async function startSocketServer ( nuxt : Nuxt , options : ModuleOptions , manifest : Manifest ) {
2525 const db = localDatabase ( options . _localDatabase ! . filename )
26- const collections = manifest . collections
27-
28- const sourceMap = collections . flatMap ( ( c ) => {
29- return c . source
30- ? c . source . filter ( s => ! s . repository ) . map ( s => ( { collection : c , source : s } ) )
31- : [ ]
32- } )
33- // const localCollections = collections.filter(c => c.source && !c.source.repository)
34-
35- const watcher = chokidar . watch ( '.' , { ignoreInitial : true , cwd } )
36-
37- watcher . on ( 'add' , onChange )
38- watcher . on ( 'change' , onChange )
39- watcher . on ( 'unlink' , onRemove )
4026
4127 let websocket : ReturnType < typeof createWebSocket >
4228 let listener : Listener
@@ -88,17 +74,47 @@ export async function watchContents(nuxt: Nuxt, options: ModuleOptions, manifest
8874 } )
8975 }
9076
77+ nuxt . hook ( 'close' , async ( ) => {
78+ // Close WebSocket server
79+ await websocket . close ( )
80+ await listener . server . close ( )
81+ } )
82+
83+ return {
84+ broadcast,
85+ }
86+ }
87+
88+ export async function watchContents ( nuxt : Nuxt , options : ModuleOptions , manifest : Manifest , socket : Awaited < ReturnType < typeof startSocketServer > > ) {
89+ const db = localDatabase ( options . _localDatabase ! . filename )
90+ const collections = manifest . collections
91+
92+ const sourceMap = collections . flatMap ( ( c ) => {
93+ return c . source
94+ ? c . source . filter ( s => ! s . repository ) . map ( s => ( { collection : c , source : s , cwd : withTrailingSlash ( s . cwd ) } ) )
95+ : [ ]
96+ } )
97+ const dirsToWatch = Array . from ( new Set ( sourceMap . map ( ( { source } ) => source . cwd ) ) )
98+
99+ const watcher = chokidar . watch ( dirsToWatch , { ignoreInitial : true } )
100+
101+ watcher . on ( 'add' , onChange )
102+ watcher . on ( 'change' , onChange )
103+ watcher . on ( 'unlink' , onRemove )
104+
91105 async function onChange ( path : string ) {
92- const match = sourceMap . find ( ( { source } ) => micromatch . isMatch ( path , source ! . include , { ignore : source ! . exclude || [ ] , dot : true } ) )
106+ const match = sourceMap . find ( ( { source, cwd } ) => path . startsWith ( cwd ) && micromatch . isMatch ( path . substring ( cwd . length ) , source ! . include , { ignore : source ! . exclude || [ ] , dot : true } ) )
93107 if ( match ) {
94- const { collection, source } = match
108+ const { collection, source, cwd } = match
109+ // Remove the cwd prefix
110+ path = path . substring ( cwd . length )
95111 logger . info ( `File \`${ path } \` changed on \`${ collection . name } \` collection` )
96112 const { fixed } = parseSourceBase ( source )
97113
98114 const filePath = path . substring ( fixed . length )
99115 const keyInCollection = join ( collection . name , source ?. prefix || '' , filePath )
100116
101- const content = await readFile ( join ( nuxt . options . rootDir , 'content' , path ) , 'utf8' )
117+ const content = await readFile ( join ( cwd , path ) , 'utf8' )
102118 const checksum = getContentChecksum ( content )
103119 const localCache = db . fetchDevelopmentCacheForKey ( keyInCollection )
104120
@@ -113,14 +129,16 @@ export async function watchContents(nuxt: Nuxt, options: ModuleOptions, manifest
113129 db . insertDevelopmentCache ( keyInCollection , checksum , JSON . stringify ( parsedContent ) )
114130
115131 const insertQuery = generateCollectionInsert ( collection , parsedContent )
116- await broadcast ( collection , keyInCollection , insertQuery )
132+ await socket . broadcast ( collection , keyInCollection , insertQuery )
117133 }
118134 }
119135
120136 async function onRemove ( path : string ) {
121- const match = sourceMap . find ( ( { source } ) => micromatch . isMatch ( path , source ! . include , { ignore : source ! . exclude || [ ] , dot : true } ) )
137+ const match = sourceMap . find ( ( { source, cwd } ) => path . startsWith ( cwd ) && micromatch . isMatch ( path . substring ( cwd . length ) , source ! . include , { ignore : source ! . exclude || [ ] , dot : true } ) )
122138 if ( match ) {
123- const { collection, source } = match
139+ const { collection, source, cwd } = match
140+ // Remove the cwd prefix
141+ path = path . substring ( cwd . length )
124142 logger . info ( `File \`${ path } \` removed from \`${ collection . name } \` collection` )
125143 const { fixed } = parseSourceBase ( source )
126144
@@ -129,16 +147,13 @@ export async function watchContents(nuxt: Nuxt, options: ModuleOptions, manifest
129147
130148 await db . deleteDevelopmentCache ( keyInCollection )
131149
132- await broadcast ( collection , keyInCollection )
150+ await socket . broadcast ( collection , keyInCollection )
133151 }
134152 }
135153
136154 nuxt . hook ( 'close' , async ( ) => {
137155 watcher . close ( )
138156 db . close ( )
139- // Close WebSocket server
140- await websocket . close ( )
141- await listener . server . close ( )
142157 } )
143158}
144159
0 commit comments