@naylence/runtime 0.3.5-test.941 → 0.3.5-test.942

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.
@@ -98,12 +98,12 @@ installProcessEnvShim();
98
98
  // --- END ENV SHIM ---
99
99
 
100
100
  // This file is auto-generated during build - do not edit manually
101
- // Generated from package.json version: 0.3.5-test.941
101
+ // Generated from package.json version: 0.3.5-test.942
102
102
  /**
103
103
  * The package version, injected at build time.
104
104
  * @internal
105
105
  */
106
- const VERSION = '0.3.5-test.941';
106
+ const VERSION = '0.3.5-test.942';
107
107
 
108
108
  /**
109
109
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -10777,7 +10777,7 @@ class UpstreamSessionManager extends TaskSpawner {
10777
10777
  this.currentStopSubtasks = null;
10778
10778
  await Promise.allSettled(tasks.map((task) => task.promise));
10779
10779
  if (this.connector) {
10780
- logger$Z.info('upstream_stopping_old_connector', {
10780
+ logger$Z.debug('upstream_stopping_old_connector', {
10781
10781
  connect_epoch: this.connectEpoch,
10782
10782
  target_system_id: this.targetSystemId,
10783
10783
  timestamp: new Date().toISOString(),
@@ -10788,7 +10788,7 @@ class UpstreamSessionManager extends TaskSpawner {
10788
10788
  error: err instanceof Error ? err.message : String(err),
10789
10789
  });
10790
10790
  });
10791
- logger$Z.info('upstream_old_connector_stopped', {
10791
+ logger$Z.debug('upstream_old_connector_stopped', {
10792
10792
  connect_epoch: this.connectEpoch,
10793
10793
  target_system_id: this.targetSystemId,
10794
10794
  timestamp: new Date().toISOString(),
@@ -20332,6 +20332,7 @@ class InPageConnector extends BaseAsyncConnector {
20332
20332
  ensureBrowserEnvironment$2();
20333
20333
  super(baseConfig);
20334
20334
  this.listenerRegistered = false;
20335
+ this.visibilityChangeListenerRegistered = false;
20335
20336
  this.channelName =
20336
20337
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
20337
20338
  ? config.channelName.trim()
@@ -20419,6 +20420,92 @@ class InPageConnector extends BaseAsyncConnector {
20419
20420
  };
20420
20421
  getSharedBus$1().addEventListener(this.channelName, this.onMsg);
20421
20422
  this.listenerRegistered = true;
20423
+ // Setup visibility change monitoring
20424
+ this.visibilityChangeHandler = () => {
20425
+ const isHidden = document.hidden;
20426
+ logger$G.debug('inpage_visibility_changed', {
20427
+ channel: this.channelName,
20428
+ connector_id: this.connectorId,
20429
+ visibility: isHidden ? 'hidden' : 'visible',
20430
+ timestamp: new Date().toISOString(),
20431
+ });
20432
+ // Pause/resume connector based on visibility
20433
+ if (isHidden && this.state === core.ConnectorState.STARTED) {
20434
+ this.pause().catch((err) => {
20435
+ logger$G.warning('inpage_pause_failed', {
20436
+ channel: this.channelName,
20437
+ connector_id: this.connectorId,
20438
+ error: err instanceof Error ? err.message : String(err),
20439
+ });
20440
+ });
20441
+ }
20442
+ else if (!isHidden && this.state === core.ConnectorState.PAUSED) {
20443
+ this.resume().catch((err) => {
20444
+ logger$G.warning('inpage_resume_failed', {
20445
+ channel: this.channelName,
20446
+ connector_id: this.connectorId,
20447
+ error: err instanceof Error ? err.message : String(err),
20448
+ });
20449
+ });
20450
+ }
20451
+ };
20452
+ if (typeof document !== 'undefined') {
20453
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
20454
+ this.visibilityChangeListenerRegistered = true;
20455
+ // Track page lifecycle events to detect browser unload/discard
20456
+ if (typeof window !== 'undefined') {
20457
+ const lifecycleLogger = (event) => {
20458
+ logger$G.info('inpage_page_lifecycle', {
20459
+ channel: this.channelName,
20460
+ connector_id: this.connectorId,
20461
+ event_type: event.type,
20462
+ visibility_state: document.visibilityState,
20463
+ timestamp: new Date().toISOString(),
20464
+ });
20465
+ };
20466
+ window.addEventListener('beforeunload', lifecycleLogger);
20467
+ window.addEventListener('unload', lifecycleLogger);
20468
+ window.addEventListener('pagehide', lifecycleLogger);
20469
+ window.addEventListener('pageshow', lifecycleLogger);
20470
+ document.addEventListener('freeze', lifecycleLogger);
20471
+ document.addEventListener('resume', lifecycleLogger);
20472
+ }
20473
+ // Log initial state with detailed visibility info
20474
+ logger$G.debug('inpage_initial_visibility', {
20475
+ channel: this.channelName,
20476
+ connector_id: this.connectorId,
20477
+ visibility: document.hidden ? 'hidden' : 'visible',
20478
+ document_hidden: document.hidden,
20479
+ visibility_state: document.visibilityState,
20480
+ has_focus: document.hasFocus(),
20481
+ timestamp: new Date().toISOString(),
20482
+ });
20483
+ }
20484
+ }
20485
+ /**
20486
+ * Override start() to check initial visibility state
20487
+ */
20488
+ async start(inboundHandler) {
20489
+ await super.start(inboundHandler);
20490
+ // After transitioning to STARTED, check if tab is already hidden
20491
+ if (typeof document !== 'undefined' && document.hidden) {
20492
+ logger$G.debug('inpage_start_in_hidden_tab', {
20493
+ channel: this.channelName,
20494
+ connector_id: this.connectorId,
20495
+ document_hidden: document.hidden,
20496
+ visibility_state: document.visibilityState,
20497
+ has_focus: document.hasFocus(),
20498
+ timestamp: new Date().toISOString(),
20499
+ });
20500
+ // Immediately pause if tab is hidden at start time
20501
+ await this.pause().catch((err) => {
20502
+ logger$G.warning('inpage_initial_pause_failed', {
20503
+ channel: this.channelName,
20504
+ connector_id: this.connectorId,
20505
+ error: err instanceof Error ? err.message : String(err),
20506
+ });
20507
+ });
20508
+ }
20422
20509
  }
20423
20510
  // Allow listeners to feed envelopes directly into the in-page receive queue.
20424
20511
  async pushToReceive(rawOrEnvelope) {
@@ -20468,6 +20555,11 @@ class InPageConnector extends BaseAsyncConnector {
20468
20555
  getSharedBus$1().removeEventListener(this.channelName, this.onMsg);
20469
20556
  this.listenerRegistered = false;
20470
20557
  }
20558
+ if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
20559
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
20560
+ this.visibilityChangeListenerRegistered = false;
20561
+ this.visibilityChangeHandler = undefined;
20562
+ }
20471
20563
  const closeCode = typeof code === 'number' ? code : 1000;
20472
20564
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
20473
20565
  const shutdownError = new FameTransportClose(closeReason, closeCode);
@@ -96,12 +96,12 @@ installProcessEnvShim();
96
96
  // --- END ENV SHIM ---
97
97
 
