Prototype: allowRequest(recent,limit,window,now) validates positive integer settings, nonnegative now, and nondecreasing nonnegative accepted history no later than now. Duplicate timestamps valid. Return {allowed,history} filtering to strictly greater than now-window, then append now only if filtered size<limit. Preserve input; an overfull active history remains intact and denied.
Final: SlidingWindowLimiter applies that rule per nonempty client. allow(clientId,now) returns bool, rejects backward time including after denial, and preserves state on invalid calls. Different clients have independent clocks. history(clientId) returns a fresh retained list relative to last valid allow, without advancing/expiring; unseen valid client gives [].
Every class is exported by name from exercise.mjs. Keep instances independent. Unless explicitly documented otherwise, input values have the stated collection/string types and do not contain null elements. Invalid calls preserve state; validate before mutation. Return fresh mutable snapshots unless stated otherwise.
Complete the starter code, then run the checks.
Results and errors will appear here.