FunctionWrapper API Reference
FunctionWrapper is an advanced utility class that provides 80+ higher-order function decorators and wrappers for logging, timing, retrying, caching, debouncing, throttling, validating, transforming, and managing functions in versatile ways.
| Method | Parameters | Description | Usage Example | Output |
|---|---|---|---|---|
log(fn) |
fn: Function |
Logs function call and result | const add = (a,b)=>a+b; const loggedAdd = FunctionWrapper.log(add); loggedAdd(2,3); |
Logs: Calling add [2,3] Logs: Result from add 5 |
time(fn) |
fn: Function |
Measures execution time (async supported) | const slow = () => new Promise(res=>setTimeout(()=>res(42),100)); const timed = FunctionWrapper.time(slow); timed(); |
Logs: slow took 100.00 ms |
retry(fn, retries=3, delayMs=0) |
fn: Function, retries?: number, delayMs?: number |
Retries a failing function up to retries times with optional delay |
const unstable = ()=>{ if(Math.random()<0.7) throw Error('Fail'); return 'Ok'; }; const reliable = FunctionWrapper.retry(unstable,5,100); reliable().then(console.log) |
Either 'Ok' or error if all retries fail |
memo(fn) |
fn: Function |
Caches function results based on arguments | const square = x=>x*x; const cached = FunctionWrapper.memo(square); cached(2); cached(2); |
Only first call computes, second returns cached value |
debounce(fn, wait=300) |
fn: Function, wait?: number |
Delays execution until wait ms of inactivity |
const save = x=>console.log('Saved',x); const dSave = FunctionWrapper.debounce(save,500); dSave(1); dSave(2); |
Only 'Saved 2' after 500ms |
throttle(fn, wait=300) |
fn: Function, wait?: number |
Ensures function executes at most once per wait ms |
const log = x=>console.log(x); const tLog = FunctionWrapper.throttle(log,500); tLog(1); tLog(2); |
Executes 1 immediately, 2 after 500ms |
validate(fn, validator) |
fn: Function, validator: Function |
Validates arguments before calling | const sum = (a,b)=>a+b; const validated = FunctionWrapper.validate(sum,args=>{if(args.some(x=>typeof x!=='number'))throw Error('Invalid');}); validated(1,2); |
Returns 3 |
catch(fn, onError, fallback=null) |
fn: Function, onError?: Function, fallback?: any |
Catches errors, calls onError, optionally returns fallback |
const fail = ()=>{throw Error('Oops')}; const safe = FunctionWrapper.catch(fail,e=>console.log(e.message),'F'); safe(); |
Logs 'Oops' and returns 'F' |
once(fn) |
fn: Function |
Executes function only once globally | const inc=()=>1; const onceInc=FunctionWrapper.once(inc); onceInc(); onceInc(); |
Returns 1 both calls, only first actually executes |
after(fn, n=1) |
fn: Function, n?: number |
Executes function after n calls |
const log=()=>console.log('Hello'); const after2=FunctionWrapper.after(log,2); after2(); after2(); |
Logs 'Hello' on second call |
before(fn, n=1) |
fn: Function, n?: number |
Executes function at most n times |
const log=()=>console.log('Hi'); const b4=FunctionWrapper.before(log,2); b4(); b4(); b4(); |
Logs 'Hi' twice, third call returns null |
delayFn(fn, delay=1000) |
fn: Function, delay?: number |
Executes function after a delay | const say=()=>console.log('Hi'); const delayed=FunctionWrapper.delayFn(say,500); delayed(); |
Logs 'Hi' after 500ms |
timeLimit(fn, timeout=1000) |
fn: Function, timeout?: number |
Rejects if execution exceeds timeout | const slow=()=>new Promise(res=>setTimeout(()=>res(1),1500)); FunctionWrapper.timeLimit(slow,1000) |
Throws 'Timeout exceeded' |
tap(fn, tapFn) |
fn: Function, tapFn: Function |
Executes tapFn with function result without affecting it |
const double=x=>x*2; const tapped=FunctionWrapper.tap(double,r=>console.log('Tap',r)); tapped(3); |
Logs 'Tap 6', returns 6 |
restrict(fn, isAllowed) |
fn: Function, isAllowed: Function |
Throws if isAllowed returns false |
const secret=()=>42; const restricted=FunctionWrapper.restrict(secret,()=>false); restricted(); |
Throws 'Access denied' |
lock(fn) |
fn: Function |
Prevents concurrent execution | const sleep=x=>new Promise(res=>setTimeout(res,x)); const locked=FunctionWrapper.lock(sleep); locked(100); locked(100); |
Second call throws 'Already running' |
history(fn) |
fn: Function |
Tracks inputs and outputs | const add=(a,b)=>a+b; const h=FunctionWrapper.history(add); h(1,2); h.getHistory(); |
Returns [ { args:[1,2], result:3 } ] |
watch(fn) |
fn: Function |
Allows subscribing to results | const add=(a,b)=>a+b; const w=FunctionWrapper.watch(add); w.subscribe((args,res)=>console.log('Watched',res)); w(2,3); |
Logs 'Watched 5' |
mask(fn, masker) |
fn: Function, masker: Function |
Transforms arguments before calling | const sum=(a,b)=>a+b; const masked=FunctionWrapper.mask(sum,args=>args.map(x=>x*2)); masked(1,2); |
Returns 6 |
cancelable(fn) |
fn: Function |
Returns a cancelable promise | const p=()=>new Promise(res=>setTimeout(()=>res(1),500)); const c=FunctionWrapper.cancelable(p); const promise=c(); promise.cancel(); |
Rejects with 'Cancelled' |
limit(fn, max=5) |
fn: Function, max?: number |
Limits number of executions | const log=x=>x; const limited=FunctionWrapper.limit(log,2); limited(1); limited(2); limited(3); |
Third call throws 'Limit exceeded' |
rateTracker(fn, windowMs=1000) |
fn: Function, windowMs?: number |
Tracks number of calls in sliding window | const add=(a,b)=>a+b; const tracked=FunctionWrapper.rateTracker(add); tracked(1,2); |
Result object has _rate property |
replay(fn) |
fn: Function |
Returns cached result for identical arguments | const f=x=>x*2; const r=FunctionWrapper.replay(f); r(2); r(2); |
Returns 4 both times, second call uses cached result |
safeJson(fn) |
fn: Function |
Wraps function to catch JSON errors | const parse=JSON.parse; const safeParse=FunctionWrapper.safeJson(parse); safeParse('invalid'); |
Returns { error: 'Invalid JSON', details: ... } |
profile(fn) |
fn: Function |
Logs execution stats in table | const slow=x=>new Promise(res=>setTimeout(()=>res(x),100)); FunctionWrapper.profile(slow)(5); |
Logs table with function name, duration, timestamp |
unit(fn, unit='') |
fn: Function, unit?: string |
Returns { value, unit, timestamp } |
const add=(a,b)=>a+b; const u=FunctionWrapper.unit(add,'ms'); u(1,2); |
{ value:3, unit:'ms', timestamp: 12345678 } |
changelog(fn) |
fn: Function |
Logs changes in object output | const obj=()=>({x:Math.random()}); const c=FunctionWrapper.changelog(obj); c(); c(); |
Logs only changes |
undoable(fn, inverseFn) |
fn: Function, inverseFn: Function |
Supports undo operation | let x=0; const inc=()=>x++; const dec=()=>x--; const u=FunctionWrapper.undoable(inc,dec); u(); u.undo(); |
x returns to previous state |
feedback(fn, logger) |
fn: Function, logger?: Function |
Logs input/output with custom logger | const add=(a,b)=>a+b; const f=FunctionWrapper.feedback(add); f(1,2); |
Logs { input:[1,2], output:3 } |
locale(fn, formatter) |
fn: Function, formatter?: {input?: fn, output?: fn} |
Formats input/output | const add=(a,b)=>a+b; const loc=FunctionWrapper.locale(add,{output:r=>'Result:'+r}); loc(1,2); |
Returns 'Result:3' |
queue(fn) |
fn: Function |
Executes function sequentially | const sleep=x=>new Promise(res=>setTimeout(()=>res(x),100)); const q=FunctionWrapper.queue(sleep); q(1); q(2); |
Second call waits until first finishes |
repeat(fn, n=1) |
fn: Function, n?: number |
Calls function n times, returns array of results |
const f=x=>x*2; FunctionWrapper.repeat(f,3)(2); |
[4,4,4] |
test(fn, testCases=[]) |
fn: Function, testCases:Array<[input,expected]> |
Runs test cases | const add=(a,b)=>a+b; FunctionWrapper.test(add,[[ [1,2],3 ]])(); |
[ { input:[1,2], expected:3, result:3, passed:true } ] |
delayResult(fn, ms=1000) |
fn: Function, ms?: number |
Returns result after delay | const f=x=>x+1; FunctionWrapper.delayResult(f,500)(2); |
Returns 3 after 500ms |
ensure(fn, validator) |
fn: Function, validator: Function |
Throws if output fails validation | const f=x=>x*2; const e=FunctionWrapper.ensure(f,r=>r<5); e(2); e(3); |
Throws on second call |
randomizeArgs(fn) |
fn: Function |
Shuffles arguments randomly before calling | const f=(a,b)=>[a,b]; FunctionWrapper.randomizeArgs(f)(1,2); |
Returns [2,1] or [1,2] |
randomBehavior(fn, behaviors=[]) |
fn: Function, behaviors: Function[] |
Executes one of the random behaviors | const f=x=>x; const b=[(fn,args)=>fn(...args)*2]; FunctionWrapper.randomBehavior(f,b)(2); |
Returns 4 |
transformOutput(fn, transformer) |
fn: Function, transformer: Function |
Transforms function output | const f=x=>x+1; FunctionWrapper.transformOutput(f,r=>r*2)(2); |
Returns 6 |
evolve(fn, evolver) |
fn: Function, evolver: Function |
Mutates or extends output | const f=()=>({a:1}); FunctionWrapper.evolve(f,{b:2})(); |
{ a:1, b:2 } |
simulate(fn, {failRate=0.1, corrupt=false, delay=300}) |
fn: Function, options |
Simulates failures, delays, and corruption | const f=x=>x; FunctionWrapper.simulate(f,{failRate:1})(1) |
Throws 'Simulated Failure' |
chainable(fn) |
fn: Function |
Allows chaining calls and collecting results | const f=x=>x*2; const c=FunctionWrapper.chainable(f); c(1)(2).value(); |
Returns [2,4] |
predict(fn, modelFn) |
fn: Function, modelFn: Function |
Adds prediction based on function output | const f=x=>x*2; const p=FunctionWrapper.predict(f,r=>r+1); p(2); |
{ result:4, prediction:5 } |
delayIf(fn, condition, delayMs=1000) |
fn: Function, condition: Function, delayMs?: number |
Delays execution if condition is true | const f=x=>x; FunctionWrapper.delayIf(f,x=>x>0,500)(1); |
Returns 1 after 500ms |
eventual(fn, checkFn, interval=100) |
fn: Function, checkFn: Function, interval?: number |
Polls until checkFn returns true | const f=x=>x; FunctionWrapper.eventual(f,()=>true)(); |
Resolves immediately |
pipe(...fns) |
fns: Function[] |
Composes multiple functions left to right | FunctionWrapper.pipe(x=>x+1,x=>x*2)(2); |
Returns (2+1)*2 = 6 |
filterArgs(fn, filterFn) |
fn: Function, filterFn: Function |
Calls fn only if filterFn returns true | const f=x=>x; FunctionWrapper.filterArgs(f,x=>x>0)(-1); |
Returns null |
warnOnArgs(fn, warningFn) |
fn: Function, warningFn: Function |
Warns if warningFn returns true | const f=x=>x; FunctionWrapper.warnOnArgs(f,x=>x<0)(-1); |
Logs warning, returns -1 |
oncePerArgs(fn) |
fn: Function |
Executes once per argument combination | const f=x=>x; FunctionWrapper.oncePerArgs(f)(1); FunctionWrapper.oncePerArgs(f)(1); |
Returns 1, then null |
alertOn(fn, condition) |
fn: Function, condition: Function |
Alerts if condition on result is true | const f=x=>x; FunctionWrapper.alertOn(f,r=>r>0)(1); |
Logs alert, returns 1 |
hook(fn, { before, after }) |
fn: Function, before?: Function, after?: Function |
Adds pre- and post-execution hooks | const f=x=>x*2; FunctionWrapper.hook(f,{before:x=>console.log('Before',x),after:(r)=>console.log('After',r)})(2); |
Logs 'Before 2', 'After 4', returns 4 |
delayEach(fn, delayMs=300) |
fn: Function, delayMs?: number |
Calls function for each argument sequentially with delay | const f=x=>x*2; FunctionWrapper.delayEach(f,100)(1,2,3); |
Returns [2,4,6] over 100ms intervals |
sandbox(fn, timeout=1000) |
fn: Function, timeout?: number |
Executes safely with error handling | const f=()=>{throw Error('Fail')}; FunctionWrapper.sandbox(f)(); |
Logs 'Sandbox Error: Fail', returns undefined |
afterIdle(fn, timeout=0) |
fn: Function, timeout?: number |
Executes when browser idle | FunctionWrapper.afterIdle(()=>console.log('Idle'),500) |
Logs 'Idle' after idle period |
smartIdle(fn, {timeout=1000}) |
fn: Function, options |
Idle execution with cancellation | const f=x=>x; const s=FunctionWrapper.smartIdle(f); s(1); s.cancel(); |
Cancels execution if idle hasn't started |