Overview
The WrapperInit class provides a convenient way to track function execution metrics while wrapping functions with resilience behavior. It maintains counters for function calls and provides built-in hooks integration.
Class Definition
class WrapperInit {
functionCalls : number ;
f_store : Map < string , number >;
record ( name : string ) : void ;
hooks () : ResilienceHooks ;
wrap < Fn extends ( ... args : any []) => any >(
fn : Fn ,
config ?: Omit < ResilienceConfig , 'hooks' | 'name' > & { name ?: string }
) : ( ... args : Parameters < Fn >) => Promise < Awaited < ReturnType < Fn >>>;
run < Fn extends ( ... args : any []) => any >(
fn : Fn ,
... args : Parameters < Fn >
) : ReturnType < Fn >;
}
Constructor
const wrapper = new WrapperInit ();
Creates a new metrics tracker with initialized counters.
Properties
Total number of function calls tracked across all functions.
f_store
Map<string, number>
default: "new Map()"
Map of function names to their individual call counts. Key is the function name, value is the number of times that function was attempted.
Methods
record()
Records a function attempt by name, incrementing both the function-specific counter and the total counter.
record ( name : string ): void
The name of the function to record an attempt for.
Implementation (from src/index.ts:214-218):
record ( name : string ) {
const prev = this . f_store . get ( name ) ?? 0 ;
this . f_store . set ( name , prev + 1 );
this . functionCalls ++ ;
}
hooks()
Returns a ResilienceHooks object that automatically records metrics on each attempt.
A hooks object with onAttempt configured to call record(name) for each function attempt.
Implementation (from src/index.ts:223-229):
hooks (): Resilience . ResilienceHooks {
return {
onAttempt : ({ name }) => {
this . record ( name );
},
};
}
wrap()
Wraps a function with resilience behavior and automatically attaches metrics hooks.
wrap < Fn extends ( ... args : any []) => any > (
fn : Fn ,
config ?: Omit < ResilienceConfig , 'hooks' | 'name' > & { name? : string }
) : ( ... args : Parameters < Fn >) => Promise < Awaited < ReturnType < Fn >>>
fn
Fn extends (...args: any[]) => any
required
The function to wrap with resilience and metrics tracking.
config
Omit<ResilienceConfig, 'hooks' | 'name'> & { name?: string }
default: "{}"
Resilience configuration without hooks or name (those are set automatically). Optional function name. Defaults to fn.name or “anonymous”.
Number of retry attempts.
Execution timeout in milliseconds.
Backoff strategy for retries.
retryOn
(err: unknown) => boolean
Predicate to determine if error should trigger retry.
Circuit breaker configuration.
Enable abort signal support.
wrappedFunction
(...args: Parameters<Fn>) => Promise<Awaited<ReturnType<Fn>>>
The wrapped function with resilience and metrics tracking.
Implementation (from src/index.ts:234-243):
wrap < Fn extends ( ... args : any []) => any > (
fn : Fn ,
config : Omit < Resilience . ResilienceConfig , 'hooks' | 'name' > & { name? : string } = {}
) {
return withResilience ( fn , {
... config ,
name: config . name ?? fn . name ?? 'anonymous' ,
hooks: this . hooks (),
});
}
run()
Runs a function immediately and records metrics without applying resilience features.
run < Fn extends ( ... args : any []) => any > (
fn : Fn ,
... args : Parameters < Fn >
): ReturnType < Fn >
fn
Fn extends (...args: any[]) => any
required
The function to execute.
Arguments to pass to the function.
The return value from executing the function (not wrapped in a Promise).
Implementation (from src/index.ts:248-258):
run < Fn extends ( ... args : any []) => any >( fn : Fn , ... args : Parameters < Fn >) : ReturnType < Fn > {
const wf = new WrappedFunction ( fn , ... args )
if ( ! this . f_store . has ( wf . name )) {
this . f_store . set ( wf . name , 0 )
}
const val = wf . run ();
const cur_count : number = this . f_store . get ( wf . name ) as number ;
this . f_store . set ( wf . name , cur_count + 1 );
this . functionCalls ++ ;
return val . returnValue
}
Examples
Basic Usage with Metrics Tracking
import { WrapperInit } from '@oldwhisper/resilience' ;
const wrapper = new WrapperInit ();
// Wrap multiple functions
const fetchUser = wrapper . wrap (
async ( id : string ) => {
return await fetch ( `/api/users/ ${ id } ` ). then ( r => r . json ());
},
{
name: 'fetch-user' ,
retries: 3 ,
timeoutMs: 5000
}
);
const fetchPosts = wrapper . wrap (
async ( userId : string ) => {
return await fetch ( `/api/posts?user= ${ userId } ` ). then ( r => r . json ());
},
{
name: 'fetch-posts' ,
retries: 2
}
);
// Use the wrapped functions
await fetchUser ( '123' );
await fetchUser ( '456' );
await fetchPosts ( '123' );
// Check metrics
console . log ( 'Total calls:' , wrapper . functionCalls ); // 3
console . log ( 'fetch-user calls:' , wrapper . f_store . get ( 'fetch-user' )); // 2
console . log ( 'fetch-posts calls:' , wrapper . f_store . get ( 'fetch-posts' )); // 1
Using run() for Synchronous Execution
const wrapper = new WrapperInit ();
function calculateTotal ( items : number []) : number {
return items . reduce (( sum , item ) => sum + item , 0 );
}
// Run without resilience features, just tracking
const result = wrapper . run ( calculateTotal , [ 1 , 2 , 3 , 4 , 5 ]);
console . log ( 'Result:' , result ); // 15
console . log ( 'Total calls:' , wrapper . functionCalls ); // 1
Tracking Metrics Across Application
// Create a global wrapper instance
export const metricsWrapper = new WrapperInit ();
// In different modules, wrap your functions
export const apiClient = {
getUser: metricsWrapper . wrap ( getUserImpl , {
name: 'api.getUser' ,
retries: 3 ,
circuitBreaker: {
failureThreshold: 5 ,
resetTimeoutMs: 60000
}
}),
createOrder: metricsWrapper . wrap ( createOrderImpl , {
name: 'api.createOrder' ,
retries: 2 ,
timeoutMs: 10000
})
};
// Expose metrics endpoint
app . get ( '/metrics' , ( req , res ) => {
res . json ({
totalCalls: metricsWrapper . functionCalls ,
perFunction: Object . fromEntries ( metricsWrapper . f_store )
});
});
Custom Hooks with Wrapper
If you need additional hooks beyond metrics tracking, use withResilience directly:
const wrapper = new WrapperInit ();
const myFunction = withResilience (
async () => { /* ... */ },
{
name: 'my-function' ,
retries: 3 ,
hooks: {
... wrapper . hooks (), // Include metrics tracking
onSuccess : ({ name , timeMs }) => {
logger . info ( ` ${ name } succeeded in ${ timeMs } ms` );
},
onFailure : ({ name , error }) => {
logger . error ( ` ${ name } failed:` , error );
}
}
}
);
Use Cases
API Client Libraries : Track request counts per endpoint
Background Jobs : Monitor job execution frequency
Microservices : Collect service-to-service call metrics
Testing : Verify retry behavior by checking attempt counts
Dashboards : Export metrics for visualization