Sleep and background wakeup system
How do you cancel a sleep once it starts?  I would expect that calling .expireAt(nil) might accomplish that.  However, if @expireAt is nil, calcTimeLeft() crashes.

Alternatively, one might try to call .onExpiry(nil), but you don't handle @onExpiry being nil either.