import { Node } from 'shared/parse/Node' ; import { Logger } from 'shared/render/Logger' ; import { PlaytestSettings } from '../reducers/StateTypes' ; import { PlaytestCrawler } from './PlaytestCrawler' ; const cheerio = require ( 'cheerio' ) as CheerioAPI ; function mockContext ( ) { const populateScopeFn = ( ) => { return { contentSets ( ) { return { horror : true , future : true , scarredlands : true } ; } , numAdventurers ( ) { return 3 ; } , aliveAdventurers ( ) { return 3 ; } , viewCount ( id ) { return this . views [ id ] || 0 ; } , randomEnemy ( ) { return 'Giant Rat' ; } , randomEnemyOfTier ( tier ) { return 'Giant Rat' ; } , randomEnemyOfClass ( className ) { return 'Giant Rat' ; } , randomEnemyOfClassTier ( className , tier ) { return 'Giant Rat' ; } , currentCombatRound ( ) { return 0 ; } , currentCombatTier ( ) { return 1 ; } , isCombatSurgeRound ( ) { return false ; } , } ; } ; const newContext = { _templateScopeFn : populateScopeFn , path : ( [ ] as any ) , scope : { _ : populateScopeFn ( ) , } , templates : { } , views : { } , } ; for ( const k of Object . keys ( newContext . scope . _ ) ) { newContext . scope . _ [ k ] = ( newContext . scope . _ [ k ] as any ) . bind ( newContext ) ; } return newContext ; } function maybePublishLog ( logger ) { const m = logger . getFinalizedLogs ( ) ; if ( m . error . length || m . info . length || m . internal . length || m . warning . length ) { ( postMessage as any ) ( m ) ; } } interface RunMessage { type : 'RUN' ; timeoutMillis : number ; settings : PlaytestSettings ; xml : string ; } function handleMessage ( e ) { try { const crawler = new PlaytestCrawler ( e . data . settings ) ; const start = Date . now ( ) ; const timeout = e . data . timeoutMillis || 30000 ; const logger = new Logger ( ) ; const elem = cheerio . load ( e . data . xml ) ( 'quest > :first-child' ) ; if ( ! elem ) { throw new Error ( 'Invalid element passed to webworker' ) ; } console . log ( 'Playtest STARTED' ) ; let [ queueLen , numSeen ] = crawler . crawlWithLog ( new Node ( elem , mockContext ( ) ) , logger ) ; maybePublishLog ( logger ) ; let elapsed = 0 ; let lastLog = elapsed ; let step = 0 ; const asyncTest = ( ) => { if ( elapsed > timeout || ! ( queueLen > 0 ) ) { const ms = Date . now ( ) - start ; const lines = crawler . getLines ( ) . length ; console . log ( `Playtest COMPLETE (${ ms } ms, ${ lines } lines)` ) ; ( postMessage as any ) ( { status : 'COMPLETE' , ms , lines } ) ; close ( ) ; return ; } const result = crawler . crawlWithLog ( undefined , logger ) ; queueLen = result [ 0 ] ; numSeen = result [ 1 ] ; if ( elapsed - lastLog > 250 ) { console . log ( `Playtest (step ${ step }, queueLen ${ queueLen }, seen ${ numSeen })` ) ; lastLog = elapsed ; } maybePublishLog ( logger ) ; elapsed = ( Date . now ( ) - start ) ; step ++ ; setTimeout ( asyncTest , 0 ) ; } ; asyncTest ( ) ; } catch ( err ) { console . error ( err . toString ( ) ) ; ( postMessage as any ) ( { status : 'COMPLETE' } ) ; } } onmessage = ( handleMessage as any ) ;