77 * @see https://github.com/babel/babel-loader/issues/34
88 * @see https://github.com/babel/babel-loader/pull/41
99 */
10- const fs = require ( "fs" ) ;
1110const os = require ( "os" ) ;
12- const path = require ( "path" ) ;
13- const zlib = require ( "zlib" ) ;
1411const crypto = require ( "crypto" ) ;
1512const findCacheDir = require ( "find-cache-dir" ) ;
16- const { promisify } = require ( "util " ) ;
13+ const { open } = require ( "lmdb " ) ;
1714
1815const transform = require ( "./transform" ) ;
1916// Lazily instantiated when needed
2017let defaultCacheDirectory = null ;
21-
22- const readFile = promisify ( fs . readFile ) ;
23- const writeFile = promisify ( fs . writeFile ) ;
24- const gunzip = promisify ( zlib . gunzip ) ;
25- const gzip = promisify ( zlib . gzip ) ;
26- const makeDir = require ( "make-dir" ) ;
18+ let cacheDB = null ;
2719
2820/**
29- * Read the contents from the compressed file.
30- *
31- * @async
32- * @params {String} filename
33- * @params {Boolean} compress
21+ * Initialize cache
3422 */
35- const read = async function ( filename , compress ) {
36- const data = await readFile ( filename + ( compress ? ".gz" : "" ) ) ;
37- const content = compress ? await gunzip ( data ) : data ;
3823
39- return JSON . parse ( content . toString ( ) ) ;
40- } ;
24+ async function initCacheDB ( cacheDir , cacheCompression ) {
25+ if ( cacheDB ) return cacheDB ;
26+ const fallback = cacheDir !== os . tmpdir ( ) ;
4127
42- /**
43- * Write contents into a compressed file.
44- *
45- * @async
46- * @params {String} filename
47- * @params {Boolean} compress
48- * @params {String} result
49- */
50- const write = async function ( filename , compress , result ) {
51- const content = JSON . stringify ( result ) ;
28+ try {
29+ cacheDB = open ( {
30+ path : cacheDir ,
31+ compression : cacheCompression ,
32+ sharedStructuresKey : Symbol . for ( `structures` ) ,
33+ } ) ;
34+ } catch ( err ) {
35+ if ( fallback ) {
36+ cacheDB = initCacheDB ( os . tmpdir ( ) , cacheCompression ) ;
37+ }
5238
53- const data = compress ? await gzip ( content ) : content ;
54- return await writeFile ( filename + ( compress ? ".gz" : "" ) , data ) ;
55- } ;
39+ throw err ;
40+ }
41+ }
5642
5743/**
58- * Build the filename for the cached file
44+ * Build the cache key for the cached file
5945 *
6046 * @params {String} source File source code
6147 * @params {Object} options Options used
6248 *
6349 * @return {String }
6450 */
65- const filename = function ( source , identifier , options ) {
51+ const fileCacheKey = function ( source , identifier , options ) {
6652 // md4 hashing is not supported starting with node v17.0.0
6753 const majorNodeVersion = parseInt ( process . versions . node . split ( "." ) [ 0 ] , 10 ) ;
6854 let hashType = "md4" ;
@@ -76,7 +62,7 @@ const filename = function (source, identifier, options) {
7662
7763 hash . update ( contents ) ;
7864
79- return hash . digest ( "hex" ) + ".json" ;
65+ return hash . digest ( "hex" ) ;
8066} ;
8167
8268/**
@@ -85,51 +71,21 @@ const filename = function (source, identifier, options) {
8571 * @params {String} directory
8672 * @params {Object} params
8773 */
88- const handleCache = async function ( directory , params ) {
89- const {
90- source,
91- options = { } ,
92- cacheIdentifier,
93- cacheDirectory,
94- cacheCompression,
95- } = params ;
74+ const handleCache = async function ( params ) {
75+ const { source, options = { } , cacheIdentifier } = params ;
9676
97- const file = path . join ( directory , filename ( source , cacheIdentifier , options ) ) ;
98-
99- try {
100- // No errors mean that the file was previously cached
101- // we just need to return it
102- return await read ( file , cacheCompression ) ;
103- } catch ( err ) { }
77+ const cacheKey = fileCacheKey ( source , cacheIdentifier , options ) ;
10478
105- const fallback =
106- typeof cacheDirectory !== "string" && directory !== os . tmpdir ( ) ;
107-
108- // Make sure the directory exists.
109- try {
110- await makeDir ( directory ) ;
111- } catch ( err ) {
112- if ( fallback ) {
113- return handleCache ( os . tmpdir ( ) , params ) ;
114- }
115-
116- throw err ;
79+ // Fetch cached result if it exists
80+ const cached = await cacheDB . get ( cacheKey ) ;
81+ if ( typeof cached !== "undefined" ) {
82+ return cached ;
11783 }
11884
119- // Otherwise just transform the file
85+ // Otherwise, just transform the cacheKey
12086 // return it to the user asap and write it in cache
12187 const result = await transform ( source , options ) ;
122-
123- try {
124- await write ( file , cacheCompression , result ) ;
125- } catch ( err ) {
126- if ( fallback ) {
127- // Fallback to tmpdir if node_modules folder not writable
128- return handleCache ( os . tmpdir ( ) , params ) ;
129- }
130-
131- throw err ;
132- }
88+ cacheDB . put ( cacheKey , result ) ;
13389
13490 return result ;
13591} ;
@@ -173,5 +129,7 @@ module.exports = async function (params) {
173129 directory = defaultCacheDirectory ;
174130 }
175131
176- return await handleCache ( directory , params ) ;
132+ await initCacheDB ( directory , params . cacheCompression ) ;
133+
134+ return await handleCache ( params ) ;
177135} ;
0 commit comments