@@ -18,10 +18,11 @@ import { homedir } from 'node:os'
1818import { dirname , join } from 'node:path'
1919import { fileURLToPath } from 'node:url'
2020
21+ // This file lives at <root>/storage/framework/core/buddy/scripts/.
22+ const here = dirname ( fileURLToPath ( import . meta. url ) )
23+ const projectRoot = join ( here , '..' , '..' , '..' , '..' , '..' )
24+
2125function resolveRpxEntry ( ) : string | null {
22- // This file lives at <root>/storage/framework/core/buddy/scripts/.
23- const here = dirname ( fileURLToPath ( import . meta. url ) )
24- const projectRoot = join ( here , '..' , '..' , '..' , '..' , '..' )
2526 const candidates = [
2627 process . env . RPX_MODULE ,
2728 join ( projectRoot , 'node_modules/@stacksjs/rpx/dist/index.js' ) ,
@@ -31,9 +32,35 @@ function resolveRpxEntry(): string | null {
3132 return candidates . find ( p => existsSync ( p ) ) ?? null
3233}
3334
35+ /**
36+ * On-demand sites are ON by default for Stacks: the shared daemon lazily boots a
37+ * sibling app's dev server the first time you open its `<name>.localhost` URL, so
38+ * you never start them by hand. The default scan root is the folder this app
39+ * lives in (its siblings), derived from this file's location so it survives the
40+ * sudo re-exec that binds :443. Override the roots with `STACKS_RPX_SITE_ROOTS`
41+ * (comma-separated) or turn the whole thing off with `STACKS_RPX_ON_DEMAND=0`.
42+ *
43+ * Typed loosely so this compiles against any installed `@stacksjs/rpx` version
44+ * (the field is ignored by older builds that predate on-demand sites).
45+ */
46+ function resolveOnDemandSites ( ) : { enabled : boolean , roots : string [ ] } | undefined {
47+ if ( process . env . STACKS_RPX_ON_DEMAND === '0' )
48+ return undefined
49+ const rootsEnv = process . env . STACKS_RPX_SITE_ROOTS
50+ const roots = rootsEnv
51+ ? rootsEnv . split ( ',' ) . map ( r => r . trim ( ) ) . filter ( Boolean )
52+ : [ dirname ( projectRoot ) ] // the directory your app lives in → its siblings boot on demand
53+ return { enabled : true , roots }
54+ }
55+
3456const entry = resolveRpxEntry ( )
3557const rpx = entry ? await import ( entry ) : await import ( '@stacksjs/rpx' )
3658const { runDaemon } = rpx as typeof import ( '@stacksjs/rpx' )
3759
38- const handle = await runDaemon ( { verbose : process . env . RPX_VERBOSE === '1' } )
60+ const daemonOptions : Record < string , unknown > = { verbose : process . env . RPX_VERBOSE === '1' }
61+ const onDemandSites = resolveOnDemandSites ( )
62+ if ( onDemandSites )
63+ daemonOptions . onDemandSites = onDemandSites
64+
65+ const handle = await runDaemon ( daemonOptions as Parameters < typeof runDaemon > [ 0 ] )
3966await handle . done
0 commit comments