diff --git a/src/contexts/decorators/cancellable.ts b/src/contexts/decorators/cancellable.ts index c76ce8b20a..4875f586c6 100644 --- a/src/contexts/decorators/cancellable.ts +++ b/src/contexts/decorators/cancellable.ts @@ -25,8 +25,12 @@ function cancellable(lazy: boolean = false) { let ctx: Partial = args[contextIndex]; if (ctx === undefined) { ctx = {}; - args[contextIndex] = ctx; + } else { + // Copy the ctx into a new ctx object to avoid mutating the ctx in case + // it is used again + ctx = { ...ctx }; } + args[contextIndex] = ctx; // Runtime type check on the context parameter contextsUtils.checkContextCancellable(ctx, key, targetName); return setupCancellable( diff --git a/src/contexts/decorators/timed.ts b/src/contexts/decorators/timed.ts index 08345f0a6c..312af6aef0 100644 --- a/src/contexts/decorators/timed.ts +++ b/src/contexts/decorators/timed.ts @@ -31,8 +31,12 @@ function timed( let ctx: Partial = args[contextIndex]; if (ctx === undefined) { ctx = {}; - args[contextIndex] = ctx; + } else { + // Copy the ctx into a new ctx object to avoid mutating the ctx in case + // it is used again + ctx = { ...ctx }; } + args[contextIndex] = ctx; // Runtime type check on the context parameter contextsUtils.checkContextTimed(ctx, key, targetName); const teardownContext = setupTimedContext( @@ -51,8 +55,12 @@ function timed( let ctx: Partial = args[contextIndex]; if (ctx === undefined) { ctx = {}; - args[contextIndex] = ctx; + } else { + // Copy the ctx into a new ctx object to avoid mutating the ctx in case + // it is used again + ctx = { ...ctx }; } + args[contextIndex] = ctx; // Runtime type check on the context parameter contextsUtils.checkContextTimed(ctx, key, targetName); const teardownContext = setupTimedContext( @@ -71,8 +79,12 @@ function timed( let ctx: Partial = args[contextIndex]; if (ctx === undefined) { ctx = {}; - args[contextIndex] = ctx; + } else { + // Copy the ctx into a new ctx object to avoid mutating the ctx in case + // it is used again + ctx = { ...ctx }; } + args[contextIndex] = ctx; // Runtime type check on the context parameter contextsUtils.checkContextTimed(ctx, key, targetName); const teardownContext = setupTimedContext( @@ -91,8 +103,12 @@ function timed( let ctx: Partial = args[contextIndex]; if (ctx === undefined) { ctx = {}; - args[contextIndex] = ctx; + } else { + // Copy the ctx into a new ctx object to avoid mutating the ctx in case + // it is used again + ctx = { ...ctx }; } + args[contextIndex] = ctx; // Runtime type check on the context parameter contextsUtils.checkContextTimed(ctx, key, targetName); const teardownContext = setupTimedContext( diff --git a/src/contexts/decorators/timedCancellable.ts b/src/contexts/decorators/timedCancellable.ts index 31e95b4fa0..8121321aad 100644 --- a/src/contexts/decorators/timedCancellable.ts +++ b/src/contexts/decorators/timedCancellable.ts @@ -31,8 +31,12 @@ function timedCancellable( let ctx: Partial = args[contextIndex]; if (ctx === undefined) { ctx = {}; - args[contextIndex] = ctx; + } else { + // Copy the ctx into a new ctx object to avoid mutating the ctx in case + // it is used again + ctx = { ...ctx }; } + args[contextIndex] = ctx; // Runtime type check on the context parameter contextsUtils.checkContextTimed(ctx, key, targetName); const lazy_ = typeof lazy === 'boolean' ? lazy : lazy(this); diff --git a/src/contexts/functions/cancellable.ts b/src/contexts/functions/cancellable.ts index 77fd8e8981..0f8cbe3731 100644 --- a/src/contexts/functions/cancellable.ts +++ b/src/contexts/functions/cancellable.ts @@ -73,7 +73,7 @@ function cancellable, R>( lazy: boolean = false, ): (...params: ContextAndParameters) => PromiseCancellable { return (...params) => { - const ctx = params[0] ?? {}; + const ctx = params[0] != null ? { ...params[0] } : {}; const args = params.slice(1) as P; return setupCancellable(f, lazy, ctx, args); }; diff --git a/src/contexts/functions/timed.ts b/src/contexts/functions/timed.ts index 3c4e621c66..9d53820023 100644 --- a/src/contexts/functions/timed.ts +++ b/src/contexts/functions/timed.ts @@ -125,7 +125,7 @@ function timed>( ): (...params: ContextAndParameters) => any { if (f instanceof utils.AsyncFunction) { return async (...params) => { - const ctx = params[0] ?? {}; + const ctx = params[0] != null ? { ...params[0] } : {}; const args = params.slice(1) as P; const teardownContext = setupTimedContext( delay, @@ -140,7 +140,7 @@ function timed>( }; } else if (f instanceof utils.GeneratorFunction) { return function* (...params) { - const ctx = params[0] ?? {}; + const ctx = params[0] != null ? { ...params[0] } : {}; const args = params.slice(1) as P; const teardownContext = setupTimedContext( delay, @@ -155,7 +155,7 @@ function timed>( }; } else if (f instanceof utils.AsyncGeneratorFunction) { return async function* (...params) { - const ctx = params[0] ?? {}; + const ctx = params[0] != null ? { ...params[0] } : {}; const args = params.slice(1) as P; const teardownContext = setupTimedContext( delay, @@ -170,7 +170,7 @@ function timed>( }; } else { return (...params) => { - const ctx = params[0] ?? {}; + const ctx = params[0] != null ? { ...params[0] } : {}; const args = params.slice(1) as P; const teardownContext = setupTimedContext( delay, diff --git a/src/contexts/functions/timedCancellable.ts b/src/contexts/functions/timedCancellable.ts index 332302358a..4b0fa7f5d0 100644 --- a/src/contexts/functions/timedCancellable.ts +++ b/src/contexts/functions/timedCancellable.ts @@ -153,7 +153,7 @@ function timedCancellable, R>( errorTimeoutConstructor: new () => Error = contextsErrors.ErrorContextsTimedTimeOut, ): (...params: ContextAndParameters) => PromiseCancellable { return (...params) => { - const ctx = params[0] ?? {}; + const ctx = params[0] != null ? { ...params[0] } : {}; const args = params.slice(1) as P; return setupTimedCancellable( f,