98
98
  // This file is auto-generated during build - do not edit manually
99
- // Generated from package.json version: 0.3.5-test.941
99
+ // Generated from package.json version: 0.3.5-test.942
100
100
  /**
101
101
  * The package version, injected at build time.
102
102
  * @internal
103
103
  */
104
- const VERSION = '0.3.5-test.941';
104
+ const VERSION = '0.3.5-test.942';
105
105
 
106
106
  /**
107
107
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -10775,7 +10775,7 @@ class UpstreamSessionManager extends TaskSpawner {
10775
10775
  this.currentStopSubtasks = null;
10776
10776
  await Promise.allSettled(tasks.map((task) => task.promise));
10777
10777
  if (this.connector) {
10778
- logger$Z.info('upstream_stopping_old_connector', {
10778
+ logger$Z.debug('upstream_stopping_old_connector', {
10779
10779
  connect_epoch: this.connectEpoch,
10780
10780
  target_system_id: this.targetSystemId,
10781
10781
  timestamp: new Date().toISOString(),
@@ -10786,7 +10786,7 @@ class UpstreamSessionManager extends TaskSpawner {
10786
10786
  error: err instanceof Error ? err.message : String(err),
10787
10787
  });
10788
10788
  });
10789
- logger$Z.info('upstream_old_connector_stopped', {
10789
+ logger$Z.debug('upstream_old_connector_stopped', {
10790
10790
  connect_epoch: this.connectEpoch,
10791
10791
  target_system_id: this.targetSystemId,
10792
10792
  timestamp: new Date().toISOString(),
@@ -20330,6 +20330,7 @@ class InPageConnector extends BaseAsyncConnector {
20330
20330
  ensureBrowserEnvironment$2();
20331
20331
  super(baseConfig);
20332
20332
  this.listenerRegistered = false;
20333
+ this.visibilityChangeListenerRegistered = false;
20333
20334
  this.channelName =
20334
20335
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
20335
20336
  ? config.channelName.trim()
@@ -20417,6 +20418,92 @@ class InPageConnector extends BaseAsyncConnector {
20417
20418
  };
20418
20419
  getSharedBus$1().addEventListener(this.channelName, this.onMsg);
20419
20420
  this.listenerRegistered = true;
20421
+ // Setup visibility change monitoring
20422
+ this.visibilityChangeHandler = () => {
20423
+ const isHidden = document.hidden;
20424
+ logger$G.debug('inpage_visibility_changed', {
20425
+ channel: this.channelName,
20426
+ connector_id: this.connectorId,
20427
+ visibility: isHidden ? 'hidden' : 'visible',
20428
+ timestamp: new Date().toISOString(),
20429
+ });
20430
+ // Pause/resume connector based on visibility
20431
+ if (isHidden && this.state === ConnectorState.STARTED) {
20432
+ this.pause().catch((err) => {
20433
+ logger$G.warning('inpage_pause_failed', {
20434
+ channel: this.channelName,
20435
+ connector_id: this.connectorId,
20436
+ error: err instanceof Error ? err.message : String(err),
20437
+ });
20438
+ });
20439
+ }
20440
+ else if (!isHidden && this.state === ConnectorState.PAUSED) {
20441
+ this.resume().catch((err) => {
20442
+ logger$G.warning('inpage_resume_failed', {
20443
+ channel: this.channelName,
20444
+ connector_id: this.connectorId,
20445
+ error: err instanceof Error ? err.message : String(err),
20446
+ });
20447
+ });
20448
+ }
20449
+ };
20450
+ if (typeof document !== 'undefined') {
20451
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
20452
+ this.visibilityChangeListenerRegistered = true;
20453
+ // Track page lifecycle events to detect browser unload/discard
20454
+ if (typeof window !== 'undefined') {
20455
+ const lifecycleLogger = (event) => {
20456
+ logger$G.info('inpage_page_lifecycle', {
20457
+ channel: this.channelName,
20458
+ connector_id: this.connectorId,
20459
+ event_type: event.type,
20460
+ visibility_state: document.visibilityState,
20461
+ timestamp: new Date().toISOString(),
20462
+ });
20463
+ };
20464
+ window.addEventListener('beforeunload', lifecycleLogger);
20465
+ window.addEventListener('unload', lifecycleLogger);
20466
+ window.addEventListener('pagehide', lifecycleLogger);
20467
+ window.addEventListener('pageshow', lifecycleLogger);
20468
+ document.addEventListener('freeze', lifecycleLogger);
20469
+ document.addEventListener('resume', lifecycleLogger);
20470
+ }
20471
+ // Log initial state with detailed visibility info
20472
+ logger$G.debug('inpage_initial_visibility', {
20473
+ channel: this.channelName,
20474
+ connector_id: this.connectorId,
20475
+ visibility: document.hidden ? 'hidden' : 'visible',
20476
+ document_hidden: document.hidden,
20477
+ visibility_state: document.visibilityState,
20478
+ has_focus: document.hasFocus(),
20479
+ timestamp: new Date().toISOString(),
20480
+ });
20481
+ }
20482
+ }
20483
+ /**
20484
+ * Override start() to check initial visibility state
20485
+ */
20486
+ async start(inboundHandler) {
20487
+ await super.start(inboundHandler);
20488
+ // After transitioning to STARTED, check if tab is already hidden
20489
+ if (typeof document !== 'undefined' && document.hidden) {
20490
+ logger$G.debug('inpage_start_in_hidden_tab', {
20491
+ channel: this.channelName,
20492
+ connector_id: this.connectorId,
20493
+ document_hidden: document.hidden,
20494
+ visibility_state: document.visibilityState,
20495
+ has_focus: document.hasFocus(),
20496
+ timestamp: new Date().toISOString(),
20497
+ });
20498
+ // Immediately pause if tab is hidden at start time
20499
+ await this.pause().catch((err) => {
20500
+ logger$G.warning('inpage_initial_pause_failed', {
20501
+ channel: this.channelName,
20502
+ connector_id: this.connectorId,
20503
+ error: err instanceof Error ? err.message : String(err),
20504
+ });
20505
+ });
20506
+ }
20420
20507
  }
20421
20508
  // Allow listeners to feed envelopes directly into the in-page receive queue.
20422
20509
  async pushToReceive(rawOrEnvelope) {
@@ -20466,6 +20553,11 @@ class InPageConnector extends BaseAsyncConnector {
20466
20553
  getSharedBus$1().removeEventListener(this.channelName, this.onMsg);
20467
20554
  this.listenerRegistered = false;
20468
20555
  }
20556
+ if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
20557
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
20558
+ this.visibilityChangeListenerRegistered = false;
20559
+ this.visibilityChangeHandler = undefined;
20560
+ }
20469
20561
  const closeCode = typeof code === 'number' ? code : 1000;
20470
20562
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
20471
20563
  const shutdownError = new FameTransportClose(closeReason, closeCode);
@@ -9,6 +9,7 @@ const base_async_connector_js_1 = require("./base-async-connector.js");
9
9
  const errors_js_1 = require("../errors/errors.js");
10
10
  const logging_js_1 = require("../util/logging.js");
11
11
  const bounded_async_queue_js_1 = require("../util/bounded-async-queue.js");
