@mmstack/primitives 20.15.1 → 20.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6922,14 +6922,27 @@ function storeTabSync(sig, opt, bus, injector) {
6922
6922
  case 'hello': {
6923
6923
  if (phase !== 'live' || msg.from === sync.origin)
6924
6924
  return;
6925
- // first responder wins: jittered answer, cancelled when someone else answers first
6926
- const timer = setTimeout(() => {
6927
- responseTimers.delete(msg.from);
6925
+ const respond = () => {
6928
6926
  const snap = sync.snapshot();
6929
6927
  const covered = Object.entries(snap.wm).every(([origin, v]) => (msg.wm[origin] ?? 0) >= v);
6930
6928
  post(covered
6931
6929
  ? { t: 'uptodate', proto: OP_PROTO_VERSION, to: msg.from }
6932
6930
  : { t: 'state', proto: OP_PROTO_VERSION, to: msg.from, state: snap });
6931
+ };
6932
+ // `jitterMs: 0` answers HERE, in the message handler, with no timer at all. This is the
6933
+ // difference between "as fast as possible" and "possible": a hidden tab's timers are
6934
+ // aligned to ≥1s, so even setTimeout(0) from a backgrounded responder routinely outlives
6935
+ // the joiner's hello window — while message events are not throttled. A channel whose
6936
+ // typical population is one hidden responder (a builder answering its preview tab) opts
6937
+ // in; the jittered path stays the default for many-peer channels.
6938
+ if (jitterMs === 0) {
6939
+ respond();
6940
+ return;
6941
+ }
6942
+ // first responder wins: jittered answer, cancelled when someone else answers first
6943
+ const timer = setTimeout(() => {
6944
+ responseTimers.delete(msg.from);
6945
+ respond();
6933
6946
  }, Math.random() * jitterMs);
6934
6947
  responseTimers.set(msg.from, timer);
6935
6948
  return;