11import * as childProcess from 'child_process' ;
22import * as path from 'path' ;
33import { promises as fs } from 'fs' ;
4- import envPaths from 'env-paths' ;
54import * as puppeteer from 'puppeteer' ;
65// @ts -expect-error the bundle: syntax is from a plugin in the rollup config and TS does not know about it
76import startDisownedBrowserPath from 'bundle:./start-disowned-browser' ;
7+ import { fileURLToPath } from 'url' ;
88
9- const readConfig = async ( configPath : string ) => {
9+ const readCache = async ( cachePath : string ) => {
1010 try {
11- const config = await fs . readFile ( configPath , 'utf8' ) . catch ( ( ) => '' ) ;
12- const parsed = JSON . parse ( config ) ;
11+ const cache = await fs . readFile ( cachePath , 'utf8' ) . catch ( ( ) => '' ) ;
12+ const parsed = JSON . parse ( cache ) ;
1313 if ( typeof parsed === 'object' ) return parsed ;
1414 } catch { }
1515
1616 return { } ;
1717} ;
1818
19- const updateConfig = async (
20- configPath : string ,
19+ const updateCacheFile = async (
20+ cachePath : string ,
2121 browser : 'chromium' ,
2222 headless : boolean ,
2323 value : string | undefined ,
2424 previousValue : string | undefined ,
2525) => {
26- await fs . mkdir ( path . dirname ( configPath ) , { recursive : true } ) ;
27- const oldConfig = await readConfig ( configPath ) ;
26+ await fs . mkdir ( path . dirname ( cachePath ) , { recursive : true } ) ;
27+ const oldCache = await readCache ( cachePath ) ;
2828 const headlessStr = headless ? 'headless' : 'headed' ;
29- const browserObj = oldConfig [ browser ] || ( oldConfig [ browser ] = { } ) ;
29+ const browserObj = oldCache [ browser ] || ( oldCache [ browser ] = { } ) ;
3030 if (
3131 previousValue !== undefined &&
3232 previousValue !== browserObj [ headlessStr ]
@@ -35,17 +35,17 @@ const updateConfig = async (
3535 }
3636
3737 browserObj [ headlessStr ] = value ;
38- await fs . writeFile ( configPath , JSON . stringify ( oldConfig , null , 2 ) ) ;
38+ await fs . writeFile ( cachePath , JSON . stringify ( oldCache , null , 2 ) ) ;
3939} ;
4040
4141const connectToCachedBrowser = async (
42- configPath : string ,
42+ cachePath : string ,
4343 browser : 'chromium' ,
4444 headless : boolean ,
4545 timeLimit = 5000 ,
4646) => {
47- const config = await readConfig ( configPath ) ;
48- const cachedWSEndpoint = config [ browser ] ?. [ headless ? 'headless' : 'headed' ] ;
47+ const cache = await readCache ( cachePath ) ;
48+ const cachedWSEndpoint = cache [ browser ] ?. [ headless ? 'headless' : 'headed' ] ;
4949 // In case another process is currently starting a browser, wait for that process
5050 // rather than starting a whole new one
5151 if ( cachedWSEndpoint === 'starting' && timeLimit > 0 ) {
@@ -56,7 +56,7 @@ const connectToCachedBrowser = async (
5656 setTimeout (
5757 ( ) =>
5858 connectToCachedBrowser (
59- configPath ,
59+ cachePath ,
6060 browser ,
6161 headless ,
6262 timeLimit - 50 ,
@@ -87,28 +87,35 @@ export const connectToBrowser = async (
8787) => {
8888 // I acknowledge that this code is gross and should be refactored
8989 // Constraints:
90- // - If there is no browser in the config , multiple concurrent processes should only start 1 new browser
91- // - If there is a killed browser in the config , multiple concurrent processes should only start 1 new browser
92- // - If there "starting" in the config but nothing is really starting, multiple concurrent processes should only start 1 new browser
90+ // - If there is no browser in the cache , multiple concurrent processes should only start 1 new browser
91+ // - If there is a killed browser in the cache , multiple concurrent processes should only start 1 new browser
92+ // - If there "starting" in the cache but nothing is really starting, multiple concurrent processes should only start 1 new browser
9393 // TODO: Idea: use a state machine!!!
94- const dataPath = envPaths ( 'pleasantest' ) . data ;
95- const configPath = path . join ( dataPath , 'config.json' ) ;
94+ // This is the folder that Pleasantest is installed in (e.g. <something>/node_modules/pleasantest)
95+ const installFolder = path . dirname (
96+ path . dirname ( path . dirname ( fileURLToPath ( import . meta. url ) ) ) ,
97+ ) ;
98+ // Something like <something>/node_modules/pleasantest/.browser-cache.json
99+ const cachePath = path . join ( installFolder , '.browser-cache.json' ) ;
96100 const cachedBrowser = await connectToCachedBrowser (
97- configPath ,
101+ cachePath ,
98102 browser ,
99103 headless ,
100104 ) ;
101- if ( isBrowser ( cachedBrowser ) ) return cachedBrowser ;
102- let valueWrittenInMeantime = await updateConfig (
103- configPath ,
105+ if ( isBrowser ( cachedBrowser ) ) {
106+ return cachedBrowser ;
107+ }
108+
109+ let valueWrittenInMeantime = await updateCacheFile (
110+ cachePath ,
104111 browser ,
105112 headless ,
106113 'starting' ,
107114 cachedBrowser . previousValue ,
108115 ) ;
109116 if ( valueWrittenInMeantime ) {
110117 const connectedBrowser = await connectToCachedBrowser (
111- configPath ,
118+ cachePath ,
112119 browser ,
113120 headless ,
114121 ) ;
@@ -131,17 +138,17 @@ export const connectToBrowser = async (
131138 } ) ;
132139 } ) . catch ( async ( error ) => {
133140 subprocess . kill ( ) ;
134- valueWrittenInMeantime = await updateConfig (
135- configPath ,
141+ valueWrittenInMeantime = await updateCacheFile (
142+ cachePath ,
136143 browser ,
137144 headless ,
138145 '' ,
139146 'starting' ,
140147 ) ;
141148 throw error ;
142149 } ) ;
143- valueWrittenInMeantime = await updateConfig (
144- configPath ,
150+ valueWrittenInMeantime = await updateCacheFile (
151+ cachePath ,
145152 browser ,
146153 headless ,
147154 wsEndpoint ,
0 commit comments