@@ -296,62 +296,45 @@ export const compileToSvg = (data: ContestData<{ withMarkdown: true }>) =>
296296 send < RenderTypstMessage > ( "renderTypst" , worker , compilerPrepare ( data ) ) ;
297297
298298export const compileToSvgDebounced = ( ( ) => {
299- let inFlight : Promise < string | undefined > | undefined = undefined ;
300- let pendingData : ContestData < { withMarkdown : true } > | undefined = undefined ;
301- let nextDeferred :
302- | {
303- resolve : ( v : string | undefined ) => void ;
304- reject : ( e : unknown ) => void ;
305- promise : Promise < string | undefined > ;
306- }
307- | undefined = undefined ;
308-
309- const runNext = ( ) => {
310- if ( ! pendingData ) {
311- // Nothing to run next
312- inFlight = undefined ;
313- return ;
314- }
315- const data = pendingData ;
316- pendingData = undefined ;
317- const deferred = nextDeferred ! ;
318- nextDeferred = undefined ;
319- inFlight = compileToSvg ( data )
320- . then ( ( res ) => {
321- deferred . resolve ( res ) ;
322- return res ;
323- } )
324- . catch ( ( err ) => {
325- deferred . reject ( err ) ;
326- throw err ;
327- } )
328- . finally ( ( ) => {
329- if ( pendingData ) runNext ( ) ;
330- else inFlight = undefined ;
331- } ) ;
299+ type Task = {
300+ args : ContestData < { withMarkdown : true } > ;
301+ promise : Promise < string | undefined > ;
302+ resolve : ( v : string | undefined ) => void ;
303+ reject : ( e : unknown ) => void ;
332304 } ;
305+ let currentTask : Task | undefined = undefined ;
306+ let waitingTask : Task | undefined = undefined ;
333307
334- return ( data : ContestData < { withMarkdown : true } > ) => {
335- if ( ! inFlight ) {
336- // No job running, execute immediately
337- inFlight = compileToSvg ( data ) . finally ( ( ) => {
338- if ( pendingData ) runNext ( ) ;
339- else inFlight = undefined ;
340- } ) ;
341- return inFlight ;
342- }
343- // A job is running: coalesce into the next run with the latest data
344- pendingData = data ;
345- if ( ! nextDeferred ) {
346- let resolve ! : ( v : string | undefined ) => void ;
347- let reject ! : ( e : unknown ) => void ;
348- const promise = new Promise < string | undefined > ( ( res , rej ) => {
349- resolve = res ;
350- reject = rej ;
308+ const run = ( ) => {
309+ if ( currentTask ) return ;
310+ if ( waitingTask ) {
311+ currentTask = waitingTask ;
312+ waitingTask = undefined ;
313+ } else return ;
314+ const task = currentTask ;
315+ compileToSvg ( task . args )
316+ . then ( task . resolve , task . reject )
317+ . then ( ( ) => {
318+ currentTask = undefined ;
319+ run ( ) ;
351320 } ) ;
352- nextDeferred = { resolve, reject, promise } ;
353- }
354- return nextDeferred . promise ;
321+ } ;
322+ return ( args : ContestData < { withMarkdown : true } > ) => {
323+ let resolve : ( v : string | undefined ) => void , reject : ( e : unknown ) => void ;
324+ const promise = new Promise < string | undefined > ( ( res , rej ) => {
325+ resolve = res ;
326+ reject = rej ;
327+ } ) ;
328+ const newTask : Task = {
329+ args,
330+ promise,
331+ resolve : resolve ! ,
332+ reject : reject ! ,
333+ } ;
334+ if ( waitingTask ) waitingTask . reject ( "Aborted" ) ;
335+ waitingTask = newTask ;
336+ run ( ) ;
337+ return promise ;
355338 } ;
356339} ) ( ) ;
357340
0 commit comments