@@ -18,6 +18,7 @@ import { handleEvent } from "./handleEvent"
1818import { HandleActionsOptions , TestOptions } from "./types"
1919import { deepClone , findNamedChild , set } from "./utils"
2020import { handleArrayLogic } from "./arrayHandling"
21+ import { create } from "mutative"
2122
2223/**
2324 * Recursively evaluate a value or object.
@@ -240,6 +241,7 @@ function realTest<Variables>(
240241 path,
241242 }
242243
244+ // Add the timer directly to the array
243245 options . timers . push ( timer )
244246 }
245247
@@ -254,6 +256,7 @@ function realTest<Variables>(
254256 )
255257
256258 if ( index !== - 1 ) {
259+ // Remove the timer directly from the array
257260 options . timers . splice ( index , 1 )
258261 }
259262
@@ -333,33 +336,52 @@ export function handleActions<Context>(
333336 return context
334337 }
335338
339+ return create ( context , ( draft ) => {
340+ handleActionsOnDraft ( input , draft , context , options )
341+ } )
342+ }
343+
344+ /**
345+ * Internal function that applies actions directly to a draft object.
346+ * This is used both by handleActions and handleEvent to avoid code duplication.
347+ */
348+ export function handleActionsOnDraft < Context > (
349+ input : any ,
350+ draft : any ,
351+ originalContext : Context ,
352+ options ?: HandleActionsOptions ,
353+ ) : void {
354+ if ( ! input || typeof input !== "object" ) {
355+ return
356+ }
357+
336358 const addOrDec = ( op : string ) => {
337359 if ( typeof input [ op ] === "string" ) {
338360 let reference = input [ op ]
339361
340- const variableValue = findNamedChild ( input [ op ] , context , true )
362+ const variableValue = findNamedChild ( input [ op ] , originalContext , true )
341363
342364 if ( typeof variableValue !== "number" ) {
343365 return
344366 }
345367
346368 set (
347- context ,
369+ draft ,
348370 reference ,
349371 op === "$inc" ? variableValue + 1 : variableValue - 1 ,
350372 )
351373 } else {
352374 let reference = input [ op ] [ 0 ]
353375
354- const variableValue = findNamedChild ( reference , context , true )
355- const incrementBy = findNamedChild ( input [ op ] [ 1 ] , context , false )
376+ const variableValue = findNamedChild ( reference , originalContext , true )
377+ const incrementBy = findNamedChild ( input [ op ] [ 1 ] , originalContext , false )
356378
357379 if ( typeof variableValue !== "number" ) {
358380 return
359381 }
360382
361383 set (
362- context ,
384+ draft ,
363385 reference ,
364386 op === "$inc"
365387 ? variableValue + incrementBy
@@ -376,10 +398,10 @@ export function handleActions<Context>(
376398 reference = reference . substring ( 1 )
377399 }
378400
379- const value = findNamedChild ( input [ op ] [ 1 ] , context , false )
401+ const value = findNamedChild ( input [ op ] [ 1 ] , originalContext , false )
380402
381403 // clone the thing
382- const array = deepClone ( findNamedChild ( reference , context , true ) )
404+ const array = deepClone ( findNamedChild ( reference , originalContext , true ) )
383405
384406 if ( ! Array . isArray ( array ) ) {
385407 return
@@ -395,7 +417,7 @@ export function handleActions<Context>(
395417 array . push ( value )
396418 }
397419
398- set ( context , reference , array )
420+ set ( draft , reference , array )
399421 }
400422
401423 for ( const key of Object . keys ( input ) ) {
@@ -416,12 +438,12 @@ export function handleActions<Context>(
416438 // Therefore the 1st operand might get written to, but the 2nd one is purely a read.
417439 const variableValue1 = findNamedChild (
418440 input [ "$mul" ] [ 0 ] ,
419- context ,
441+ originalContext ,
420442 true ,
421443 )
422444 const variableValue2 = findNamedChild (
423445 input [ "$mul" ] [ 1 ] ,
424- context ,
446+ originalContext ,
425447 false ,
426448 )
427449
@@ -432,15 +454,15 @@ export function handleActions<Context>(
432454 break
433455 }
434456
435- set ( context , reference , variableValue1 * variableValue2 )
457+ set ( draft , reference , variableValue1 * variableValue2 )
436458 break
437459 }
438460 case "$set" : {
439461 let reference = input . $set [ 0 ]
440462
441- const value = findNamedChild ( input . $set [ 1 ] , context , false )
463+ const value = findNamedChild ( input . $set [ 1 ] , originalContext , false )
442464
443- set ( context , reference , value )
465+ set ( draft , reference , value )
444466 break
445467 }
446468 case "$push" : {
@@ -458,11 +480,11 @@ export function handleActions<Context>(
458480 reference = reference . substring ( 1 )
459481 }
460482
461- const value = findNamedChild ( input . $remove [ 1 ] , context , false )
483+ const value = findNamedChild ( input . $remove [ 1 ] , originalContext , false )
462484
463485 // clone the thing
464486 let array : unknown [ ] = deepClone (
465- findNamedChild ( reference , context , true ) ,
487+ findNamedChild ( reference , originalContext , true ) ,
466488 )
467489
468490 if ( ! Array . isArray ( array ) ) {
@@ -471,24 +493,22 @@ export function handleActions<Context>(
471493
472494 array = array . filter ( ( item ) => item !== value )
473495
474- set ( context , reference , array )
496+ set ( draft , reference , array )
475497 break
476498 }
477499 case "$reset" : {
478500 let reference = input . $reset
479501 const value = findNamedChild (
480502 reference ,
481- options . originalContext ,
503+ options ? .originalContext ,
482504 true ,
483505 )
484506
485- set ( context , reference , value )
507+ set ( draft , reference , value )
486508 break
487509 }
488510 }
489511 }
490-
491- return context
492512}
493513
494514export { handleEvent }
0 commit comments