12
+ const core_1 = require("@naylence/core");
12
13
  const logger = (0, logging_js_1.getLogger)('naylence.fame.connector.inpage_connector');
13
14
  exports.INPAGE_CONNECTOR_TYPE = 'inpage-connector';
14
15
  const DEFAULT_CHANNEL = 'naylence-fabric';
@@ -67,6 +68,7 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
67
68
  ensureBrowserEnvironment();
68
69
  super(baseConfig);
69
70
  this.listenerRegistered = false;
71
+ this.visibilityChangeListenerRegistered = false;
70
72
  this.channelName =
71
73
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
72
74
  ? config.channelName.trim()
@@ -154,6 +156,92 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
154
156
  };
155
157
  getSharedBus().addEventListener(this.channelName, this.onMsg);
156
158
  this.listenerRegistered = true;
159
+ // Setup visibility change monitoring
160
+ this.visibilityChangeHandler = () => {
161
+ const isHidden = document.hidden;
162
+ logger.debug('inpage_visibility_changed', {
163
+ channel: this.channelName,
164
+ connector_id: this.connectorId,
165
+ visibility: isHidden ? 'hidden' : 'visible',
166
+ timestamp: new Date().toISOString(),
167
+ });
168
+ // Pause/resume connector based on visibility
169
+ if (isHidden && this.state === core_1.ConnectorState.STARTED) {
170
+ this.pause().catch((err) => {
171
+ logger.warning('inpage_pause_failed', {
172
+ channel: this.channelName,
173
+ connector_id: this.connectorId,
174
+ error: err instanceof Error ? err.message : String(err),
175
+ });
176
+ });
177
+ }
178
+ else if (!isHidden && this.state === core_1.ConnectorState.PAUSED) {
179
+ this.resume().catch((err) => {
180
+ logger.warning('inpage_resume_failed', {
181
+ channel: this.channelName,
182
+ connector_id: this.connectorId,
183
+ error: err instanceof Error ? err.message : String(err),
184
+ });
185
+ });
186
+ }
187
+ };
188
+ if (typeof document !== 'undefined') {
189
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
190
+ this.visibilityChangeListenerRegistered = true;
191
+ // Track page lifecycle events to detect browser unload/discard
192
+ if (typeof window !== 'undefined') {
193
+ const lifecycleLogger = (event) => {
194
+ logger.info('inpage_page_lifecycle', {
195
+ channel: this.channelName,
196
+ connector_id: this.connectorId,
197
+ event_type: event.type,
198
+ visibility_state: document.visibilityState,
199
+ timestamp: new Date().toISOString(),
200
+ });
201
+ };
202
+ window.addEventListener('beforeunload', lifecycleLogger);
203
+ window.addEventListener('unload', lifecycleLogger);
204
+ window.addEventListener('pagehide', lifecycleLogger);
205
+ window.addEventListener('pageshow', lifecycleLogger);
206
+ document.addEventListener('freeze', lifecycleLogger);
207
+ document.addEventListener('resume', lifecycleLogger);
208
+ }
209
+ // Log initial state with detailed visibility info
210
+ logger.debug('inpage_initial_visibility', {
211
+ channel: this.channelName,
212
+ connector_id: this.connectorId,
213
+ visibility: document.hidden ? 'hidden' : 'visible',
214
+ document_hidden: document.hidden,
215
+ visibility_state: document.visibilityState,
216
+ has_focus: document.hasFocus(),
217
+ timestamp: new Date().toISOString(),
218
+ });
219
+ }
220
+ }
221
+ /**
222
+ * Override start() to check initial visibility state
223
+ */
224
+ async start(inboundHandler) {
225
+ await super.start(inboundHandler);
226
+ // After transitioning to STARTED, check if tab is already hidden
227
+ if (typeof document !== 'undefined' && document.hidden) {
228
+ logger.debug('inpage_start_in_hidden_tab', {
229
+ channel: this.channelName,
230
+ connector_id: this.connectorId,
231
+ document_hidden: document.hidden,
232
+ visibility_state: document.visibilityState,
233
+ has_focus: document.hasFocus(),
234
+ timestamp: new Date().toISOString(),
235
+ });
236
+ // Immediately pause if tab is hidden at start time
237
+ await this.pause().catch((err) => {
238
+ logger.warning('inpage_initial_pause_failed', {
239
+ channel: this.channelName,
240
+ connector_id: this.connectorId,
241
+ error: err instanceof Error ? err.message : String(err),
242
+ });
243
+ });
244
+ }
157
245
  }
158
246
  // Allow listeners to feed envelopes directly into the in-page receive queue.
159
247
  async pushToReceive(rawOrEnvelope) {
@@ -203,6 +291,11 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
203
291
  getSharedBus().removeEventListener(this.channelName, this.onMsg);
204
292
  this.listenerRegistered = false;
205
293
  }
294
+ if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
295
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
296
+ this.visibilityChangeListenerRegistered = false;
297
+ this.visibilityChangeHandler = undefined;
298
+ }
206
299
  const closeCode = typeof code === 'number' ? code : 1000;
207
300
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
208
301
  const shutdownError = new errors_js_1.FameTransportClose(closeReason, closeCode);
