@@ -200,7 +200,7 @@ class IO {
200
200
* @returns {boolean }
201
201
*/
202
202
send ( command , payload ) {
203
- try {
203
+ try {
204
204
let message = JSON . stringify ( { command : command , payload : payload } ) ;
205
205
this . socket . send ( message ) ;
206
206
} catch {
@@ -419,6 +419,7 @@ Object.assign(IO.prototype, Dispatcher);
419
419
420
420
/**
421
421
* RFC-compliant UUID
422
+ *
422
423
* @see {@link https://www.ietf.org/rfc/rfc4122.txt }
423
424
*/
424
425
function uuidv4 ( ) {
@@ -434,6 +435,25 @@ function microtime() {
434
435
return performance . now ( ) + performance . timing . navigationStart ;
435
436
}
436
437
438
+ /**
439
+ * Same as Date.now(), but with microsecond precision
440
+ *
441
+ * To offer protection against timing attacks and fingerprinting, the precision of performance.now()
442
+ * might get rounded depending on browser settings. Currently, the resolution is 5μs in Chrome.
443
+ * To avoid collisions, we add 1μs if two consecutive timestamps are identical.
444
+ *
445
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Performance/now }
446
+ * @see {@link https://hal.inria.fr/hal-03215569/document }
447
+ * @see {@link https://gruss.cc/files/fantastictimers.pdf }
448
+ */
449
+ function microtime ( ) {
450
+ let ts = performance . now ( ) ;
451
+ if ( ts <= globalThis . _last_microtime ) ts = globalThis . _last_microtime + 1e-3 ;
452
+ globalThis . _last_microtime = ts ;
453
+ return ts + performance . timing . navigationStart ;
454
+ }
455
+
456
+
437
457
/**
438
458
* Performs a deep merge of objects and returns new object. Does not modify
439
459
* objects (immutable) and merges arrays via concatenation.
0 commit comments