@naylence/runtime 0.3.5-test.933 → 0.3.5-test.936
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.
- package/dist/browser/index.cjs +178 -4
- package/dist/browser/index.mjs +178 -4
- package/dist/cjs/naylence/fame/connector/base-async-connector.js +92 -0
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +59 -1
- package/dist/cjs/naylence/fame/node/upstream-session-manager.js +26 -1
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/connector/base-async-connector.js +92 -0
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +59 -1
- package/dist/esm/naylence/fame/node/upstream-session-manager.js +27 -2
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +178 -4
- package/dist/node/index.mjs +178 -4
- package/dist/node/node.cjs +178 -4
- package/dist/node/node.mjs +178 -4
- package/dist/types/naylence/fame/connector/base-async-connector.d.ts +8 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +2 -2
package/dist/node/node.cjs
CHANGED
|
@@ -2116,6 +2116,10 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2116
2116
|
* Stop the connector gracefully
|
|
2117
2117
|
*/
|
|
2118
2118
|
async stop() {
|
|
2119
|
+
logger$1f.debug('stopping_connector', {
|
|
2120
|
+
current_state: this._state,
|
|
2121
|
+
connector_id: this._connectorFlowId,
|
|
2122
|
+
});
|
|
2119
2123
|
if (!core.ConnectorStateUtils.canStop(this._state)) {
|
|
2120
2124
|
logger$1f.debug('connector_stop_already_stopped', {
|
|
2121
2125
|
current_state: this._state,
|
|
@@ -2128,6 +2132,52 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2128
2132
|
if (this._lastError) {
|
|
2129
2133
|
throw this._lastError;
|
|
2130
2134
|
}
|
|
2135
|
+
logger$1f.debug('connector_stopped', {
|
|
2136
|
+
current_state: this._state,
|
|
2137
|
+
connector_id: this._connectorFlowId,
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
/**
|
|
2141
|
+
* Pause the connector (suspends heartbeat and housekeeping, but keeps connection alive)
|
|
2142
|
+
*/
|
|
2143
|
+
async pause() {
|
|
2144
|
+
logger$1f.debug('pausing_connector', {
|
|
2145
|
+
current_state: this._state,
|
|
2146
|
+
connector_id: this._connectorFlowId,
|
|
2147
|
+
});
|
|
2148
|
+
if (this._state !== core.ConnectorState.STARTED) {
|
|
2149
|
+
logger$1f.debug('connector_pause_invalid_state', {
|
|
2150
|
+
current_state: this._state,
|
|
2151
|
+
connector_id: this._connectorFlowId,
|
|
2152
|
+
});
|
|
2153
|
+
return;
|
|
2154
|
+
}
|
|
2155
|
+
this._setState(core.ConnectorState.PAUSED);
|
|
2156
|
+
logger$1f.debug('connector_paused', {
|
|
2157
|
+
current_state: this._state,
|
|
2158
|
+
connector_id: this._connectorFlowId,
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2161
|
+
/**
|
|
2162
|
+
* Resume the connector from paused state
|
|
2163
|
+
*/
|
|
2164
|
+
async resume() {
|
|
2165
|
+
logger$1f.debug('resuming_connector', {
|
|
2166
|
+
current_state: this._state,
|
|
2167
|
+
connector_id: this._connectorFlowId,
|
|
2168
|
+
});
|
|
2169
|
+
if (this._state !== core.ConnectorState.PAUSED) {
|
|
2170
|
+
logger$1f.debug('connector_resume_invalid_state', {
|
|
2171
|
+
current_state: this._state,
|
|
2172
|
+
connector_id: this._connectorFlowId,
|
|
2173
|
+
});
|
|
2174
|
+
return;
|
|
2175
|
+
}
|
|
2176
|
+
this._setState(core.ConnectorState.STARTED);
|
|
2177
|
+
logger$1f.debug('connector_resumed', {
|
|
2178
|
+
current_state: this._state,
|
|
2179
|
+
connector_id: this._connectorFlowId,
|
|
2180
|
+
});
|
|
2131
2181
|
}
|
|
2132
2182
|
/**
|
|
2133
2183
|
* Close the connector with optional code and reason
|
|
@@ -2458,8 +2508,21 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2458
2508
|
*/
|
|
2459
2509
|
async _shutdown(code, reason, gracePeriod, exc) {
|
|
2460
2510
|
if (this._closed) {
|
|
2511
|
+
logger$1f.debug('shutdown_already_closed', {
|
|
2512
|
+
connector_id: this._connectorFlowId,
|
|
2513
|
+
current_state: this._state,
|
|
2514
|
+
});
|
|
2461
2515
|
return;
|
|
2462
2516
|
}
|
|
2517
|
+
logger$1f.info('connector_shutdown_starting', {
|
|
2518
|
+
connector_id: this._connectorFlowId,
|
|
2519
|
+
connector_type: this.constructor.name,
|
|
2520
|
+
code,
|
|
2521
|
+
reason,
|
|
2522
|
+
current_state: this._state,
|
|
2523
|
+
has_error: !!exc,
|
|
2524
|
+
timestamp: new Date().toISOString(),
|
|
2525
|
+
});
|
|
2463
2526
|
this._closed = true;
|
|
2464
2527
|
this._closeCode = code;
|
|
2465
2528
|
this._closeReason = reason;
|
|
@@ -2481,16 +2544,39 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2481
2544
|
this._sendPromiseResolve = undefined;
|
|
2482
2545
|
}
|
|
2483
2546
|
// Close transport
|
|
2547
|
+
logger$1f.info('connector_closing_transport', {
|
|
2548
|
+
connector_id: this._connectorFlowId,
|
|
2549
|
+
connector_type: this.constructor.name,
|
|
2550
|
+
timestamp: new Date().toISOString(),
|
|
2551
|
+
});
|
|
2484
2552
|
await this._transportClose(code, reason);
|
|
2553
|
+
logger$1f.info('connector_transport_closed', {
|
|
2554
|
+
connector_id: this._connectorFlowId,
|
|
2555
|
+
connector_type: this.constructor.name,
|
|
2556
|
+
timestamp: new Date().toISOString(),
|
|
2557
|
+
});
|
|
2485
2558
|
// Shutdown spawned tasks
|
|
2559
|
+
logger$1f.info('connector_shutting_down_tasks', {
|
|
2560
|
+
connector_id: this._connectorFlowId,
|
|
2561
|
+
connector_type: this.constructor.name,
|
|
2562
|
+
grace_period_ms: effectiveGracePeriod * 1000,
|
|
2563
|
+
join_timeout_ms: this._shutdownJoinTimeout,
|
|
2564
|
+
timestamp: new Date().toISOString(),
|
|
2565
|
+
});
|
|
2486
2566
|
try {
|
|
2487
2567
|
await this.shutdownTasks({
|
|
2488
2568
|
gracePeriod: effectiveGracePeriod * 1000, // Convert to milliseconds
|
|
2489
2569
|
joinTimeout: this._shutdownJoinTimeout,
|
|
2490
2570
|
});
|
|
2571
|
+
logger$1f.info('connector_tasks_shutdown_complete', {
|
|
2572
|
+
connector_id: this._connectorFlowId,
|
|
2573
|
+
connector_type: this.constructor.name,
|
|
2574
|
+
timestamp: new Date().toISOString(),
|
|
2575
|
+
});
|
|
2491
2576
|
}
|
|
2492
2577
|
catch (error) {
|
|
2493
2578
|
logger$1f.warning('task_shutdown_error', {
|
|
2579
|
+
connector_id: this._connectorFlowId,
|
|
2494
2580
|
error: error instanceof Error ? error.message : String(error),
|
|
2495
2581
|
});
|
|
2496
2582
|
}
|
|
@@ -2502,6 +2588,12 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2502
2588
|
if (this._closeResolver) {
|
|
2503
2589
|
this._closeResolver();
|
|
2504
2590
|
}
|
|
2591
|
+
logger$1f.info('connector_shutdown_complete', {
|
|
2592
|
+
connector_id: this._connectorFlowId,
|
|
2593
|
+
connector_type: this.constructor.name,
|
|
2594
|
+
final_state: this._state,
|
|
2595
|
+
timestamp: new Date().toISOString(),
|
|
2596
|
+
});
|
|
2505
2597
|
}
|
|
2506
2598
|
/**
|
|
2507
2599
|
* Close the underlying transport
|
|
@@ -5386,12 +5478,12 @@ for (const [name, config] of Object.entries(SQLITE_PROFILES)) {
|
|
|
5386
5478
|
}
|
|
5387
5479
|
|
|
5388
5480
|
// This file is auto-generated during build - do not edit manually
|
|
5389
|
-
// Generated from package.json version: 0.3.5-test.
|
|
5481
|
+
// Generated from package.json version: 0.3.5-test.936
|
|
5390
5482
|
/**
|
|
5391
5483
|
* The package version, injected at build time.
|
|
5392
5484
|
* @internal
|
|
5393
5485
|
*/
|
|
5394
|
-
const VERSION = '0.3.5-test.
|
|
5486
|
+
const VERSION = '0.3.5-test.936';
|
|
5395
5487
|
|
|
5396
5488
|
/**
|
|
5397
5489
|
* Fame errors module - Fame protocol specific error classes
|
|
@@ -11444,12 +11536,22 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11444
11536
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
11445
11537
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
11446
11538
|
this.channel = new BroadcastChannel(this.channelName);
|
|
11447
|
-
logger$10.
|
|
11539
|
+
logger$10.info('broadcast_channel_connector_created', {
|
|
11448
11540
|
channel: this.channelName,
|
|
11449
11541
|
connector_id: this.connectorId,
|
|
11450
11542
|
inbox_capacity: preferredCapacity,
|
|
11543
|
+
timestamp: new Date().toISOString(),
|
|
11451
11544
|
});
|
|
11452
11545
|
this.onMsg = (event) => {
|
|
11546
|
+
// Guard: Don't process if listener was unregistered
|
|
11547
|
+
if (!this.listenerRegistered) {
|
|
11548
|
+
logger$10.warning('broadcast_channel_message_after_unregister', {
|
|
11549
|
+
channel: this.channelName,
|
|
11550
|
+
connector_id: this.connectorId,
|
|
11551
|
+
timestamp: new Date().toISOString(),
|
|
11552
|
+
});
|
|
11553
|
+
return;
|
|
11554
|
+
}
|
|
11453
11555
|
const message = event.data;
|
|
11454
11556
|
logger$10.debug('broadcast_channel_raw_event', {
|
|
11455
11557
|
channel: this.channelName,
|
|
@@ -11521,6 +11623,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11521
11623
|
visibility: isHidden ? 'hidden' : 'visible',
|
|
11522
11624
|
timestamp: new Date().toISOString(),
|
|
11523
11625
|
});
|
|
11626
|
+
// Pause/resume connector based on visibility
|
|
11627
|
+
if (isHidden && this.state === core.ConnectorState.STARTED) {
|
|
11628
|
+
this.pause().catch((err) => {
|
|
11629
|
+
logger$10.warning('broadcast_channel_pause_failed', {
|
|
11630
|
+
channel: this.channelName,
|
|
11631
|
+
connector_id: this.connectorId,
|
|
11632
|
+
error: err instanceof Error ? err.message : String(err),
|
|
11633
|
+
});
|
|
11634
|
+
});
|
|
11635
|
+
}
|
|
11636
|
+
else if (!isHidden && this.state === core.ConnectorState.PAUSED) {
|
|
11637
|
+
this.resume().catch((err) => {
|
|
11638
|
+
logger$10.warning('broadcast_channel_resume_failed', {
|
|
11639
|
+
channel: this.channelName,
|
|
11640
|
+
connector_id: this.connectorId,
|
|
11641
|
+
error: err instanceof Error ? err.message : String(err),
|
|
11642
|
+
});
|
|
11643
|
+
});
|
|
11644
|
+
}
|
|
11524
11645
|
};
|
|
11525
11646
|
if (typeof document !== 'undefined') {
|
|
11526
11647
|
document.addEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
@@ -11576,16 +11697,44 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11576
11697
|
return await this.inbox.dequeue();
|
|
11577
11698
|
}
|
|
11578
11699
|
async _transportClose(code, reason) {
|
|
11700
|
+
logger$10.info('broadcast_channel_transport_closing', {
|
|
11701
|
+
channel: this.channelName,
|
|
11702
|
+
connector_id: this.connectorId,
|
|
11703
|
+
code,
|
|
11704
|
+
reason,
|
|
11705
|
+
listener_registered: this.listenerRegistered,
|
|
11706
|
+
timestamp: new Date().toISOString(),
|
|
11707
|
+
});
|
|
11579
11708
|
if (this.listenerRegistered) {
|
|
11709
|
+
logger$10.info('broadcast_channel_removing_listener', {
|
|
11710
|
+
channel: this.channelName,
|
|
11711
|
+
connector_id: this.connectorId,
|
|
11712
|
+
timestamp: new Date().toISOString(),
|
|
11713
|
+
});
|
|
11580
11714
|
this.channel.removeEventListener('message', this.onMsg);
|
|
11581
11715
|
this.listenerRegistered = false;
|
|
11716
|
+
logger$10.info('broadcast_channel_listener_removed', {
|
|
11717
|
+
channel: this.channelName,
|
|
11718
|
+
connector_id: this.connectorId,
|
|
11719
|
+
timestamp: new Date().toISOString(),
|
|
11720
|
+
});
|
|
11582
11721
|
}
|
|
11583
11722
|
if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
|
|
11584
11723
|
document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
11585
11724
|
this.visibilityChangeListenerRegistered = false;
|
|
11586
11725
|
this.visibilityChangeHandler = undefined;
|
|
11587
11726
|
}
|
|
11727
|
+
logger$10.info('broadcast_channel_closing', {
|
|
11728
|
+
channel: this.channelName,
|
|
11729
|
+
connector_id: this.connectorId,
|
|
11730
|
+
timestamp: new Date().toISOString(),
|
|
11731
|
+
});
|
|
11588
11732
|
this.channel.close();
|
|
11733
|
+
logger$10.info('broadcast_channel_closed', {
|
|
11734
|
+
channel: this.channelName,
|
|
11735
|
+
connector_id: this.connectorId,
|
|
11736
|
+
timestamp: new Date().toISOString(),
|
|
11737
|
+
});
|
|
11589
11738
|
const closeCode = typeof code === 'number' ? code : 1000;
|
|
11590
11739
|
const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
|
|
11591
11740
|
const shutdownError = new FameTransportClose(closeReason, closeCode);
|
|
@@ -12188,7 +12337,22 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12188
12337
|
this.currentStopSubtasks = null;
|
|
12189
12338
|
await Promise.allSettled(tasks.map((task) => task.promise));
|
|
12190
12339
|
if (this.connector) {
|
|
12191
|
-
|
|
12340
|
+
logger$$.info('upstream_stopping_old_connector', {
|
|
12341
|
+
connect_epoch: this.connectEpoch,
|
|
12342
|
+
target_system_id: this.targetSystemId,
|
|
12343
|
+
timestamp: new Date().toISOString(),
|
|
12344
|
+
});
|
|
12345
|
+
await this.connector.stop().catch((err) => {
|
|
12346
|
+
logger$$.warning('upstream_connector_stop_error', {
|
|
12347
|
+
connect_epoch: this.connectEpoch,
|
|
12348
|
+
error: err instanceof Error ? err.message : String(err),
|
|
12349
|
+
});
|
|
12350
|
+
});
|
|
12351
|
+
logger$$.info('upstream_old_connector_stopped', {
|
|
12352
|
+
connect_epoch: this.connectEpoch,
|
|
12353
|
+
target_system_id: this.targetSystemId,
|
|
12354
|
+
timestamp: new Date().toISOString(),
|
|
12355
|
+
});
|
|
12192
12356
|
this.connector = null;
|
|
12193
12357
|
}
|
|
12194
12358
|
}
|
|
@@ -12322,6 +12486,15 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12322
12486
|
if (stopEvt.isSet() || signal?.aborted) {
|
|
12323
12487
|
break;
|
|
12324
12488
|
}
|
|
12489
|
+
// Skip heartbeat if connector is paused (e.g., tab is hidden)
|
|
12490
|
+
// Keep ack time current so we don't timeout immediately after resuming
|
|
12491
|
+
if (connector.state === core.ConnectorState.PAUSED) {
|
|
12492
|
+
logger$$.debug('skipping_heartbeat_connector_paused', {
|
|
12493
|
+
connector_state: connector.state,
|
|
12494
|
+
});
|
|
12495
|
+
this.lastHeartbeatAckTime = Date.now();
|
|
12496
|
+
continue;
|
|
12497
|
+
}
|
|
12325
12498
|
const envelope = await this.makeHeartbeatEnvelope();
|
|
12326
12499
|
logger$$.debug('sending_heartbeat', {
|
|
12327
12500
|
hb_corr_id: envelope.corrId,
|
|
@@ -12343,6 +12516,7 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12343
12516
|
throw error;
|
|
12344
12517
|
}
|
|
12345
12518
|
await this.node.dispatchEvent('onHeartbeatSent', this.node, envelope);
|
|
12519
|
+
// Don't check heartbeat timeout when paused
|
|
12346
12520
|
if (this.lastHeartbeatAckTime !== null &&
|
|
12347
12521
|
Date.now() - this.lastHeartbeatAckTime > graceMs) {
|
|
12348
12522
|
throw new FameConnectError('missed heartbeat acknowledgement');
|
package/dist/node/node.mjs
CHANGED
|
@@ -2115,6 +2115,10 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2115
2115
|
* Stop the connector gracefully
|
|
2116
2116
|
*/
|
|
2117
2117
|
async stop() {
|
|
2118
|
+
logger$1f.debug('stopping_connector', {
|
|
2119
|
+
current_state: this._state,
|
|
2120
|
+
connector_id: this._connectorFlowId,
|
|
2121
|
+
});
|
|
2118
2122
|
if (!ConnectorStateUtils.canStop(this._state)) {
|
|
2119
2123
|
logger$1f.debug('connector_stop_already_stopped', {
|
|
2120
2124
|
current_state: this._state,
|
|
@@ -2127,6 +2131,52 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2127
2131
|
if (this._lastError) {
|
|
2128
2132
|
throw this._lastError;
|
|
2129
2133
|
}
|
|
2134
|
+
logger$1f.debug('connector_stopped', {
|
|
2135
|
+
current_state: this._state,
|
|
2136
|
+
connector_id: this._connectorFlowId,
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
/**
|
|
2140
|
+
* Pause the connector (suspends heartbeat and housekeeping, but keeps connection alive)
|
|
2141
|
+
*/
|
|
2142
|
+
async pause() {
|
|
2143
|
+
logger$1f.debug('pausing_connector', {
|
|
2144
|
+
current_state: this._state,
|
|
2145
|
+
connector_id: this._connectorFlowId,
|
|
2146
|
+
});
|
|
2147
|
+
if (this._state !== ConnectorState.STARTED) {
|
|
2148
|
+
logger$1f.debug('connector_pause_invalid_state', {
|
|
2149
|
+
current_state: this._state,
|
|
2150
|
+
connector_id: this._connectorFlowId,
|
|
2151
|
+
});
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
this._setState(ConnectorState.PAUSED);
|
|
2155
|
+
logger$1f.debug('connector_paused', {
|
|
2156
|
+
current_state: this._state,
|
|
2157
|
+
connector_id: this._connectorFlowId,
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Resume the connector from paused state
|
|
2162
|
+
*/
|
|
2163
|
+
async resume() {
|
|
2164
|
+
logger$1f.debug('resuming_connector', {
|
|
2165
|
+
current_state: this._state,
|
|
2166
|
+
connector_id: this._connectorFlowId,
|
|
2167
|
+
});
|
|
2168
|
+
if (this._state !== ConnectorState.PAUSED) {
|
|
2169
|
+
logger$1f.debug('connector_resume_invalid_state', {
|
|
2170
|
+
current_state: this._state,
|
|
2171
|
+
connector_id: this._connectorFlowId,
|
|
2172
|
+
});
|
|
2173
|
+
return;
|
|
2174
|
+
}
|
|
2175
|
+
this._setState(ConnectorState.STARTED);
|
|
2176
|
+
logger$1f.debug('connector_resumed', {
|
|
2177
|
+
current_state: this._state,
|
|
2178
|
+
connector_id: this._connectorFlowId,
|
|
2179
|
+
});
|
|
2130
2180
|
}
|
|
2131
2181
|
/**
|
|
2132
2182
|
* Close the connector with optional code and reason
|
|
@@ -2457,8 +2507,21 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2457
2507
|
*/
|
|
2458
2508
|
async _shutdown(code, reason, gracePeriod, exc) {
|
|
2459
2509
|
if (this._closed) {
|
|
2510
|
+
logger$1f.debug('shutdown_already_closed', {
|
|
2511
|
+
connector_id: this._connectorFlowId,
|
|
2512
|
+
current_state: this._state,
|
|
2513
|
+
});
|
|
2460
2514
|
return;
|
|
2461
2515
|
}
|
|
2516
|
+
logger$1f.info('connector_shutdown_starting', {
|
|
2517
|
+
connector_id: this._connectorFlowId,
|
|
2518
|
+
connector_type: this.constructor.name,
|
|
2519
|
+
code,
|
|
2520
|
+
reason,
|
|
2521
|
+
current_state: this._state,
|
|
2522
|
+
has_error: !!exc,
|
|
2523
|
+
timestamp: new Date().toISOString(),
|
|
2524
|
+
});
|
|
2462
2525
|
this._closed = true;
|
|
2463
2526
|
this._closeCode = code;
|
|
2464
2527
|
this._closeReason = reason;
|
|
@@ -2480,16 +2543,39 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2480
2543
|
this._sendPromiseResolve = undefined;
|
|
2481
2544
|
}
|
|
2482
2545
|
// Close transport
|
|
2546
|
+
logger$1f.info('connector_closing_transport', {
|
|
2547
|
+
connector_id: this._connectorFlowId,
|
|
2548
|
+
connector_type: this.constructor.name,
|
|
2549
|
+
timestamp: new Date().toISOString(),
|
|
2550
|
+
});
|
|
2483
2551
|
await this._transportClose(code, reason);
|
|
2552
|
+
logger$1f.info('connector_transport_closed', {
|
|
2553
|
+
connector_id: this._connectorFlowId,
|
|
2554
|
+
connector_type: this.constructor.name,
|
|
2555
|
+
timestamp: new Date().toISOString(),
|
|
2556
|
+
});
|
|
2484
2557
|
// Shutdown spawned tasks
|
|
2558
|
+
logger$1f.info('connector_shutting_down_tasks', {
|
|
2559
|
+
connector_id: this._connectorFlowId,
|
|
2560
|
+
connector_type: this.constructor.name,
|
|
2561
|
+
grace_period_ms: effectiveGracePeriod * 1000,
|
|
2562
|
+
join_timeout_ms: this._shutdownJoinTimeout,
|
|
2563
|
+
timestamp: new Date().toISOString(),
|
|
2564
|
+
});
|
|
2485
2565
|
try {
|
|
2486
2566
|
await this.shutdownTasks({
|
|
2487
2567
|
gracePeriod: effectiveGracePeriod * 1000, // Convert to milliseconds
|
|
2488
2568
|
joinTimeout: this._shutdownJoinTimeout,
|
|
2489
2569
|
});
|
|
2570
|
+
logger$1f.info('connector_tasks_shutdown_complete', {
|
|
2571
|
+
connector_id: this._connectorFlowId,
|
|
2572
|
+
connector_type: this.constructor.name,
|
|
2573
|
+
timestamp: new Date().toISOString(),
|
|
2574
|
+
});
|
|
2490
2575
|
}
|
|
2491
2576
|
catch (error) {
|
|
2492
2577
|
logger$1f.warning('task_shutdown_error', {
|
|
2578
|
+
connector_id: this._connectorFlowId,
|
|
2493
2579
|
error: error instanceof Error ? error.message : String(error),
|
|
2494
2580
|
});
|
|
2495
2581
|
}
|
|
@@ -2501,6 +2587,12 @@ class BaseAsyncConnector extends TaskSpawner {
|
|
|
2501
2587
|
if (this._closeResolver) {
|
|
2502
2588
|
this._closeResolver();
|
|
2503
2589
|
}
|
|
2590
|
+
logger$1f.info('connector_shutdown_complete', {
|
|
2591
|
+
connector_id: this._connectorFlowId,
|
|
2592
|
+
connector_type: this.constructor.name,
|
|
2593
|
+
final_state: this._state,
|
|
2594
|
+
timestamp: new Date().toISOString(),
|
|
2595
|
+
});
|
|
2504
2596
|
}
|
|
2505
2597
|
/**
|
|
2506
2598
|
* Close the underlying transport
|
|
@@ -5385,12 +5477,12 @@ for (const [name, config] of Object.entries(SQLITE_PROFILES)) {
|
|
|
5385
5477
|
}
|
|
5386
5478
|
|
|
5387
5479
|
// This file is auto-generated during build - do not edit manually
|
|
5388
|
-
// Generated from package.json version: 0.3.5-test.
|
|
5480
|
+
// Generated from package.json version: 0.3.5-test.936
|
|
5389
5481
|
/**
|
|
5390
5482
|
* The package version, injected at build time.
|
|
5391
5483
|
* @internal
|
|
5392
5484
|
*/
|
|
5393
|
-
const VERSION = '0.3.5-test.
|
|
5485
|
+
const VERSION = '0.3.5-test.936';
|
|
5394
5486
|
|
|
5395
5487
|
/**
|
|
5396
5488
|
* Fame errors module - Fame protocol specific error classes
|
|
@@ -11443,12 +11535,22 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11443
11535
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
11444
11536
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
11445
11537
|
this.channel = new BroadcastChannel(this.channelName);
|
|
11446
|
-
logger$10.
|
|
11538
|
+
logger$10.info('broadcast_channel_connector_created', {
|
|
11447
11539
|
channel: this.channelName,
|
|
11448
11540
|
connector_id: this.connectorId,
|
|
11449
11541
|
inbox_capacity: preferredCapacity,
|
|
11542
|
+
timestamp: new Date().toISOString(),
|
|
11450
11543
|
});
|
|
11451
11544
|
this.onMsg = (event) => {
|
|
11545
|
+
// Guard: Don't process if listener was unregistered
|
|
11546
|
+
if (!this.listenerRegistered) {
|
|
11547
|
+
logger$10.warning('broadcast_channel_message_after_unregister', {
|
|
11548
|
+
channel: this.channelName,
|
|
11549
|
+
connector_id: this.connectorId,
|
|
11550
|
+
timestamp: new Date().toISOString(),
|
|
11551
|
+
});
|
|
11552
|
+
return;
|
|
11553
|
+
}
|
|
11452
11554
|
const message = event.data;
|
|
11453
11555
|
logger$10.debug('broadcast_channel_raw_event', {
|
|
11454
11556
|
channel: this.channelName,
|
|
@@ -11520,6 +11622,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11520
11622
|
visibility: isHidden ? 'hidden' : 'visible',
|
|
11521
11623
|
timestamp: new Date().toISOString(),
|
|
11522
11624
|
});
|
|
11625
|
+
// Pause/resume connector based on visibility
|
|
11626
|
+
if (isHidden && this.state === ConnectorState.STARTED) {
|
|
11627
|
+
this.pause().catch((err) => {
|
|
11628
|
+
logger$10.warning('broadcast_channel_pause_failed', {
|
|
11629
|
+
channel: this.channelName,
|
|
11630
|
+
connector_id: this.connectorId,
|
|
11631
|
+
error: err instanceof Error ? err.message : String(err),
|
|
11632
|
+
});
|
|
11633
|
+
});
|
|
11634
|
+
}
|
|
11635
|
+
else if (!isHidden && this.state === ConnectorState.PAUSED) {
|
|
11636
|
+
this.resume().catch((err) => {
|
|
11637
|
+
logger$10.warning('broadcast_channel_resume_failed', {
|
|
11638
|
+
channel: this.channelName,
|
|
11639
|
+
connector_id: this.connectorId,
|
|
11640
|
+
error: err instanceof Error ? err.message : String(err),
|
|
11641
|
+
});
|
|
11642
|
+
});
|
|
11643
|
+
}
|
|
11523
11644
|
};
|
|
11524
11645
|
if (typeof document !== 'undefined') {
|
|
11525
11646
|
document.addEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
@@ -11575,16 +11696,44 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11575
11696
|
return await this.inbox.dequeue();
|
|
11576
11697
|
}
|
|
11577
11698
|
async _transportClose(code, reason) {
|
|
11699
|
+
logger$10.info('broadcast_channel_transport_closing', {
|
|
11700
|
+
channel: this.channelName,
|
|
11701
|
+
connector_id: this.connectorId,
|
|
11702
|
+
code,
|
|
11703
|
+
reason,
|
|
11704
|
+
listener_registered: this.listenerRegistered,
|
|
11705
|
+
timestamp: new Date().toISOString(),
|
|
11706
|
+
});
|
|
11578
11707
|
if (this.listenerRegistered) {
|
|
11708
|
+
logger$10.info('broadcast_channel_removing_listener', {
|
|
11709
|
+
channel: this.channelName,
|
|
11710
|
+
connector_id: this.connectorId,
|
|
11711
|
+
timestamp: new Date().toISOString(),
|
|
11712
|
+
});
|
|
11579
11713
|
this.channel.removeEventListener('message', this.onMsg);
|
|
11580
11714
|
this.listenerRegistered = false;
|
|
11715
|
+
logger$10.info('broadcast_channel_listener_removed', {
|
|
11716
|
+
channel: this.channelName,
|
|
11717
|
+
connector_id: this.connectorId,
|
|
11718
|
+
timestamp: new Date().toISOString(),
|
|
11719
|
+
});
|
|
11581
11720
|
}
|
|
11582
11721
|
if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
|
|
11583
11722
|
document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
11584
11723
|
this.visibilityChangeListenerRegistered = false;
|
|
11585
11724
|
this.visibilityChangeHandler = undefined;
|
|
11586
11725
|
}
|
|
11726
|
+
logger$10.info('broadcast_channel_closing', {
|
|
11727
|
+
channel: this.channelName,
|
|
11728
|
+
connector_id: this.connectorId,
|
|
11729
|
+
timestamp: new Date().toISOString(),
|
|
11730
|
+
});
|
|
11587
11731
|
this.channel.close();
|
|
11732
|
+
logger$10.info('broadcast_channel_closed', {
|
|
11733
|
+
channel: this.channelName,
|
|
11734
|
+
connector_id: this.connectorId,
|
|
11735
|
+
timestamp: new Date().toISOString(),
|
|
11736
|
+
});
|
|
11588
11737
|
const closeCode = typeof code === 'number' ? code : 1000;
|
|
11589
11738
|
const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
|
|
11590
11739
|
const shutdownError = new FameTransportClose(closeReason, closeCode);
|
|
@@ -12187,7 +12336,22 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12187
12336
|
this.currentStopSubtasks = null;
|
|
12188
12337
|
await Promise.allSettled(tasks.map((task) => task.promise));
|
|
12189
12338
|
if (this.connector) {
|
|
12190
|
-
|
|
12339
|
+
logger$$.info('upstream_stopping_old_connector', {
|
|
12340
|
+
connect_epoch: this.connectEpoch,
|
|
12341
|
+
target_system_id: this.targetSystemId,
|
|
12342
|
+
timestamp: new Date().toISOString(),
|
|
12343
|
+
});
|
|
12344
|
+
await this.connector.stop().catch((err) => {
|
|
12345
|
+
logger$$.warning('upstream_connector_stop_error', {
|
|
12346
|
+
connect_epoch: this.connectEpoch,
|
|
12347
|
+
error: err instanceof Error ? err.message : String(err),
|
|
12348
|
+
});
|
|
12349
|
+
});
|
|
12350
|
+
logger$$.info('upstream_old_connector_stopped', {
|
|
12351
|
+
connect_epoch: this.connectEpoch,
|
|
12352
|
+
target_system_id: this.targetSystemId,
|
|
12353
|
+
timestamp: new Date().toISOString(),
|
|
12354
|
+
});
|
|
12191
12355
|
this.connector = null;
|
|
12192
12356
|
}
|
|
12193
12357
|
}
|
|
@@ -12321,6 +12485,15 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12321
12485
|
if (stopEvt.isSet() || signal?.aborted) {
|
|
12322
12486
|
break;
|
|
12323
12487
|
}
|
|
12488
|
+
// Skip heartbeat if connector is paused (e.g., tab is hidden)
|
|
12489
|
+
// Keep ack time current so we don't timeout immediately after resuming
|
|
12490
|
+
if (connector.state === ConnectorState.PAUSED) {
|
|
12491
|
+
logger$$.debug('skipping_heartbeat_connector_paused', {
|
|
12492
|
+
connector_state: connector.state,
|
|
12493
|
+
});
|
|
12494
|
+
this.lastHeartbeatAckTime = Date.now();
|
|
12495
|
+
continue;
|
|
12496
|
+
}
|
|
12324
12497
|
const envelope = await this.makeHeartbeatEnvelope();
|
|
12325
12498
|
logger$$.debug('sending_heartbeat', {
|
|
12326
12499
|
hb_corr_id: envelope.corrId,
|
|
@@ -12342,6 +12515,7 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12342
12515
|
throw error;
|
|
12343
12516
|
}
|
|
12344
12517
|
await this.node.dispatchEvent('onHeartbeatSent', this.node, envelope);
|
|
12518
|
+
// Don't check heartbeat timeout when paused
|
|
12345
12519
|
if (this.lastHeartbeatAckTime !== null &&
|
|
12346
12520
|
Date.now() - this.lastHeartbeatAckTime > graceMs) {
|
|
12347
12521
|
throw new FameConnectError('missed heartbeat acknowledgement');
|
|
@@ -103,6 +103,14 @@ export declare abstract class BaseAsyncConnector extends TaskSpawner implements
|
|
|
103
103
|
* Stop the connector gracefully
|
|
104
104
|
*/
|
|
105
105
|
stop(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Pause the connector (suspends heartbeat and housekeeping, but keeps connection alive)
|
|
108
|
+
*/
|
|
109
|
+
pause(): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Resume the connector from paused state
|
|
112
|
+
*/
|
|
113
|
+
resume(): Promise<void>;
|
|
106
114
|
/**
|
|
107
115
|
* Close the connector with optional code and reason
|
|
108
116
|
*/
|
package/dist/types/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naylence/runtime",
|
|
3
|
-
"version": "0.3.5-test.
|
|
3
|
+
"version": "0.3.5-test.936",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Naylence Runtime - Complete TypeScript runtime",
|
|
6
6
|
"author": "Naylence Dev <naylencedev@gmail.com>",
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
"dependencies": {
|
|
177
177
|
"@fastify/formbody": "^8.0.2",
|
|
178
178
|
"@fastify/websocket": "^11.2.0",
|
|
179
|
-
"@naylence/core": "^0.3.
|
|
179
|
+
"@naylence/core": "^0.3.5",
|
|
180
180
|
"@noble/ciphers": "^2.0.1",
|
|
181
181
|
"@noble/curves": "^2.0.1",
|
|
182
182
|
"@noble/ed25519": "^3.0.0",
|