@@ -388,7 +388,7 @@ class UpstreamSessionManager extends task_spawner_js_1.TaskSpawner {
388
388
  this.currentStopSubtasks = null;
389
389
  await Promise.allSettled(tasks.map((task) => task.promise));
390
390
  if (this.connector) {
391
- logger.info('upstream_stopping_old_connector', {
391
+ logger.debug('upstream_stopping_old_connector', {
392
392
  connect_epoch: this.connectEpoch,
393
393
  target_system_id: this.targetSystemId,
394
394
  timestamp: new Date().toISOString(),
@@ -399,7 +399,7 @@ class UpstreamSessionManager extends task_spawner_js_1.TaskSpawner {
399
399
  error: err instanceof Error ? err.message : String(err),
400
400
  });
401
401
  });
402
- logger.info('upstream_old_connector_stopped', {
402
+ logger.debug('upstream_old_connector_stopped', {
403
403
  connect_epoch: this.connectEpoch,
404
404
  target_system_id: this.targetSystemId,
405
405
  timestamp: new Date().toISOString(),
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  // This file is auto-generated during build - do not edit manually
3
- // Generated from package.json version: 0.3.5-test.941
3
+ // Generated from package.json version: 0.3.5-test.942
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.VERSION = void 0;
6
6
  /**
7
7
  * The package version, injected at build time.
8
8
  * @internal
9
9
  */
10
- exports.VERSION = '0.3.5-test.941';
10
+ exports.VERSION = '0.3.5-test.942';
@@ -6,6 +6,7 @@ import { BaseAsyncConnector, } from './base-async-connector.js';
6
6
  import { FameTransportClose } from '../errors/errors.js';
7
7
  import { getLogger } from '../util/logging.js';
8
8
  import { BoundedAsyncQueue, QueueFullError, } from '../util/bounded-async-queue.js';
9
+ import { ConnectorState } from '@naylence/core';
9
10
  const logger = getLogger('naylence.fame.connector.inpage_connector');
10
11
  export const INPAGE_CONNECTOR_TYPE = 'inpage-connector';
11
12
  const DEFAULT_CHANNEL = 'naylence-fabric';
@@ -64,6 +65,7 @@ export class InPageConnector extends BaseAsyncConnector {
64
65
  ensureBrowserEnvironment();
65
66
  super(baseConfig);
66
67
  this.listenerRegistered = false;
68
+ this.visibilityChangeListenerRegistered = false;
67
69
  this.channelName =
68
70
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
69
71
  ? config.channelName.trim()
@@ -151,6 +153,92 @@ export class InPageConnector extends BaseAsyncConnector {
151
153
  };
152
154
  getSharedBus().addEventListener(this.channelName, this.onMsg);
153
155
  this.listenerRegistered = true;
156
+ // Setup visibility change monitoring
157
+ this.visibilityChangeHandler = () => {
158
+ const isHidden = document.hidden;
159
+ logger.debug('inpage_visibility_changed', {
160
+ channel: this.channelName,
161
+ connector_id: this.connectorId,
162
+ visibility: isHidden ? 'hidden' : 'visible',
163
+ timestamp: new Date().toISOString(),
164
+ });
165
+ // Pause/resume connector based on visibility
166
+ if (isHidden && this.state === ConnectorState.STARTED) {
167
+ this.pause().catch((err) => {
168
+ logger.warning('inpage_pause_failed', {
169
+ channel: this.channelName,
170
+ connector_id: this.connectorId,
171
+ error: err instanceof Error ? err.message : String(err),
172
+ });
173
+ });
174
+ }
175
+ else if (!isHidden && this.state === ConnectorState.PAUSED) {
176
+ this.resume().catch((err) => {
177
+ logger.warning('inpage_resume_failed', {
178
+ channel: this.channelName,
179
+ connector_id: this.connectorId,
180
+ error: err instanceof Error ? err.message : String(err),
181
+ });
182
+ });
183
+ }
184
+ };
185
+ if (typeof document !== 'undefined') {
186
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
187
+ this.visibilityChangeListenerRegistered = true;
188
+ // Track page lifecycle events to detect browser unload/discard
189
+ if (typeof window !== 'undefined') {
190
+ const lifecycleLogger = (event) => {
191
+ logger.info('inpage_page_lifecycle', {
192
+ channel: this.channelName,
193
+ connector_id: this.connectorId,
194
+ event_type: event.type,
195
+ visibility_state: document.visibilityState,
196
+ timestamp: new Date().toISOString(),
197
+ });
198
+ };
199
+ window.addEventListener('beforeunload', lifecycleLogger);
200
+ window.addEventListener('unload', lifecycleLogger);
201
+ window.addEventListener('pagehide', lifecycleLogger);
202
+ window.addEventListener('pageshow', lifecycleLogger);
203
+ document.addEventListener('freeze', lifecycleLogger);
204
+ document.addEventListener('resume', lifecycleLogger);
205
+ }
206
+ // Log initial state with detailed visibility info
207
+ logger.debug('inpage_initial_visibility', {
208
+ channel: this.channelName,
209
+ connector_id: this.connectorId,
210
+ visibility: document.hidden ? 'hidden' : 'visible',
211
+ document_hidden: document.hidden,
212
+ visibility_state: document.visibilityState,
213
+ has_focus: document.hasFocus(),
214
+ timestamp: new Date().toISOString(),
215
+ });
216
+ }
217
+ }
218
+ /**
219
+ * Override start() to check initial visibility state
220
+ */
221
+ async start(inboundHandler) {
222
+ await super.start(inboundHandler);
223
+ // After transitioning to STARTED, check if tab is already hidden
224
+ if (typeof document !== 'undefined' && document.hidden) {
225
+ logger.debug('inpage_start_in_hidden_tab', {
226
+ channel: this.channelName,
227
+ connector_id: this.connectorId,
228
+ document_hidden: document.hidden,
229
+ visibility_state: document.visibilityState,
230
+ has_focus: document.hasFocus(),
231
+ timestamp: new Date().toISOString(),
232
+ });
233
+ // Immediately pause if tab is hidden at start time
234
+ await this.pause().catch((err) => {
235
+ logger.warning('inpage_initial_pause_failed', {
236
+ channel: this.channelName,
237
+ connector_id: this.connectorId,
238
+ error: err instanceof Error ? err.message : String(err),
239
+ });
240
+ });
241
+ }
154
242
  }
155
243
  // Allow listeners to feed envelopes directly into the in-page receive queue.
156
244
  async pushToReceive(rawOrEnvelope) {
@@ -200,6 +288,11 @@ export class InPageConnector extends BaseAsyncConnector {
200
288
  getSharedBus().removeEventListener(this.channelName, this.onMsg);
201
289
  this.listenerRegistered = false;
202
290
  }
291
+ if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
292
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
293
+ this.visibilityChangeListenerRegistered = false;
294
+ this.visibilityChangeHandler = undefined;
295
+ }
203
296
  const closeCode = typeof code === 'number' ? code : 1000;
204
297
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
205
298
  const shutdownError = new FameTransportClose(closeReason, closeCode);
@@ -385,7 +385,7 @@ export class UpstreamSessionManager extends TaskSpawner {
385
385
  this.currentStopSubtasks = null;
386
386
  await Promise.allSettled(tasks.map((task) => task.promise));
387
387
  if (this.connector) {
388
- logger.info('upstream_stopping_old_connector', {
388
+ logger.debug('upstream_stopping_old_connector', {
389
389
  connect_epoch: this.connectEpoch,
390
390
  target_system_id: this.targetSystemId,
391
391
  timestamp: new Date().toISOString(),
@@ -396,7 +396,7 @@ export class UpstreamSessionManager extends TaskSpawner {
396
396
  error: err instanceof Error ? err.message : String(err),
397
397
  });
398
398
  });
399
- logger.info('upstream_old_connector_stopped', {
399
+ logger.debug('upstream_old_connector_stopped', {
400
400
  connect_epoch: this.connectEpoch,
401
401
  target_system_id: this.targetSystemId,
402
402
  timestamp: new Date().toISOString(),
@@ -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.941
2
+ // Generated from package.json version: 0.3.5-test.942
3
3
  /**
4
4
  * The package version, injected at build time.
5
5
  * @internal
6
6
  */
7
- export const VERSION = '0.3.5-test.941';
7
+ export const VERSION = '0.3.5-test.942';
@@ -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.941
17
+ // Generated from package.json version: 0.3.5-test.942
18
18
  /**
19
19
  * The package version, injected at build time.
20
20
  * @internal
21
21
  */
22
- const VERSION = '0.3.5-test.941';
22
+ const VERSION = '0.3.5-test.942';
23
23
 
24
24
  /**
25
25
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -10693,7 +10693,7 @@ class UpstreamSessionManager extends TaskSpawner {
10693
10693
  this.currentStopSubtasks = null;
10694
10694
  await Promise.allSettled(tasks.map((task) => task.promise));
10695
10695
  if (this.connector) {
10696
- logger$Z.info('upstream_stopping_old_connector', {
10696
+ logger$Z.debug('upstream_stopping_old_connector', {
10697
10697
  connect_epoch: this.connectEpoch,
10698
10698
  target_system_id: this.targetSystemId,
10699
10699
  timestamp: new Date().toISOString(),
@@ -10704,7 +10704,7 @@ class UpstreamSessionManager extends TaskSpawner {
10704
10704
  error: err instanceof Error ? err.message : String(err),
10705
10705
  });
10706
10706
  });
10707
- logger$Z.info('upstream_old_connector_stopped', {
10707
+ logger$Z.debug('upstream_old_connector_stopped', {
10708
10708
  connect_epoch: this.connectEpoch,
10709
10709
  target_system_id: this.targetSystemId,
10710
10710
  timestamp: new Date().toISOString(),
@@ -20248,6 +20248,7 @@ class InPageConnector extends BaseAsyncConnector {
20248
20248
  ensureBrowserEnvironment$2();
20249
20249
  super(baseConfig);
20250
20250
  this.listenerRegistered = false;
20251
+ this.visibilityChangeListenerRegistered = false;
20251
20252
  this.channelName =
20252
20253
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
20253
20254
  ? config.channelName.trim()
@@ -20335,6 +20336,92 @@ class InPageConnector extends BaseAsyncConnector {
20335
20336
  };
20336
20337
  getSharedBus$1().addEventListener(this.channelName, this.onMsg);
20337
20338
  this.listenerRegistered = true;
20339
+ // Setup visibility change monitoring
20340
+ this.visibilityChangeHandler = () => {
20341
+ const isHidden = document.hidden;
20342
+ logger$G.debug('inpage_visibility_changed', {
20343
+ channel: this.channelName,
20344
+ connector_id: this.connectorId,
20345
+ visibility: isHidden ? 'hidden' : 'visible',
20346
+ timestamp: new Date().toISOString(),
20347
+ });
20348
+ // Pause/resume connector based on visibility
20349
+ if (isHidden && this.state === core.ConnectorState.STARTED) {
20350
+ this.pause().catch((err) => {
20351
+ logger$G.warning('inpage_pause_failed', {
20352
+ channel: this.channelName,
20353
+ connector_id: this.connectorId,
20354
+ error: err instanceof Error ? err.message : String(err),
20355
+ });
20356
+ });
20357
+ }
20358
+ else if (!isHidden && this.state === core.ConnectorState.PAUSED) {
20359
+ this.resume().catch((err) => {
20360
+ logger$G.warning('inpage_resume_failed', {
20361
+ channel: this.channelName,
20362
+ connector_id: this.connectorId,
20363
+ error: err instanceof Error ? err.message : String(err),
20364
+ });
20365
+ });
20366
+ }
20367
+ };
20368
+ if (typeof document !== 'undefined') {
20369
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
20370
+ this.visibilityChangeListenerRegistered = true;
20371
+ // Track page lifecycle events to detect browser unload/discard
20372
+ if (typeof window !== 'undefined') {
20373
+ const lifecycleLogger = (event) => {
20374
+ logger$G.info('inpage_page_lifecycle', {
20375
+ channel: this.channelName,
20376
+ connector_id: this.connectorId,
20377
+ event_type: event.type,
20378
+ visibility_state: document.visibilityState,
20379
+ timestamp: new Date().toISOString(),
20380
+ });
20381
+ };
20382
+ window.addEventListener('beforeunload', lifecycleLogger);
20383
+ window.addEventListener('unload', lifecycleLogger);
20384
+ window.addEventListener('pagehide', lifecycleLogger);
20385
+ window.addEventListener('pageshow', lifecycleLogger);
20386
+ document.addEventListener('freeze', lifecycleLogger);
20387
+ document.addEventListener('resume', lifecycleLogger);
20388
+ }
20389
+ // Log initial state with detailed visibility info
20390
+ logger$G.debug('inpage_initial_visibility', {
20391
+ channel: this.channelName,
20392
+ connector_id: this.connectorId,
20393
+ visibility: document.hidden ? 'hidden' : 'visible',
20394
+ document_hidden: document.hidden,
20395
+ visibility_state: document.visibilityState,
20396
+ has_focus: document.hasFocus(),
20397
+ timestamp: new Date().toISOString(),
20398
+ });
20399
+ }
20400
+ }
20401
+ /**
20402
+ * Override start() to check initial visibility state
20403
+ */
20404
+ async start(inboundHandler) {
20405
+ await super.start(inboundHandler);
20406
+ // After transitioning to STARTED, check if tab is already hidden
20407
+ if (typeof document !== 'undefined' && document.hidden) {
20408
+ logger$G.debug('inpage_start_in_hidden_tab', {
20409
+ channel: this.channelName,
20410
+ connector_id: this.connectorId,
20411
+ document_hidden: document.hidden,
20412
+ visibility_state: document.visibilityState,
20413
+ has_focus: document.hasFocus(),
20414
+ timestamp: new Date().toISOString(),
20415
+ });
20416
+ // Immediately pause if tab is hidden at start time
20417
+ await this.pause().catch((err) => {
20418
+ logger$G.warning('inpage_initial_pause_failed', {
20419
+ channel: this.channelName,
20420
+ connector_id: this.connectorId,
20421
+ error: err instanceof Error ? err.message : String(err),
20422
+ });
20423
+ });
20424
+ }
20338
20425
  }
20339
20426
  // Allow listeners to feed envelopes directly into the in-page receive queue.
20340
20427
  async pushToReceive(rawOrEnvelope) {
@@ -20384,6 +20471,11 @@ class InPageConnector extends BaseAsyncConnector {
20384
20471
  getSharedBus$1().removeEventListener(this.channelName, this.onMsg);
20385
20472
  this.listenerRegistered = false;
20386
20473
  }
20474
+ if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
20475
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
20476
+ this.visibilityChangeListenerRegistered = false;
20477
+ this.visibilityChangeHandler = undefined;
20478
+ }
20387
20479
  const closeCode = typeof code === 'number' ? code : 1000;
20388
20480
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
20389
20481
  const shutdownError = new FameTransportClose(closeReason, closeCode);
@@ -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.941
16
+ // Generated from package.json version: 0.3.5-test.942
17
17
  /**
18
18
  * The package version, injected at build time.
19
19
  * @internal
20
20
  */
21
- const VERSION = '0.3.5-test.941';
21
+ const VERSION = '0.3.5-test.942';
22
22
 
23
23
  /**
24
24
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -10692,7 +10692,7 @@ class UpstreamSessionManager extends TaskSpawner {
10692
10692
  this.currentStopSubtasks = null;
10693
10693
  await Promise.allSettled(tasks.map((task) => task.promise));
10694
10694
  if (this.connector) {
10695
- logger$Z.info('upstream_stopping_old_connector', {
10695
+ logger$Z.debug('upstream_stopping_old_connector', {
10696
10696
  connect_epoch: this.connectEpoch,
10697
10697
  target_system_id: this.targetSystemId,
10698
10698
  timestamp: new Date().toISOString(),
@@ -10703,7 +10703,7 @@ class UpstreamSessionManager extends TaskSpawner {
10703
10703
  error: err instanceof Error ? err.message : String(err),
10704
10704
  });
10705
10705
  });
10706
- logger$Z.info('upstream_old_connector_stopped', {
10706
+ logger$Z.debug('upstream_old_connector_stopped', {
10707
10707
  connect_epoch: this.connectEpoch,
10708
10708
  target_system_id: this.targetSystemId,
10709
10709
  timestamp: new Date().toISOString(),
@@ -20247,6 +20247,7 @@ class InPageConnector extends BaseAsyncConnector {
20247
20247
  ensureBrowserEnvironment$2();
20248
20248
  super(baseConfig);
20249
20249
  this.listenerRegistered = false;
20250
+ this.visibilityChangeListenerRegistered = false;
20250
20251
  this.channelName =
20251
20252
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
20252
20253
  ? config.channelName.trim()
@@ -20334,6 +20335,92 @@ class InPageConnector extends BaseAsyncConnector {
20334
20335
  };
20335
20336
  getSharedBus$1().addEventListener(this.channelName, this.onMsg);
20336
20337
  this.listenerRegistered = true;
20338
+ // Setup visibility change monitoring
20339
+ this.visibilityChangeHandler = () => {
20340
+ const isHidden = document.hidden;
20341
+ logger$G.debug('inpage_visibility_changed', {
20342
+ channel: this.channelName,
20343
+ connector_id: this.connectorId,
20344
+ visibility: isHidden ? 'hidden' : 'visible',
20345
+ timestamp: new Date().toISOString(),
20346
+ });
20347
+ // Pause/resume connector based on visibility
20348
+ if (isHidden && this.state === ConnectorState.STARTED) {
20349
+ this.pause().catch((err) => {
20350
+ logger$G.warning('inpage_pause_failed', {
20351
+ channel: this.channelName,
20352
+ connector_id: this.connectorId,
20353
+ error: err instanceof Error ? err.message : String(err),
20354
+ });
20355
+ });
20356
+ }
20357
+ else if (!isHidden && this.state === ConnectorState.PAUSED) {
20358
+ this.resume().catch((err) => {
20359
+ logger$G.warning('inpage_resume_failed', {
20360
+ channel: this.channelName,
20361
+ connector_id: this.connectorId,
20362
+ error: err instanceof Error ? err.message : String(err),
20363
+ });
20364
+ });
20365
+ }
20366
+ };
20367
+ if (typeof document !== 'undefined') {
20368
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
20369
+ this.visibilityChangeListenerRegistered = true;
20370
+ // Track page lifecycle events to detect browser unload/discard
20371
+ if (typeof window !== 'undefined') {
20372
+ const lifecycleLogger = (event) => {
20373
+ logger$G.info('inpage_page_lifecycle', {
20374
+ channel: this.channelName,
20375
+ connector_id: this.connectorId,
20376
+ event_type: event.type,
20377
+ visibility_state: document.visibilityState,
20378
+ timestamp: new Date().toISOString(),
20379
+ });
20380
+ };
20381
+ window.addEventListener('beforeunload', lifecycleLogger);
20382
+ window.addEventListener('unload', lifecycleLogger);
20383
+ window.addEventListener('pagehide', lifecycleLogger);
20384
+ window.addEventListener('pageshow', lifecycleLogger);
20385
+ document.addEventListener('freeze', lifecycleLogger);
20386
+ document.addEventListener('resume', lifecycleLogger);
20387
+ }
20388
+ // Log initial state with detailed visibility info
20389
+ logger$G.debug('inpage_initial_visibility', {
20390
+ channel: this.channelName,
20391
+ connector_id: this.connectorId,
20392
+ visibility: document.hidden ? 'hidden' : 'visible',
20393
+ document_hidden: document.hidden,
20394
+ visibility_state: document.visibilityState,
20395
+ has_focus: document.hasFocus(),
20396
+ timestamp: new Date().toISOString(),
20397
+ });
20398
+ }
20399
+ }
20400
+ /**
20401
+ * Override start() to check initial visibility state
20402
+ */
20403
+ async start(inboundHandler) {
20404
+ await super.start(inboundHandler);
20405
+ // After transitioning to STARTED, check if tab is already hidden
20406
+ if (typeof document !== 'undefined' && document.hidden) {
20407
+ logger$G.debug('inpage_start_in_hidden_tab', {
20408
+ channel: this.channelName,
20409
+ connector_id: this.connectorId,
20410
+ document_hidden: document.hidden,
20411
+ visibility_state: document.visibilityState,
20412
+ has_focus: document.hasFocus(),
20413
+ timestamp: new Date().toISOString(),
20414
+ });
20415
+ // Immediately pause if tab is hidden at start time
20416
+ await this.pause().catch((err) => {
20417
+ logger$G.warning('inpage_initial_pause_failed', {
20418
+ channel: this.channelName,
20419
+ connector_id: this.connectorId,
20420
+ error: err instanceof Error ? err.message : String(err),
20421
+ });
20422
+ });
20423
+ }
20337
20424
  }
20338
20425
  // Allow listeners to feed envelopes directly into the in-page receive queue.
20339
20426
  async pushToReceive(rawOrEnvelope) {
@@ -20383,6 +20470,11 @@ class InPageConnector extends BaseAsyncConnector {
20383
20470
  getSharedBus$1().removeEventListener(this.channelName, this.onMsg);
20384
20471
  this.listenerRegistered = false;
20385
20472
  }
20473
+ if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
20474
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
20475
+ this.visibilityChangeListenerRegistered = false;
20476
+ this.visibilityChangeHandler = undefined;
20477
+ }
20386
20478
  const closeCode = typeof code === 'number' ? code : 1000;
20387
20479
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
20388
20480
  const shutdownError = new FameTransportClose(closeReason, closeCode);
@@ -5478,12 +5478,12 @@ for (const [name, config] of Object.entries(SQLITE_PROFILES)) {
5478
5478
  }
5479
5479
 
5480
5480
  // This file is auto-generated during build - do not edit manually
5481
- // Generated from package.json version: 0.3.5-test.941
5481
+ // Generated from package.json version: 0.3.5-test.942
5482
5482
  /**
5483
5483
  * The package version, injected at build time.
5484
5484
  * @internal
5485
5485
  */
5486
- const VERSION = '0.3.5-test.941';
5486
+ const VERSION = '0.3.5-test.942';
5487
5487
 
5488
5488
  /**
5489
5489
  * Fame errors module - Fame protocol specific error classes
@@ -12385,7 +12385,7 @@ class UpstreamSessionManager extends TaskSpawner {
12385
12385
  this.currentStopSubtasks = null;
12386
12386
  await Promise.allSettled(tasks.map((task) => task.promise));
12387
12387
  if (this.connector) {
12388
- logger$$.info('upstream_stopping_old_connector', {
12388
+ logger$$.debug('upstream_stopping_old_connector', {
12389
12389
  connect_epoch: this.connectEpoch,
12390
12390
  target_system_id: this.targetSystemId,
12391
12391
  timestamp: new Date().toISOString(),
@@ -12396,7 +12396,7 @@ class UpstreamSessionManager extends TaskSpawner {
12396
12396
  error: err instanceof Error ? err.message : String(err),
12397
12397
  });
12398
12398
  });
12399
- logger$$.info('upstream_old_connector_stopped', {
12399
+ logger$$.debug('upstream_old_connector_stopped', {
12400
12400
  connect_epoch: this.connectEpoch,
12401
12401
  target_system_id: this.targetSystemId,
12402
12402
  timestamp: new Date().toISOString(),
@@ -21426,6 +21426,7 @@ class InPageConnector extends BaseAsyncConnector {
21426
21426
  ensureBrowserEnvironment$2();
21427
21427
  super(baseConfig);
21428
21428
  this.listenerRegistered = false;
21429
+ this.visibilityChangeListenerRegistered = false;
21429
21430
  this.channelName =
21430
21431
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
21431
21432
  ? config.channelName.trim()
@@ -21513,6 +21514,92 @@ class InPageConnector extends BaseAsyncConnector {
21513
21514
  };
21514
21515
  getSharedBus$1().addEventListener(this.channelName, this.onMsg);
21515
21516
  this.listenerRegistered = true;
21517
+ // Setup visibility change monitoring
21518
+ this.visibilityChangeHandler = () => {
21519
+ const isHidden = document.hidden;
21520
+ logger$J.debug('inpage_visibility_changed', {
21521
+ channel: this.channelName,
21522
+ connector_id: this.connectorId,
21523
+ visibility: isHidden ? 'hidden' : 'visible',
21524
+ timestamp: new Date().toISOString(),
21525
+ });
21526
+ // Pause/resume connector based on visibility
21527
+ if (isHidden && this.state === core.ConnectorState.STARTED) {
21528
+ this.pause().catch((err) => {
21529
+ logger$J.warning('inpage_pause_failed', {
21530
+ channel: this.channelName,
21531
+ connector_id: this.connectorId,
21532
+ error: err instanceof Error ? err.message : String(err),
21533
+ });
21534
+ });
21535
+ }
21536
+ else if (!isHidden && this.state === core.ConnectorState.PAUSED) {
21537
+ this.resume().catch((err) => {
21538
+ logger$J.warning('inpage_resume_failed', {
21539
+ channel: this.channelName,
21540
+ connector_id: this.connectorId,
21541
+ error: err instanceof Error ? err.message : String(err),
21542
+ });
21543
+ });
21544
+ }
21545
+ };
21546
+ if (typeof document !== 'undefined') {
21547
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
21548
+ this.visibilityChangeListenerRegistered = true;
21549
+ // Track page lifecycle events to detect browser unload/discard
21550
+ if (typeof window !== 'undefined') {
21551
+ const lifecycleLogger = (event) => {
21552
+ logger$J.info('inpage_page_lifecycle', {
21553
+ channel: this.channelName,
21554
+ connector_id: this.connectorId,
21555
+ event_type: event.type,
21556
+ visibility_state: document.visibilityState,
21557
+ timestamp: new Date().toISOString(),
21558
+ });
21559
+ };
21560
+ window.addEventListener('beforeunload', lifecycleLogger);
21561
+ window.addEventListener('unload', lifecycleLogger);
21562
+ window.addEventListener('pagehide', lifecycleLogger);
21563
+ window.addEventListener('pageshow', lifecycleLogger);
21564
+ document.addEventListener('freeze', lifecycleLogger);
21565
+ document.addEventListener('resume', lifecycleLogger);
21566
+ }
21567
+ // Log initial state with detailed visibility info
21568
+ logger$J.debug('inpage_initial_visibility', {
21569
+ channel: this.channelName,
21570
+ connector_id: this.connectorId,
21571
+ visibility: document.hidden ? 'hidden' : 'visible',
21572
+ document_hidden: document.hidden,
21573
+ visibility_state: document.visibilityState,
21574
+ has_focus: document.hasFocus(),
21575
+ timestamp: new Date().toISOString(),
21576
+ });
21577
+ }
21578
+ }
21579
+ /**
21580
+ * Override start() to check initial visibility state
21581
+ */
21582
+ async start(inboundHandler) {
21583
+ await super.start(inboundHandler);
21584
+ // After transitioning to STARTED, check if tab is already hidden
21585
+ if (typeof document !== 'undefined' && document.hidden) {
21586
+ logger$J.debug('inpage_start_in_hidden_tab', {
21587
+ channel: this.channelName,
21588
+ connector_id: this.connectorId,
21589
+ document_hidden: document.hidden,
21590
+ visibility_state: document.visibilityState,
21591
+ has_focus: document.hasFocus(),
21592
+ timestamp: new Date().toISOString(),
21593
+ });
21594
+ // Immediately pause if tab is hidden at start time
21595
+ await this.pause().catch((err) => {
21596
+ logger$J.warning('inpage_initial_pause_failed', {
21597
+ channel: this.channelName,
21598
+ connector_id: this.connectorId,
21599
+ error: err instanceof Error ? err.message : String(err),
21600
+ });
21601
+ });
21602
+ }
21516
21603
  }
21517
21604
  // Allow listeners to feed envelopes directly into the in-page receive queue.
21518
21605
  async pushToReceive(rawOrEnvelope) {
@@ -21562,6 +21649,11 @@ class InPageConnector extends BaseAsyncConnector {
21562
21649
  getSharedBus$1().removeEventListener(this.channelName, this.onMsg);
21563
21650
  this.listenerRegistered = false;
21564
21651
  }
21652
+ if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
21653
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
21654
+ this.visibilityChangeListenerRegistered = false;
21655
+ this.visibilityChangeHandler = undefined;
21656
+ }
21565
21657
  const closeCode = typeof code === 'number' ? code : 1000;
21566
21658
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
21567
21659
  const shutdownError = new FameTransportClose(closeReason, closeCode);
@@ -5477,12 +5477,12 @@ for (const [name, config] of Object.entries(SQLITE_PROFILES)) {
5477
5477
  }
5478
5478
 
5479
5479
  // This file is auto-generated during build - do not edit manually
5480
- // Generated from package.json version: 0.3.5-test.941
5480
+ // Generated from package.json version: 0.3.5-test.942
5481
5481
  /**
5482
5482
  * The package version, injected at build time.
5483
5483
  * @internal
5484
5484
  */
5485
- const VERSION = '0.3.5-test.941';
5485
+ const VERSION = '0.3.5-test.942';
5486
5486
 
5487
5487
  /**
5488
5488
  * Fame errors module - Fame protocol specific error classes
@@ -12384,7 +12384,7 @@ class UpstreamSessionManager extends TaskSpawner {
12384
12384
  this.currentStopSubtasks = null;
12385
12385
  await Promise.allSettled(tasks.map((task) => task.promise));
12386
12386
  if (this.connector) {
12387
- logger$$.info('upstream_stopping_old_connector', {
12387
+ logger$$.debug('upstream_stopping_old_connector', {
12388
12388
  connect_epoch: this.connectEpoch,
12389
12389
  target_system_id: this.targetSystemId,
12390
12390
  timestamp: new Date().toISOString(),
@@ -12395,7 +12395,7 @@ class UpstreamSessionManager extends TaskSpawner {
12395
12395
  error: err instanceof Error ? err.message : String(err),
12396
12396
  });
12397
12397
  });
12398
- logger$$.info('upstream_old_connector_stopped', {
12398
+ logger$$.debug('upstream_old_connector_stopped', {
12399
12399
  connect_epoch: this.connectEpoch,
12400
12400
  target_system_id: this.targetSystemId,
12401
12401
  timestamp: new Date().toISOString(),
@@ -21425,6 +21425,7 @@ class InPageConnector extends BaseAsyncConnector {
21425
21425
  ensureBrowserEnvironment$2();
21426
21426
  super(baseConfig);
21427
21427
  this.listenerRegistered = false;
21428
+ this.visibilityChangeListenerRegistered = false;
21428
21429
  this.channelName =
21429
21430
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
21430
21431
  ? config.channelName.trim()
@@ -21512,6 +21513,92 @@ class InPageConnector extends BaseAsyncConnector {
21512
21513
  };
21513
21514
  getSharedBus$1().addEventListener(this.channelName, this.onMsg);
21514
21515
  this.listenerRegistered = true;
21516
+ // Setup visibility change monitoring
21517
+ this.visibilityChangeHandler = () => {
21518
+ const isHidden = document.hidden;
21519
+ logger$J.debug('inpage_visibility_changed', {
21520
+ channel: this.channelName,
21521
+ connector_id: this.connectorId,
21522
+ visibility: isHidden ? 'hidden' : 'visible',
21523
+ timestamp: new Date().toISOString(),
21524
+ });
21525
+ // Pause/resume connector based on visibility
21526
+ if (isHidden && this.state === ConnectorState.STARTED) {
21527
+ this.pause().catch((err) => {
21528
+ logger$J.warning('inpage_pause_failed', {
21529
+ channel: this.channelName,
21530
+ connector_id: this.connectorId,
21531
+ error: err instanceof Error ? err.message : String(err),
21532
+ });
21533
+ });
21534
+ }
21535
+ else if (!isHidden && this.state === ConnectorState.PAUSED) {
21536
+ this.resume().catch((err) => {
21537
+ logger$J.warning('inpage_resume_failed', {
21538
+ channel: this.channelName,
21539
+ connector_id: this.connectorId,
21540
+ error: err instanceof Error ? err.message : String(err),
21541
+ });
21542
+ });
21543
+ }
21544
+ };
21545
+ if (typeof document !== 'undefined') {
21546
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
21547
+ this.visibilityChangeListenerRegistered = true;
21548
+ // Track page lifecycle events to detect browser unload/discard
21549
+ if (typeof window !== 'undefined') {
21550
+ const lifecycleLogger = (event) => {
21551
+ logger$J.info('inpage_page_lifecycle', {
21552
+ channel: this.channelName,
21553
+ connector_id: this.connectorId,
21554
+ event_type: event.type,
21555
+ visibility_state: document.visibilityState,
21556
+ timestamp: new Date().toISOString(),
21557
+ });
21558
+ };
21559
+ window.addEventListener('beforeunload', lifecycleLogger);
21560
+ window.addEventListener('unload', lifecycleLogger);
21561
+ window.addEventListener('pagehide', lifecycleLogger);
21562
+ window.addEventListener('pageshow', lifecycleLogger);
21563
+ document.addEventListener('freeze', lifecycleLogger);
21564
+ document.addEventListener('resume', lifecycleLogger);
21565
+ }
21566
+ // Log initial state with detailed visibility info
21567
+ logger$J.debug('inpage_initial_visibility', {
21568
+ channel: this.channelName,
21569
+ connector_id: this.connectorId,
21570
+ visibility: document.hidden ? 'hidden' : 'visible',
21571
+ document_hidden: document.hidden,
21572
+ visibility_state: document.visibilityState,
21573
+ has_focus: document.hasFocus(),
21574
+ timestamp: new Date().toISOString(),
21575
+ });
21576
+ }
21577
+ }
21578
+ /**
21579
+ * Override start() to check initial visibility state
21580
+ */
21581
+ async start(inboundHandler) {
21582
+ await super.start(inboundHandler);
21583
+ // After transitioning to STARTED, check if tab is already hidden
21584
+ if (typeof document !== 'undefined' && document.hidden) {
21585
+ logger$J.debug('inpage_start_in_hidden_tab', {
21586
+ channel: this.channelName,
21587
+ connector_id: this.connectorId,
21588
+ document_hidden: document.hidden,
21589
+ visibility_state: document.visibilityState,
21590
+ has_focus: document.hasFocus(),
21591
+ timestamp: new Date().toISOString(),
21592
+ });
21593
+ // Immediately pause if tab is hidden at start time
21594
+ await this.pause().catch((err) => {
21595
+ logger$J.warning('inpage_initial_pause_failed', {
21596
+ channel: this.channelName,
21597
+ connector_id: this.connectorId,
21598
+ error: err instanceof Error ? err.message : String(err),
21599
+ });
21600
+ });
21601
+ }
21515
21602
  }
21516
21603
  // Allow listeners to feed envelopes directly into the in-page receive queue.
21517
21604
  async pushToReceive(rawOrEnvelope) {
@@ -21561,6 +21648,11 @@ class InPageConnector extends BaseAsyncConnector {
21561
21648
  getSharedBus$1().removeEventListener(this.channelName, this.onMsg);
21562
21649
  this.listenerRegistered = false;
21563
21650
  }
21651
+ if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
21652
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
21653
+ this.visibilityChangeListenerRegistered = false;
21654
+ this.visibilityChangeHandler = undefined;
21655
+ }
21564
21656
  const closeCode = typeof code === 'number' ? code : 1000;
21565
21657
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
21566
21658
  const shutdownError = new FameTransportClose(closeReason, closeCode);
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { BaseAsyncConnector, type BaseAsyncConnectorConfig } from './base-async-connector.js';
6
6
  import type { ConnectorConfig } from './connector-config.js';
7
- import type { FameEnvelope, FameChannelMessage } from '@naylence/core';
7
+ import type { FameEnvelope, FameChannelMessage, FameEnvelopeHandler } from '@naylence/core';
8
8
  export declare const INPAGE_CONNECTOR_TYPE: "inpage-connector";
9
9
  export interface InPageConnectorConfig extends ConnectorConfig {
10
10
  type: typeof INPAGE_CONNECTOR_TYPE;
@@ -18,9 +18,15 @@ export declare class InPageConnector extends BaseAsyncConnector {
18
18
  private listenerRegistered;
19
19
  private readonly connectorId;
20
20
  private readonly onMsg;
21
+ private visibilityChangeListenerRegistered;
22
+ private visibilityChangeHandler?;
21
23
  private static generateConnectorId;
22
24
  private static coercePayload;
23
25
  constructor(config: InPageConnectorConfig, baseConfig?: BaseAsyncConnectorConfig);
26
+ /**
27
+ * Override start() to check initial visibility state
28
+ */
29
+ start(inboundHandler: FameEnvelopeHandler): Promise<void>;
24
30
  pushToReceive(rawOrEnvelope: Uint8Array | FameEnvelope | FameChannelMessage): Promise<void>;
25
31
  protected _transportSendBytes(data: Uint8Array): Promise<void>;
26
32
  protected _transportReceive(): Promise<InPageInboxItem>;
@@ -2,4 +2,4 @@
2
2
  * The package version, injected at build time.
3
3
  * @internal
4
4
  */
5
- export declare const VERSION = "0.3.5-test.941";
5
+ export declare const VERSION = "0.3.5-test.942";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naylence/runtime",
3
- "version": "0.3.5-test.941",
3
+ "version": "0.3.5-test.942",
4
4
  "type": "module",
5
5
  "description": "Naylence Runtime - Complete TypeScript runtime",
6
6
  "author": "Naylence Dev <naylencedev@gmail.com>",