@@ -235,6 +235,7 @@ var AMDLoader;
235235 *--------------------------------------------------------------------------------------------*/
236236var AMDLoader ;
237237( function ( AMDLoader ) {
238+ ;
238239 var ConfigurationOptionsUtil = ( function ( ) {
239240 function ConfigurationOptionsUtil ( ) {
240241 }
@@ -305,22 +306,8 @@ var AMDLoader;
305306 if ( typeof options . nodeCachedData . writeDelay !== 'number' || options . nodeCachedData . writeDelay < 0 ) {
306307 options . nodeCachedData . writeDelay = 1000 * 7 ;
307308 }
308- if ( typeof options . nodeCachedData . onData !== 'function' ) {
309- options . nodeCachedData . onData = function ( err ) {
310- if ( err && err . errorCode === 'cachedDataRejected' ) {
311- console . warn ( 'Rejected cached data from file: ' + err . path ) ;
312- }
313- else if ( err && err . errorCode ) {
314- console . error ( 'Problems handling cached data file: ' + err . path ) ;
315- console . error ( err . detail ) ;
316- }
317- else if ( err ) {
318- console . error ( err ) ;
319- }
320- } ;
321- }
322309 if ( ! options . nodeCachedData . path || typeof options . nodeCachedData . path !== 'string' ) {
323- options . nodeCachedData . onData ( 'INVALID cached data configuration, \'path\' MUST be set' ) ;
310+ options . onError ( 'INVALID cached data configuration, \'path\' MUST be set' ) ;
324311 options . nodeCachedData = undefined ;
325312 }
326313 }
@@ -660,7 +647,6 @@ var AMDLoader;
660647 this . _env = env ;
661648 this . _didInitialize = false ;
662649 this . _didPatchNodeRequire = false ;
663- this . _hasCreateCachedData = false ;
664650 }
665651 NodeScriptLoader . prototype . _init = function ( nodeRequire ) {
666652 if ( this . _didInitialize ) {
@@ -672,14 +658,17 @@ var AMDLoader;
672658 this . _vm = nodeRequire ( 'vm' ) ;
673659 this . _path = nodeRequire ( 'path' ) ;
674660 this . _crypto = nodeRequire ( 'crypto' ) ;
675- // check for `createCachedData`-api
676- this . _hasCreateCachedData = typeof ( new this . _vm . Script ( '' ) . createCachedData ) === 'function' ;
677661 } ;
678662 // patch require-function of nodejs such that we can manually create a script
679663 // from cached data. this is done by overriding the `Module._compile` function
680664 NodeScriptLoader . prototype . _initNodeRequire = function ( nodeRequire , moduleManager ) {
665+ // It is important to check for `nodeCachedData` first and then set `_didPatchNodeRequire`.
666+ // That's because `nodeCachedData` is set _after_ calling this for the first time...
681667 var nodeCachedData = moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData ;
682- if ( ! nodeCachedData || this . _didPatchNodeRequire ) {
668+ if ( ! nodeCachedData ) {
669+ return ;
670+ }
671+ if ( this . _didPatchNodeRequire ) {
683672 return ;
684673 }
685674 this . _didPatchNodeRequire = true ;
@@ -708,21 +697,21 @@ var AMDLoader;
708697 content = content . replace ( / ^ # ! .* / , '' ) ;
709698 // create wrapper function
710699 var wrapper = Module . wrap ( content ) ;
711- var cachedDataPath = that . _getCachedDataPath ( nodeCachedData . seed , nodeCachedData . path , filename ) ;
700+ var cachedDataPath = that . _getCachedDataPath ( nodeCachedData , filename ) ;
712701 var options = { filename : filename } ;
713702 try {
714703 options . cachedData = that . _fs . readFileSync ( cachedDataPath ) ;
715704 }
716705 catch ( e ) {
717- options . produceCachedData = ! that . _hasCreateCachedData ;
706+ // ignore
718707 }
719708 var script = new that . _vm . Script ( wrapper , options ) ;
720709 var compileWrapper = script . runInThisContext ( options ) ;
721710 var dirname = that . _path . dirname ( filename ) ;
722711 var require = makeRequireFunction ( this ) ;
723712 var args = [ this . exports , require , this , filename , dirname , process , _commonjsGlobal , Buffer ] ;
724713 var result = compileWrapper . apply ( this . exports , args ) ;
725- that . _processCachedData ( moduleManager , script , wrapper , cachedDataPath , ! options . cachedData ) ;
714+ that . _processCachedData ( script , cachedDataPath , Boolean ( options . cachedData ) , moduleManager . getConfig ( ) , moduleManager . getRecorder ( ) ) ;
726715 return result ;
727716 } ;
728717 } ;
@@ -780,16 +769,16 @@ var AMDLoader;
780769 _this . _loadAndEvalScript ( moduleManager , scriptSrc , vmScriptSrc , contents , { filename : vmScriptSrc } , recorder , callback , errorback ) ;
781770 }
782771 else {
783- var cachedDataPath_1 = _this . _getCachedDataPath ( opts . nodeCachedData . seed , opts . nodeCachedData . path , scriptSrc ) ;
772+ var cachedDataPath_1 = _this . _getCachedDataPath ( opts . nodeCachedData , scriptSrc ) ;
784773 _this . _fs . readFile ( cachedDataPath_1 , function ( _err , cachedData ) {
785774 // create script options
786775 var options = {
787776 filename : vmScriptSrc ,
788- produceCachedData : ! _this . _hasCreateCachedData && typeof cachedData === 'undefined' ,
789777 cachedData : cachedData
790778 } ;
779+ recorder . record ( cachedData ? 60 /* CachedDataFound */ : 61 /* CachedDataMissed */ , scriptSrc ) ;
791780 var script = _this . _loadAndEvalScript ( moduleManager , scriptSrc , vmScriptSrc , contents , options , recorder , callback , errorback ) ;
792- _this . _processCachedData ( moduleManager , script , contents , cachedDataPath_1 , ! options . cachedData ) ;
781+ _this . _processCachedData ( script , cachedDataPath_1 , Boolean ( cachedData ) , moduleManager . getConfig ( ) , recorder ) ;
793782 } ) ;
794783 }
795784 } ) ;
@@ -818,74 +807,56 @@ var AMDLoader;
818807 }
819808 return script ;
820809 } ;
821- NodeScriptLoader . prototype . _getCachedDataPath = function ( seed , basedir , filename ) {
822- var hash = this . _crypto . createHash ( 'md5' ) . update ( filename , 'utf8' ) . update ( seed , 'utf8' ) . digest ( 'hex' ) ;
810+ NodeScriptLoader . prototype . _getCachedDataPath = function ( config , filename ) {
811+ var hash = this . _crypto . createHash ( 'md5' ) . update ( filename , 'utf8' ) . update ( config . seed , 'utf8' ) . digest ( 'hex' ) ;
823812 var basename = this . _path . basename ( filename ) . replace ( / \. j s $ / , '' ) ;
824- return this . _path . join ( basedir , basename + "-" + hash + ".code" ) ;
813+ return this . _path . join ( config . path , basename + "-" + hash + ".code" ) ;
825814 } ;
826- NodeScriptLoader . prototype . _processCachedData = function ( moduleManager , script , contents , cachedDataPath , createCachedData ) {
815+ NodeScriptLoader . prototype . _processCachedData = function ( script , cachedDataPath , hadCachedData , config , recorder ) {
827816 var _this = this ;
828817 if ( script . cachedDataRejected ) {
829- // data rejected => delete cache file
830- moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . onData ( {
831- errorCode : 'cachedDataRejected' ,
832- path : cachedDataPath
818+ // rejected cached data
819+ // (1) delete data
820+ // (2) create new data
821+ recorder . record ( 62 /* CachedDataRejected */ , cachedDataPath ) ;
822+ this . _fs . unlink ( cachedDataPath , function ( err ) {
823+ if ( err ) {
824+ config . onError ( err ) ;
825+ }
826+ _this . _createCachedData ( script , cachedDataPath , config , recorder ) ;
833827 } ) ;
834- NodeScriptLoader . _runSoon ( function ( ) {
835- return _this . _fs . unlink ( cachedDataPath , function ( err ) {
836- if ( err ) {
837- moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . onData ( {
838- errorCode : 'unlink' ,
839- path : cachedDataPath ,
840- detail : err
841- } ) ;
842- }
843- } ) ;
844- } , moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . writeDelay / 2 ) ;
845828 }
846- else if ( script . cachedDataProduced ) {
847- // data produced => tell outside world
848- moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . onData ( undefined , {
849- path : cachedDataPath
850- } ) ;
851- // data produced => write cache file
852- NodeScriptLoader . _runSoon ( function ( ) {
853- return _this . _fs . writeFile ( cachedDataPath , script . cachedData , function ( err ) {
854- if ( err ) {
855- moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . onData ( {
856- errorCode : 'writeFile' ,
857- path : cachedDataPath ,
858- detail : err
859- } ) ;
860- }
861- } ) ;
862- } , moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . writeDelay ) ;
829+ else if ( ! hadCachedData ) {
830+ // create cached data unless we already had
831+ // and accepted cached data
832+ this . _createCachedData ( script , cachedDataPath , config , recorder ) ;
863833 }
864- else if ( this . _hasCreateCachedData && createCachedData ) {
865- // NEW world
866- // data produced => tell outside world
867- moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . onData ( undefined , {
868- path : cachedDataPath
869- } ) ;
870- // soon'ish create and save cached data
871- NodeScriptLoader . _runSoon ( function ( ) {
872- var data = script . createCachedData ( contents ) ;
834+ } ;
835+ NodeScriptLoader . prototype . _createCachedData = function ( script , cachedDataPath , config , recorder ) {
836+ var _this = this ;
837+ var timeout = Math . ceil ( config . getOptionsLiteral ( ) . nodeCachedData . writeDelay * ( 1 + Math . random ( ) ) ) ;
838+ var lastSize = - 1 ;
839+ var iteration = 0 ;
840+ var createLoop = function ( ) {
841+ setTimeout ( function ( ) {
842+ var data = script . createCachedData ( ) ;
843+ if ( data . length === lastSize ) {
844+ return ;
845+ }
846+ lastSize = data . length ;
873847 _this . _fs . writeFile ( cachedDataPath , data , function ( err ) {
874- if ( ! err ) {
875- return ;
848+ if ( err ) {
849+ config . onError ( err ) ;
876850 }
877- moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . onData ( {
878- errorCode : 'writeFile' ,
879- path : cachedDataPath ,
880- detail : err
881- } ) ;
851+ recorder . record ( 63 /* CachedDataCreated */ , cachedDataPath ) ;
852+ createLoop ( ) ;
882853 } ) ;
883- } , moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedData . writeDelay ) ;
884- }
885- } ;
886- NodeScriptLoader . _runSoon = function ( callback , minTimeout ) {
887- var timeout = minTimeout + Math . ceil ( Math . random ( ) * minTimeout ) ;
888- setTimeout ( callback , timeout ) ;
854+ } , timeout * ( Math . pow ( 4 , iteration ++ ) ) ) ;
855+ } ;
856+ // with some delay (`timeout`) create cached data
857+ // and repeat that (with backoff delay) until the
858+ // data seems to be not changing anymore
859+ createLoop ( ) ;
889860 } ;
890861 return NodeScriptLoader ;
891862 } ( ) ) ;
0 commit comments