@naylence/runtime 0.3.5-test.936 → 0.3.5-test.938

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.
@@ -68,7 +68,7 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
68
68
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
69
69
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
70
70
  this.channel = new BroadcastChannel(this.channelName);
71
- logger.info('broadcast_channel_connector_created', {
71
+ logger.debug('broadcast_channel_connector_created', {
72
72
  channel: this.channelName,
73
73
  connector_id: this.connectorId,
74
74
  inbox_capacity: preferredCapacity,
@@ -149,7 +149,7 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
149
149
  // Setup visibility change monitoring
150
150
  this.visibilityChangeHandler = () => {
151
151
  const isHidden = document.hidden;
152
- logger.info('broadcast_channel_visibility_changed', {
152
+ logger.debug('broadcast_channel_visibility_changed', {
153
153
  channel: this.channelName,
154
154
  connector_id: this.connectorId,
155
155
  visibility: isHidden ? 'hidden' : 'visible',
@@ -179,7 +179,7 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
179
179
  document.addEventListener('visibilitychange', this.visibilityChangeHandler);
180
180
  this.visibilityChangeListenerRegistered = true;
181
181
  // Log initial state
182
- logger.info('broadcast_channel_initial_visibility', {
182
+ logger.debug('broadcast_channel_initial_visibility', {
183
183
  channel: this.channelName,
184
184
  connector_id: this.connectorId,
185
185
  visibility: document.hidden ? 'hidden' : 'visible',
@@ -229,7 +229,7 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
229
229
  return await this.inbox.dequeue();
230
230
  }
231
231
  async _transportClose(code, reason) {
232
- logger.info('broadcast_channel_transport_closing', {
232
+ logger.debug('broadcast_channel_transport_closing', {
233
233
  channel: this.channelName,
234
234
  connector_id: this.connectorId,
235
235
  code,
@@ -238,14 +238,14 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
238
238
  timestamp: new Date().toISOString(),
239
239
  });
240
240
  if (this.listenerRegistered) {
241
- logger.info('broadcast_channel_removing_listener', {
241
+ logger.debug('broadcast_channel_removing_listener', {
242
242
  channel: this.channelName,
243
243
  connector_id: this.connectorId,
244
244
  timestamp: new Date().toISOString(),
245
245
  });
246
246
  this.channel.removeEventListener('message', this.onMsg);
247
247
  this.listenerRegistered = false;
248
- logger.info('broadcast_channel_listener_removed', {
248
+ logger.debug('broadcast_channel_listener_removed', {
249
249
  channel: this.channelName,
250
250
  connector_id: this.connectorId,
251
251
  timestamp: new Date().toISOString(),
@@ -256,13 +256,13 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
256
256
  this.visibilityChangeListenerRegistered = false;
257
257
  this.visibilityChangeHandler = undefined;
258
258
  }
259
- logger.info('broadcast_channel_closing', {
259
+ logger.debug('broadcast_channel_closing', {
260
260
  channel: this.channelName,
261
261
  connector_id: this.connectorId,
262
262
  timestamp: new Date().toISOString(),
263
263
  });
264
264
  this.channel.close();
265
- logger.info('broadcast_channel_closed', {
265
+ logger.debug('broadcast_channel_closed', {
266
266
  channel: this.channelName,
267
267
  connector_id: this.connectorId,
268
268
  timestamp: new Date().toISOString(),
@@ -353,6 +353,28 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
353
353
  }
354
354
  return undefined;
355
355
  }
356
+ /**
357
+ * Override start() to check initial visibility state
358
+ */
359
+ async start(inboundHandler) {
360
+ await super.start(inboundHandler);
361
+ // After transitioning to STARTED, check if tab is already hidden
362
+ if (typeof document !== 'undefined' && document.hidden) {
363
+ logger.debug('broadcast_channel_start_in_hidden_tab', {
364
+ channel: this.channelName,
365
+ connector_id: this.connectorId,
366
+ timestamp: new Date().toISOString(),
367
+ });
368
+ // Immediately pause if tab is hidden at start time
369
+ await this.pause().catch((err) => {
370
+ logger.warning('broadcast_channel_initial_pause_failed', {
371
+ channel: this.channelName,
372
+ connector_id: this.connectorId,
373
+ error: err instanceof Error ? err.message : String(err),
374
+ });
375
+ });
376
+ }
377
+ }
356
378
  _trimSeenAcks(now) {
357
379
  while (this.seenAckOrder.length > 0) {
358
380
  const candidate = this.seenAckOrder[0];
@@ -109,6 +109,7 @@ export class UpstreamSessionManager extends TaskSpawner {
109
109
  this.lastHeartbeatAckTime = null;
110
110
  this.lastSeenEpoch = null;
111
111
  this.hadSuccessfulAttach = false;
112
+ this.lastConnectorState = null;
112
113
  this.connectEpoch = 0;
113
114
  const options = normalizeOptions(optionsInput);
114
115
  this.node = options.node;
@@ -533,15 +534,26 @@ export class UpstreamSessionManager extends TaskSpawner {
533
534
  if (stopEvt.isSet() || signal?.aborted) {
534
535
  break;
535
536
  }
537
+ const currentState = connector.state;
538
+ const previousState = this.lastConnectorState;
539
+ this.lastConnectorState = currentState;
536
540
  // Skip heartbeat if connector is paused (e.g., tab is hidden)
537
541
  // Keep ack time current so we don't timeout immediately after resuming
538
- if (connector.state === ConnectorState.PAUSED) {
542
+ if (currentState === ConnectorState.PAUSED) {
539
543
  logger.debug('skipping_heartbeat_connector_paused', {
540
- connector_state: connector.state,
544
+ connector_state: currentState,
541
545
  });
542
546
  this.lastHeartbeatAckTime = Date.now();
543
547
  continue;
544
548
  }
549
+ // Reset ack time if just resumed from pause (prevents immediate timeout)
550
+ if (previousState === ConnectorState.PAUSED && currentState === ConnectorState.STARTED) {
551
+ logger.debug('connector_just_resumed_resetting_ack_time', {
552
+ previous_state: previousState,
553
+ current_state: currentState,
554
+ });
555
+ this.lastHeartbeatAckTime = Date.now();
556
+ }
545
557
  const envelope = await this.makeHeartbeatEnvelope();
546
558
  logger.debug('sending_heartbeat', {
547
559
  hb_corr_id: envelope.corrId,
@@ -1,7 +1,7 @@
1
1
  // This file is auto-generated during build - do not edit manually
2
- // Generated from package.json version: 0.3.5-test.936
2
+ // Generated from package.json version: 0.3.5-test.938
3
3
  /**
4
4
  * The package version, injected at build time.
5
5
  * @internal
6
6
  */
7
- export const VERSION = '0.3.5-test.936';
7
+ export const VERSION = '0.3.5-test.938';
@@ -14,12 +14,12 @@ var fastify = require('fastify');
14
14
  var websocketPlugin = require('@fastify/websocket');
15
15
 
16
16
  // This file is auto-generated during build - do not edit manually
17
- // Generated from package.json version: 0.3.5-test.936
17
+ // Generated from package.json version: 0.3.5-test.938
18
18
  /**
19
19
  * The package version, injected at build time.
20
20
  * @internal
21
21
  */
22
- const VERSION = '0.3.5-test.936';
22
+ const VERSION = '0.3.5-test.938';
23
23
 
24
24
  /**
25
25
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -9584,7 +9584,7 @@ class BaseAsyncConnector extends TaskSpawner {
9584
9584
  });
9585
9585
  return;
9586
9586
  }
9587
- logger$$.info('connector_shutdown_starting', {
9587
+ logger$$.debug('connector_shutdown_starting', {
9588
9588
  connector_id: this._connectorFlowId,
9589
9589
  connector_type: this.constructor.name,
9590
9590
  code,
@@ -9614,19 +9614,19 @@ class BaseAsyncConnector extends TaskSpawner {
9614
9614
  this._sendPromiseResolve = undefined;
9615
9615
  }
9616
9616
  // Close transport
9617
- logger$$.info('connector_closing_transport', {
9617
+ logger$$.debug('connector_closing_transport', {
9618
9618
  connector_id: this._connectorFlowId,
9619
9619
  connector_type: this.constructor.name,
9620
9620
  timestamp: new Date().toISOString(),
9621
9621
  });
9622
9622
  await this._transportClose(code, reason);
9623
- logger$$.info('connector_transport_closed', {
9623
+ logger$$.debug('connector_transport_closed', {
9624
9624
  connector_id: this._connectorFlowId,
9625
9625
  connector_type: this.constructor.name,
9626
9626
  timestamp: new Date().toISOString(),
9627
9627
  });
9628
9628
  // Shutdown spawned tasks
9629
- logger$$.info('connector_shutting_down_tasks', {
9629
+ logger$$.debug('connector_shutting_down_tasks', {
9630
9630
  connector_id: this._connectorFlowId,
9631
9631
  connector_type: this.constructor.name,
9632
9632
  grace_period_ms: effectiveGracePeriod * 1000,
@@ -9638,7 +9638,7 @@ class BaseAsyncConnector extends TaskSpawner {
9638
9638
  gracePeriod: effectiveGracePeriod * 1000, // Convert to milliseconds
9639
9639
  joinTimeout: this._shutdownJoinTimeout,
9640
9640
  });
9641
- logger$$.info('connector_tasks_shutdown_complete', {
9641
+ logger$$.debug('connector_tasks_shutdown_complete', {
9642
9642
  connector_id: this._connectorFlowId,
9643
9643
  connector_type: this.constructor.name,
9644
9644
  timestamp: new Date().toISOString(),
@@ -9658,7 +9658,7 @@ class BaseAsyncConnector extends TaskSpawner {
9658
9658
  if (this._closeResolver) {
9659
9659
  this._closeResolver();
9660
9660
  }
9661
- logger$$.info('connector_shutdown_complete', {
9661
+ logger$$.debug('connector_shutdown_complete', {
9662
9662
  connector_id: this._connectorFlowId,
9663
9663
  connector_type: this.constructor.name,
9664
9664
  final_state: this._state,
@@ -9799,7 +9799,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9799
9799
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
9800
9800
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
9801
9801
  this.channel = new BroadcastChannel(this.channelName);
9802
- logger$_.info('broadcast_channel_connector_created', {
9802
+ logger$_.debug('broadcast_channel_connector_created', {
9803
9803
  channel: this.channelName,
9804
9804
  connector_id: this.connectorId,
9805
9805
  inbox_capacity: preferredCapacity,
@@ -9880,7 +9880,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9880
9880
  // Setup visibility change monitoring
9881
9881
  this.visibilityChangeHandler = () => {
9882
9882
  const isHidden = document.hidden;
9883
- logger$_.info('broadcast_channel_visibility_changed', {
9883
+ logger$_.debug('broadcast_channel_visibility_changed', {
9884
9884
  channel: this.channelName,
9885
9885
  connector_id: this.connectorId,
9886
9886
  visibility: isHidden ? 'hidden' : 'visible',
@@ -9910,7 +9910,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9910
9910
  document.addEventListener('visibilitychange', this.visibilityChangeHandler);
9911
9911
  this.visibilityChangeListenerRegistered = true;
9912
9912
  // Log initial state
9913
- logger$_.info('broadcast_channel_initial_visibility', {
9913
+ logger$_.debug('broadcast_channel_initial_visibility', {
9914
9914
  channel: this.channelName,
9915
9915
  connector_id: this.connectorId,
9916
9916
  visibility: document.hidden ? 'hidden' : 'visible',
@@ -9960,7 +9960,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9960
9960
  return await this.inbox.dequeue();
9961
9961
  }
9962
9962
  async _transportClose(code, reason) {
9963
- logger$_.info('broadcast_channel_transport_closing', {
9963
+ logger$_.debug('broadcast_channel_transport_closing', {
9964
9964
  channel: this.channelName,
9965
9965
  connector_id: this.connectorId,
9966
9966
  code,
@@ -9969,14 +9969,14 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9969
9969
  timestamp: new Date().toISOString(),
9970
9970
  });
9971
9971
  if (this.listenerRegistered) {
9972
- logger$_.info('broadcast_channel_removing_listener', {
9972
+ logger$_.debug('broadcast_channel_removing_listener', {
9973
9973
  channel: this.channelName,
9974
9974
  connector_id: this.connectorId,
9975
9975
  timestamp: new Date().toISOString(),
9976
9976
  });
9977
9977
  this.channel.removeEventListener('message', this.onMsg);
9978
9978
  this.listenerRegistered = false;
9979
- logger$_.info('broadcast_channel_listener_removed', {
9979
+ logger$_.debug('broadcast_channel_listener_removed', {
9980
9980
  channel: this.channelName,
9981
9981
  connector_id: this.connectorId,
9982
9982
  timestamp: new Date().toISOString(),
@@ -9987,13 +9987,13 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9987
9987
  this.visibilityChangeListenerRegistered = false;
9988
9988
  this.visibilityChangeHandler = undefined;
9989
9989
  }
9990
- logger$_.info('broadcast_channel_closing', {
9990
+ logger$_.debug('broadcast_channel_closing', {
9991
9991
  channel: this.channelName,
9992
9992
  connector_id: this.connectorId,
9993
9993
  timestamp: new Date().toISOString(),
9994
9994
  });
9995
9995
  this.channel.close();
9996
- logger$_.info('broadcast_channel_closed', {
9996
+ logger$_.debug('broadcast_channel_closed', {
9997
9997
  channel: this.channelName,
9998
9998
  connector_id: this.connectorId,
9999
9999
  timestamp: new Date().toISOString(),
@@ -10084,6 +10084,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10084
10084
  }
10085
10085
  return undefined;
10086
10086
  }
10087
+ /**
10088
+ * Override start() to check initial visibility state
10089
+ */
10090
+ async start(inboundHandler) {
10091
+ await super.start(inboundHandler);
10092
+ // After transitioning to STARTED, check if tab is already hidden
10093
+ if (typeof document !== 'undefined' && document.hidden) {
10094
+ logger$_.debug('broadcast_channel_start_in_hidden_tab', {
10095
+ channel: this.channelName,
10096
+ connector_id: this.connectorId,
10097
+ timestamp: new Date().toISOString(),
10098
+ });
10099
+ // Immediately pause if tab is hidden at start time
10100
+ await this.pause().catch((err) => {
10101
+ logger$_.warning('broadcast_channel_initial_pause_failed', {
10102
+ channel: this.channelName,
10103
+ connector_id: this.connectorId,
10104
+ error: err instanceof Error ? err.message : String(err),
10105
+ });
10106
+ });
10107
+ }
10108
+ }
10087
10109
  _trimSeenAcks(now) {
10088
10110
  while (this.seenAckOrder.length > 0) {
10089
10111
  const candidate = this.seenAckOrder[0];
@@ -10370,6 +10392,7 @@ class UpstreamSessionManager extends TaskSpawner {
10370
10392
  this.lastHeartbeatAckTime = null;
10371
10393
  this.lastSeenEpoch = null;
10372
10394
  this.hadSuccessfulAttach = false;
10395
+ this.lastConnectorState = null;
10373
10396
  this.connectEpoch = 0;
10374
10397
  const options = normalizeOptions$k(optionsInput);
10375
10398
  this.node = options.node;
@@ -10794,15 +10817,26 @@ class UpstreamSessionManager extends TaskSpawner {
10794
10817
  if (stopEvt.isSet() || signal?.aborted) {
10795
10818
  break;
10796
10819
  }
10820
+ const currentState = connector.state;
10821
+ const previousState = this.lastConnectorState;
10822
+ this.lastConnectorState = currentState;
10797
10823
  // Skip heartbeat if connector is paused (e.g., tab is hidden)
10798
10824
  // Keep ack time current so we don't timeout immediately after resuming
10799
- if (connector.state === core.ConnectorState.PAUSED) {
10825
+ if (currentState === core.ConnectorState.PAUSED) {
10800
10826
  logger$Z.debug('skipping_heartbeat_connector_paused', {
10801
- connector_state: connector.state,
10827
+ connector_state: currentState,
10802
10828
  });
10803
10829
  this.lastHeartbeatAckTime = Date.now();
10804
10830
  continue;
10805
10831
  }
10832
+ // Reset ack time if just resumed from pause (prevents immediate timeout)
10833
+ if (previousState === core.ConnectorState.PAUSED && currentState === core.ConnectorState.STARTED) {
10834
+ logger$Z.debug('connector_just_resumed_resetting_ack_time', {
10835
+ previous_state: previousState,
10836
+ current_state: currentState,
10837
+ });
10838
+ this.lastHeartbeatAckTime = Date.now();
10839
+ }
10806
10840
  const envelope = await this.makeHeartbeatEnvelope();
10807
10841
  logger$Z.debug('sending_heartbeat', {
10808
10842
  hb_corr_id: envelope.corrId,
@@ -13,12 +13,12 @@ import fastify from 'fastify';
13
13
  import websocketPlugin from '@fastify/websocket';
14
14
 
15
15
  // This file is auto-generated during build - do not edit manually
16
- // Generated from package.json version: 0.3.5-test.936
16
+ // Generated from package.json version: 0.3.5-test.938
17
17
  /**
18
18
  * The package version, injected at build time.
19
19
  * @internal
20
20
  */
21
- const VERSION = '0.3.5-test.936';
21
+ const VERSION = '0.3.5-test.938';
22
22
 
23
23
  /**
24
24
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -9583,7 +9583,7 @@ class BaseAsyncConnector extends TaskSpawner {
9583
9583
  });
9584
9584
  return;
9585
9585
  }
9586
- logger$$.info('connector_shutdown_starting', {
9586
+ logger$$.debug('connector_shutdown_starting', {
9587
9587
  connector_id: this._connectorFlowId,
9588
9588
  connector_type: this.constructor.name,
9589
9589
  code,
@@ -9613,19 +9613,19 @@ class BaseAsyncConnector extends TaskSpawner {
9613
9613
  this._sendPromiseResolve = undefined;
9614
9614
  }
9615
9615
  // Close transport
9616
- logger$$.info('connector_closing_transport', {
9616
+ logger$$.debug('connector_closing_transport', {
9617
9617
  connector_id: this._connectorFlowId,
9618
9618
  connector_type: this.constructor.name,
9619
9619
  timestamp: new Date().toISOString(),
9620
9620
  });
9621
9621
  await this._transportClose(code, reason);
9622
- logger$$.info('connector_transport_closed', {
9622
+ logger$$.debug('connector_transport_closed', {
9623
9623
  connector_id: this._connectorFlowId,
9624
9624
  connector_type: this.constructor.name,
9625
9625
  timestamp: new Date().toISOString(),
9626
9626
  });
9627
9627
  // Shutdown spawned tasks
9628
- logger$$.info('connector_shutting_down_tasks', {
9628
+ logger$$.debug('connector_shutting_down_tasks', {
9629
9629
  connector_id: this._connectorFlowId,
9630
9630
  connector_type: this.constructor.name,
9631
9631
  grace_period_ms: effectiveGracePeriod * 1000,
@@ -9637,7 +9637,7 @@ class BaseAsyncConnector extends TaskSpawner {
9637
9637
  gracePeriod: effectiveGracePeriod * 1000, // Convert to milliseconds
9638
9638
  joinTimeout: this._shutdownJoinTimeout,
9639
9639
  });
9640
- logger$$.info('connector_tasks_shutdown_complete', {
9640
+ logger$$.debug('connector_tasks_shutdown_complete', {
9641
9641
  connector_id: this._connectorFlowId,
9642
9642
  connector_type: this.constructor.name,
9643
9643
  timestamp: new Date().toISOString(),
@@ -9657,7 +9657,7 @@ class BaseAsyncConnector extends TaskSpawner {
9657
9657
  if (this._closeResolver) {
9658
9658
  this._closeResolver();
9659
9659
  }
9660
- logger$$.info('connector_shutdown_complete', {
9660
+ logger$$.debug('connector_shutdown_complete', {
9661
9661
  connector_id: this._connectorFlowId,
9662
9662
  connector_type: this.constructor.name,
9663
9663
  final_state: this._state,
@@ -9798,7 +9798,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9798
9798
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
9799
9799
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
9800
9800
  this.channel = new BroadcastChannel(this.channelName);
9801
- logger$_.info('broadcast_channel_connector_created', {
9801
+ logger$_.debug('broadcast_channel_connector_created', {
9802
9802
  channel: this.channelName,
9803
9803
  connector_id: this.connectorId,
9804
9804
  inbox_capacity: preferredCapacity,
@@ -9879,7 +9879,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9879
9879
  // Setup visibility change monitoring
9880
9880
  this.visibilityChangeHandler = () => {
9881
9881
  const isHidden = document.hidden;
9882
- logger$_.info('broadcast_channel_visibility_changed', {
9882
+ logger$_.debug('broadcast_channel_visibility_changed', {
9883
9883
  channel: this.channelName,
9884
9884
  connector_id: this.connectorId,
9885
9885
  visibility: isHidden ? 'hidden' : 'visible',
@@ -9909,7 +9909,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9909
9909
  document.addEventListener('visibilitychange', this.visibilityChangeHandler);
9910
9910
  this.visibilityChangeListenerRegistered = true;
9911
9911
  // Log initial state
9912
- logger$_.info('broadcast_channel_initial_visibility', {
9912
+ logger$_.debug('broadcast_channel_initial_visibility', {
9913
9913
  channel: this.channelName,
9914
9914
  connector_id: this.connectorId,
9915
9915
  visibility: document.hidden ? 'hidden' : 'visible',
@@ -9959,7 +9959,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9959
9959
  return await this.inbox.dequeue();
9960
9960
  }
9961
9961
  async _transportClose(code, reason) {
9962
- logger$_.info('broadcast_channel_transport_closing', {
9962
+ logger$_.debug('broadcast_channel_transport_closing', {
9963
9963
  channel: this.channelName,
9964
9964
  connector_id: this.connectorId,
9965
9965
  code,
@@ -9968,14 +9968,14 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9968
9968
  timestamp: new Date().toISOString(),
9969
9969
  });
9970
9970
  if (this.listenerRegistered) {
9971
- logger$_.info('broadcast_channel_removing_listener', {
9971
+ logger$_.debug('broadcast_channel_removing_listener', {
9972
9972
  channel: this.channelName,
9973
9973
  connector_id: this.connectorId,
9974
9974
  timestamp: new Date().toISOString(),
9975
9975
  });
9976
9976
  this.channel.removeEventListener('message', this.onMsg);
9977
9977
  this.listenerRegistered = false;
9978
- logger$_.info('broadcast_channel_listener_removed', {
9978
+ logger$_.debug('broadcast_channel_listener_removed', {
9979
9979
  channel: this.channelName,
9980
9980
  connector_id: this.connectorId,
9981
9981
  timestamp: new Date().toISOString(),
@@ -9986,13 +9986,13 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9986
9986
  this.visibilityChangeListenerRegistered = false;
9987
9987
  this.visibilityChangeHandler = undefined;
9988
9988
  }
9989
- logger$_.info('broadcast_channel_closing', {
9989
+ logger$_.debug('broadcast_channel_closing', {
9990
9990
  channel: this.channelName,
9991
9991
  connector_id: this.connectorId,
9992
9992
  timestamp: new Date().toISOString(),
9993
9993
  });
9994
9994
  this.channel.close();
9995
- logger$_.info('broadcast_channel_closed', {
9995
+ logger$_.debug('broadcast_channel_closed', {
9996
9996
  channel: this.channelName,
9997
9997
  connector_id: this.connectorId,
9998
9998
  timestamp: new Date().toISOString(),
@@ -10083,6 +10083,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10083
10083
  }
10084
10084
  return undefined;
10085
10085
  }
10086
+ /**
10087
+ * Override start() to check initial visibility state
10088
+ */
10089
+ async start(inboundHandler) {
10090
+ await super.start(inboundHandler);
10091
+ // After transitioning to STARTED, check if tab is already hidden
10092
+ if (typeof document !== 'undefined' && document.hidden) {
10093
+ logger$_.debug('broadcast_channel_start_in_hidden_tab', {
10094
+ channel: this.channelName,
10095
+ connector_id: this.connectorId,
10096
+ timestamp: new Date().toISOString(),
10097
+ });
10098
+ // Immediately pause if tab is hidden at start time
10099
+ await this.pause().catch((err) => {
10100
+ logger$_.warning('broadcast_channel_initial_pause_failed', {
10101
+ channel: this.channelName,
10102
+ connector_id: this.connectorId,
10103
+ error: err instanceof Error ? err.message : String(err),
10104
+ });
10105
+ });
10106
+ }
10107
+ }
10086
10108
  _trimSeenAcks(now) {
10087
10109
  while (this.seenAckOrder.length > 0) {
10088
10110
  const candidate = this.seenAckOrder[0];
@@ -10369,6 +10391,7 @@ class UpstreamSessionManager extends TaskSpawner {
10369
10391
  this.lastHeartbeatAckTime = null;
10370
10392
  this.lastSeenEpoch = null;
10371
10393
  this.hadSuccessfulAttach = false;
10394
+ this.lastConnectorState = null;
10372
10395
  this.connectEpoch = 0;
10373
10396
  const options = normalizeOptions$k(optionsInput);
10374
10397
  this.node = options.node;
@@ -10793,15 +10816,26 @@ class UpstreamSessionManager extends TaskSpawner {
10793
10816
  if (stopEvt.isSet() || signal?.aborted) {
10794
10817
  break;
10795
10818
  }
10819
+ const currentState = connector.state;
10820
+ const previousState = this.lastConnectorState;
10821
+ this.lastConnectorState = currentState;
10796
10822
  // Skip heartbeat if connector is paused (e.g., tab is hidden)
10797
10823
  // Keep ack time current so we don't timeout immediately after resuming
10798
- if (connector.state === ConnectorState.PAUSED) {
10824
+ if (currentState === ConnectorState.PAUSED) {
10799
10825
  logger$Z.debug('skipping_heartbeat_connector_paused', {
10800
- connector_state: connector.state,
10826
+ connector_state: currentState,
10801
10827
  });
10802
10828
  this.lastHeartbeatAckTime = Date.now();
10803
10829
  continue;
10804
10830
  }
10831
+ // Reset ack time if just resumed from pause (prevents immediate timeout)
10832
+ if (previousState === ConnectorState.PAUSED && currentState === ConnectorState.STARTED) {
10833
+ logger$Z.debug('connector_just_resumed_resetting_ack_time', {
10834
+ previous_state: previousState,
10835
+ current_state: currentState,
10836
+ });
10837
+ this.lastHeartbeatAckTime = Date.now();
10838
+ }
10805
10839
  const envelope = await this.makeHeartbeatEnvelope();
10806
10840
  logger$Z.debug('sending_heartbeat', {
10807
10841
  hb_corr_id: envelope.corrId,