@naylence/runtime 0.3.5-test.954 → 0.3.5-test.955

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.954
101
+ // Generated from package.json version: 0.3.5-test.955
102
102
  /**
103
103
  * The package version, injected at build time.
104
104
  * @internal
105
105
  */
106
- const VERSION = '0.3.5-test.954';
106
+ const VERSION = '0.3.5-test.955';
107
107
 
108
108
  /**
109
109
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -921,7 +921,7 @@ class TaskCancelledError extends Error {
921
921
  * Provides functionality similar to Python's asyncio TaskSpawner with proper
922
922
  * error handling, cancellation, and graceful shutdown capabilities.
923
923
  */
924
- const logger$1b = getLogger('naylence.fame.util.task_spawner');
924
+ const logger$1c = getLogger('naylence.fame.util.task_spawner');
925
925
  function firstDefined(source, keys) {
926
926
  for (const key of keys) {
927
927
  if (Object.prototype.hasOwnProperty.call(source, key)) {
@@ -1082,7 +1082,7 @@ class TaskSpawner {
1082
1082
  const taskId = `task-${++this._taskCounter}`;
1083
1083
  const taskName = normalizedOptions.name || `unnamed-${taskId}`;
1084
1084
  const timeout = normalizedOptions.timeout ?? this._config.defaultTimeout;
1085
- logger$1b.debug('starting_background_task', {
1085
+ logger$1c.debug('starting_background_task', {
1086
1086
  task_name: taskName,
1087
1087
  task_id: taskId,
1088
1088
  });
@@ -1099,7 +1099,7 @@ class TaskSpawner {
1099
1099
  task.promise
1100
1100
  .then(() => {
1101
1101
  if (!this._suppressCompletionLogging) {
1102
- logger$1b.debug('task_completed_successfully', {
1102
+ logger$1c.debug('task_completed_successfully', {
1103
1103
  task_name: taskName,
1104
1104
  task_id: taskId,
1105
1105
  duration_ms: Date.now() - task.startTime,
@@ -1153,7 +1153,7 @@ class TaskSpawner {
1153
1153
  error.name === 'AbortError' ||
1154
1154
  error.message === 'Task cancelled' ||
1155
1155
  error.message === 'Aborted') {
1156
- logger$1b.debug('task_cancelled', {
1156
+ logger$1c.debug('task_cancelled', {
1157
1157
  task_name: taskName,
1158
1158
  note: 'Task cancelled as requested',
1159
1159
  });
@@ -1161,7 +1161,7 @@ class TaskSpawner {
1161
1161
  }
1162
1162
  // Handle timeout
1163
1163
  if (error instanceof TaskTimeoutError) {
1164
- logger$1b.warning('task_timed_out', {
1164
+ logger$1c.warning('task_timed_out', {
1165
1165
  task_name: taskName,
1166
1166
  error: error.message,
1167
1167
  });
@@ -1173,7 +1173,7 @@ class TaskSpawner {
1173
1173
  // Handle known WebSocket shutdown race condition (similar to Python version)
1174
1174
  if (error.message.includes("await wasn't used with future") ||
1175
1175
  error.message.includes('WebSocket closed during receive')) {
1176
- logger$1b.debug('task_shutdown_race_condition_handled', {
1176
+ logger$1c.debug('task_shutdown_race_condition_handled', {
1177
1177
  task_name: taskName,
1178
1178
  note: 'Normal WebSocket close timing during shutdown - not an error',
1179
1179
  });
@@ -1183,7 +1183,7 @@ class TaskSpawner {
1183
1183
  if (error.name === 'FameTransportClose' ||
1184
1184
  error.message.includes('normal closure') ||
1185
1185
  error.message.includes('Connection closed')) {
1186
- logger$1b.debug('task_shutdown_completed_normally', {
1186
+ logger$1c.debug('task_shutdown_completed_normally', {
1187
1187
  task_name: taskName,
1188
1188
  note: 'Task closed normally during shutdown',
1189
1189
  });
@@ -1196,14 +1196,14 @@ class TaskSpawner {
1196
1196
  // Log retriable errors as warnings (they'll be retried by upstream logic)
1197
1197
  // Log non-retriable errors as errors (fatal failures)
1198
1198
  if (isRetriableError) {
1199
- logger$1b.warning('background_task_failed', {
1199
+ logger$1c.warning('background_task_failed', {
1200
1200
  task_name: taskName,
1201
1201
  error: error.message,
1202
1202
  retriable: true,
1203
1203
  });
1204
1204
  }
1205
1205
  else {
1206
- logger$1b.error('background_task_failed', {
1206
+ logger$1c.error('background_task_failed', {
1207
1207
  task_name: taskName,
1208
1208
  error: error.message,
1209
1209
  stack: error.stack,
@@ -1222,11 +1222,11 @@ class TaskSpawner {
1222
1222
  async shutdownTasks(options = {}) {
1223
1223
  const { gracePeriod, cancelHanging, joinTimeout } = normalizeShutdownOptions(options);
1224
1224
  if (this._tasks.size === 0) {
1225
- logger$1b.debug('shutdown_tasks_no_tasks_to_shutdown');
1225
+ logger$1c.debug('shutdown_tasks_no_tasks_to_shutdown');
1226
1226
  return;
1227
1227
  }
1228
1228
  this._suppressCompletionLogging = true;
1229
- logger$1b.debug('shutting_down_tasks', {
1229
+ logger$1c.debug('shutting_down_tasks', {
1230
1230
  task_count: this._tasks.size,
1231
1231
  task_names: Array.from(this._tasks.values()).map((t) => t.name),
1232
1232
  grace_period_ms: gracePeriod,
@@ -1241,7 +1241,7 @@ class TaskSpawner {
1241
1241
  if (cancelHanging) {
1242
1242
  const stillRunning = tasks.filter((task) => task.getState() === TaskState.RUNNING && !completed.has(task));
1243
1243
  if (stillRunning.length > 0) {
1244
- logger$1b.debug('tasks_did_not_complete_within_grace_period', {
1244
+ logger$1c.debug('tasks_did_not_complete_within_grace_period', {
1245
1245
  hanging_count: stillRunning.length,
1246
1246
  });
1247
1247
  // Wait for them to finish with individual timeouts
@@ -1251,7 +1251,7 @@ class TaskSpawner {
1251
1251
  }
1252
1252
  catch (error) {
1253
1253
  if (error instanceof TaskTimeoutError) {
1254
- logger$1b.warning('task_did_not_shutdown', {
1254
+ logger$1c.warning('task_did_not_shutdown', {
1255
1255
  task_name: task.name || task.id,
1256
1256
  join_timeout_ms: joinTimeout,
1257
1257
  });
@@ -1262,7 +1262,7 @@ class TaskSpawner {
1262
1262
  }
1263
1263
  else if (!(error instanceof TaskCancelledError)) {
1264
1264
  /* istanbul ignore next - unreachable defensive branch */
1265
- logger$1b.error('task_raised_during_cancellation', {
1265
+ logger$1c.error('task_raised_during_cancellation', {
1266
1266
  task_name: task.name || task.id,
1267
1267
  error: error instanceof Error ? error.message : String(error),
1268
1268
  });
@@ -2355,6 +2355,7 @@ function validateKeyCorrelationTtlSec(ttlSec) {
2355
2355
  * condition/promise and ensure at most one notifier coroutine exists for a
2356
2356
  * flow at any time.
2357
2357
  */
2358
+ const logger$1b = getLogger('naylence.fame.flow.flow_controller');
2358
2359
  /**
2359
2360
  * Simple condition variable implementation for TypeScript/Node.js
2360
2361
  * Similar to Python's asyncio.Condition
@@ -2480,8 +2481,17 @@ class FlowController {
2480
2481
  // clamp into [0, initialWindow]
2481
2482
  const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
2482
2483
  this.credits.set(flowId, newBalance);
2484
+ const crossedZero = prev <= 0 && newBalance > 0;
2485
+ logger$1b.debug('flow_controller_add_credits', {
2486
+ flow_id: flowId,
2487
+ delta,
2488
+ prev_balance: prev,
2489
+ new_balance: newBalance,
2490
+ initial_window: this.initialWindow,
2491
+ crossed_zero: crossedZero,
2492
+ });
2483
2493
  // wake waiters only if we crossed the zero boundary
2484
- if (prev <= 0 && newBalance > 0) {
2494
+ if (crossedZero) {
2485
2495
  this.wakeWaiters(flowId);
2486
2496
  }
2487
2497
  return newBalance;
@@ -2492,11 +2502,27 @@ class FlowController {
2492
2502
  async acquire(flowId) {
2493
2503
  this.ensureFlow(flowId);
2494
2504
  const condition = this.conditions.get(flowId);
2505
+ logger$1b.debug('flow_controller_acquire_attempt', {
2506
+ flow_id: flowId,
2507
+ current_balance: this.credits.get(flowId),
2508
+ });
2495
2509
  while (this.credits.get(flowId) <= 0) {
2510
+ logger$1b.debug('flow_controller_waiting_for_credit', {
2511
+ flow_id: flowId,
2512
+ });
2496
2513
  await condition.wait();
2514
+ logger$1b.debug('flow_controller_woke_with_credit', {
2515
+ flow_id: flowId,
2516
+ balance_after_wake: this.credits.get(flowId),
2517
+ });
2497
2518
  }
2498
2519
  const current = this.credits.get(flowId);
2499
2520
  this.credits.set(flowId, current - 1);
2521
+ logger$1b.debug('flow_controller_credit_consumed', {
2522
+ flow_id: flowId,
2523
+ prev_balance: current,
2524
+ remaining_balance: current - 1,
2525
+ });
2500
2526
  }
2501
2527
  /**
2502
2528
  * Consume *credits* immediately (non-blocking).
@@ -2516,6 +2542,12 @@ class FlowController {
2516
2542
  const current = this.credits.get(flowId);
2517
2543
  const remaining = Math.max(current - credits, 0);
2518
2544
  this.credits.set(flowId, remaining);
2545
+ logger$1b.debug('flow_controller_consume', {
2546
+ flow_id: flowId,
2547
+ requested: credits,
2548
+ prev_balance: current,
2549
+ remaining_balance: remaining,
2550
+ });
2519
2551
  return remaining;
2520
2552
  }
2521
2553
  /**
@@ -2536,6 +2568,10 @@ class FlowController {
2536
2568
  this.windowIds.delete(flowId);
2537
2569
  this.credits.set(flowId, this.initialWindow);
2538
2570
  this.wakeWaiters(flowId);
2571
+ logger$1b.debug('flow_controller_flow_reset', {
2572
+ flow_id: flowId,
2573
+ reset_balance: this.initialWindow,
2574
+ });
2539
2575
  }
2540
2576
  /**
2541
2577
  * Return `[windowId, flags]` for the next outbound envelope.
@@ -9881,6 +9917,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9881
9917
  ? Math.floor(config.inboxCapacity)
9882
9918
  : DEFAULT_INBOX_CAPACITY$7;
9883
9919
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
9920
+ this.inboxCapacity = preferredCapacity;
9884
9921
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
9885
9922
  this.channel = new BroadcastChannel(this.channelName);
9886
9923
  logger$_.debug('broadcast_channel_connector_created', {
@@ -9940,15 +9977,27 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9940
9977
  if (typeof this.inbox.tryEnqueue === 'function') {
9941
9978
  const accepted = this.inbox.tryEnqueue(payload);
9942
9979
  if (accepted) {
9980
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9981
+ source: 'listener',
9982
+ enqueue_strategy: 'try',
9983
+ payload_length: payload.byteLength,
9984
+ });
9943
9985
  return;
9944
9986
  }
9945
9987
  }
9946
9988
  this.inbox.enqueue(payload);
9989
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9990
+ source: 'listener',
9991
+ enqueue_strategy: 'enqueue',
9992
+ payload_length: payload.byteLength,
9993
+ });
9947
9994
  }
9948
9995
  catch (error) {
9949
9996
  if (error instanceof QueueFullError) {
9950
9997
  logger$_.warning('broadcast_channel_receive_queue_full', {
9951
9998
  channel: this.channelName,
9999
+ inbox_capacity: this.inboxCapacity,
10000
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
9952
10001
  });
9953
10002
  }
9954
10003
  else {
@@ -10032,15 +10081,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10032
10081
  if (typeof this.inbox.tryEnqueue === 'function') {
10033
10082
  const accepted = this.inbox.tryEnqueue(item);
10034
10083
  if (accepted) {
10084
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10085
+ enqueue_strategy: 'try',
10086
+ item_type: this._describeInboxItem(item),
10087
+ });
10035
10088
  return;
10036
10089
  }
10037
10090
  }
10038
10091
  this.inbox.enqueue(item);
10092
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10093
+ enqueue_strategy: 'enqueue',
10094
+ item_type: this._describeInboxItem(item),
10095
+ });
10039
10096
  }
10040
10097
  catch (error) {
10041
10098
  if (error instanceof QueueFullError) {
10042
10099
  logger$_.warning('broadcast_channel_push_queue_full', {
10043
10100
  channel: this.channelName,
10101
+ inbox_capacity: this.inboxCapacity,
10102
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10044
10103
  });
10045
10104
  throw error;
10046
10105
  }
@@ -10063,7 +10122,11 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10063
10122
  });
10064
10123
  }
10065
10124
  async _transportReceive() {
10066
- return await this.inbox.dequeue();
10125
+ const item = await this.inbox.dequeue();
10126
+ this.logInboxSnapshot('broadcast_channel_inbox_dequeued', {
10127
+ item_type: this._describeInboxItem(item),
10128
+ });
10129
+ return item;
10067
10130
  }
10068
10131
  async _transportClose(code, reason) {
10069
10132
  logger$_.debug('broadcast_channel_transport_closing', {
@@ -10117,6 +10180,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10117
10180
  }
10118
10181
  return rawOrEnvelope;
10119
10182
  }
10183
+ _describeInboxItem(item) {
10184
+ if (item instanceof Uint8Array) {
10185
+ return 'bytes';
10186
+ }
10187
+ if (item.envelope) {
10188
+ return 'channel_message';
10189
+ }
10190
+ if (item.frame) {
10191
+ return 'envelope';
10192
+ }
10193
+ return 'unknown';
10194
+ }
10195
+ logInboxSnapshot(event, extra = {}) {
10196
+ logger$_.debug(event, {
10197
+ channel: this.channelName,
10198
+ connector_id: this.connectorId,
10199
+ connector_state: this.state,
10200
+ inbox_capacity: this.inboxCapacity,
10201
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10202
+ ...extra,
10203
+ });
10204
+ }
10120
10205
  _shouldSkipDuplicateAck(senderId, payload) {
10121
10206
  const dedupKey = this._extractAckDedupKey(payload);
10122
10207
  if (!dedupKey) {
@@ -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.954
99
+ // Generated from package.json version: 0.3.5-test.955
100
100
  /**
101
101
  * The package version, injected at build time.
102
102
  * @internal
103
103
  */
104
- const VERSION = '0.3.5-test.954';
104
+ const VERSION = '0.3.5-test.955';
105
105
 
106
106
  /**
107
107
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -919,7 +919,7 @@ class TaskCancelledError extends Error {
919
919
  * Provides functionality similar to Python's asyncio TaskSpawner with proper
920
920
  * error handling, cancellation, and graceful shutdown capabilities.
921
921
  */
922
- const logger$1b = getLogger('naylence.fame.util.task_spawner');
922
+ const logger$1c = getLogger('naylence.fame.util.task_spawner');
923
923
  function firstDefined(source, keys) {
924
924
  for (const key of keys) {
925
925
  if (Object.prototype.hasOwnProperty.call(source, key)) {
@@ -1080,7 +1080,7 @@ class TaskSpawner {
1080
1080
  const taskId = `task-${++this._taskCounter}`;
1081
1081
  const taskName = normalizedOptions.name || `unnamed-${taskId}`;
1082
1082
  const timeout = normalizedOptions.timeout ?? this._config.defaultTimeout;
1083
- logger$1b.debug('starting_background_task', {
1083
+ logger$1c.debug('starting_background_task', {
1084
1084
  task_name: taskName,
1085
1085
  task_id: taskId,
1086
1086
  });
@@ -1097,7 +1097,7 @@ class TaskSpawner {
1097
1097
  task.promise
1098
1098
  .then(() => {
1099
1099
  if (!this._suppressCompletionLogging) {
1100
- logger$1b.debug('task_completed_successfully', {
1100
+ logger$1c.debug('task_completed_successfully', {
1101
1101
  task_name: taskName,
1102
1102
  task_id: taskId,
1103
1103
  duration_ms: Date.now() - task.startTime,
@@ -1151,7 +1151,7 @@ class TaskSpawner {
1151
1151
  error.name === 'AbortError' ||
1152
1152
  error.message === 'Task cancelled' ||
1153
1153
  error.message === 'Aborted') {
1154
- logger$1b.debug('task_cancelled', {
1154
+ logger$1c.debug('task_cancelled', {
1155
1155
  task_name: taskName,
1156
1156
  note: 'Task cancelled as requested',
1157
1157
  });
@@ -1159,7 +1159,7 @@ class TaskSpawner {
1159
1159
  }
1160
1160
  // Handle timeout
1161
1161
  if (error instanceof TaskTimeoutError) {
1162
- logger$1b.warning('task_timed_out', {
1162
+ logger$1c.warning('task_timed_out', {
1163
1163
  task_name: taskName,
1164
1164
  error: error.message,
1165
1165
  });
@@ -1171,7 +1171,7 @@ class TaskSpawner {
1171
1171
  // Handle known WebSocket shutdown race condition (similar to Python version)
1172
1172
  if (error.message.includes("await wasn't used with future") ||
1173
1173
  error.message.includes('WebSocket closed during receive')) {
1174
- logger$1b.debug('task_shutdown_race_condition_handled', {
1174
+ logger$1c.debug('task_shutdown_race_condition_handled', {
1175
1175
  task_name: taskName,
1176
1176
  note: 'Normal WebSocket close timing during shutdown - not an error',
1177
1177
  });
@@ -1181,7 +1181,7 @@ class TaskSpawner {
1181
1181
  if (error.name === 'FameTransportClose' ||
1182
1182
  error.message.includes('normal closure') ||
1183
1183
  error.message.includes('Connection closed')) {
1184
- logger$1b.debug('task_shutdown_completed_normally', {
1184
+ logger$1c.debug('task_shutdown_completed_normally', {
1185
1185
  task_name: taskName,
1186
1186
  note: 'Task closed normally during shutdown',
1187
1187
  });
@@ -1194,14 +1194,14 @@ class TaskSpawner {
1194
1194
  // Log retriable errors as warnings (they'll be retried by upstream logic)
1195
1195
  // Log non-retriable errors as errors (fatal failures)
1196
1196
  if (isRetriableError) {
1197
- logger$1b.warning('background_task_failed', {
1197
+ logger$1c.warning('background_task_failed', {
1198
1198
  task_name: taskName,
1199
1199
  error: error.message,
1200
1200
  retriable: true,
1201
1201
  });
1202
1202
  }
1203
1203
  else {
1204
- logger$1b.error('background_task_failed', {
1204
+ logger$1c.error('background_task_failed', {
1205
1205
  task_name: taskName,
1206
1206
  error: error.message,
1207
1207
  stack: error.stack,
@@ -1220,11 +1220,11 @@ class TaskSpawner {
1220
1220
  async shutdownTasks(options = {}) {
1221
1221
  const { gracePeriod, cancelHanging, joinTimeout } = normalizeShutdownOptions(options);
1222
1222
  if (this._tasks.size === 0) {
1223
- logger$1b.debug('shutdown_tasks_no_tasks_to_shutdown');
1223
+ logger$1c.debug('shutdown_tasks_no_tasks_to_shutdown');
1224
1224
  return;
1225
1225
  }
1226
1226
  this._suppressCompletionLogging = true;
1227
- logger$1b.debug('shutting_down_tasks', {
1227
+ logger$1c.debug('shutting_down_tasks', {
1228
1228
  task_count: this._tasks.size,
1229
1229
  task_names: Array.from(this._tasks.values()).map((t) => t.name),
1230
1230
  grace_period_ms: gracePeriod,
@@ -1239,7 +1239,7 @@ class TaskSpawner {
1239
1239
  if (cancelHanging) {
1240
1240
  const stillRunning = tasks.filter((task) => task.getState() === TaskState.RUNNING && !completed.has(task));
1241
1241
  if (stillRunning.length > 0) {
1242
- logger$1b.debug('tasks_did_not_complete_within_grace_period', {
1242
+ logger$1c.debug('tasks_did_not_complete_within_grace_period', {
1243
1243
  hanging_count: stillRunning.length,
1244
1244
  });
1245
1245
  // Wait for them to finish with individual timeouts
@@ -1249,7 +1249,7 @@ class TaskSpawner {
1249
1249
  }
1250
1250
  catch (error) {
1251
1251
  if (error instanceof TaskTimeoutError) {
1252
- logger$1b.warning('task_did_not_shutdown', {
1252
+ logger$1c.warning('task_did_not_shutdown', {
1253
1253
  task_name: task.name || task.id,
1254
1254
  join_timeout_ms: joinTimeout,
1255
1255
  });
@@ -1260,7 +1260,7 @@ class TaskSpawner {
1260
1260
  }
1261
1261
  else if (!(error instanceof TaskCancelledError)) {
1262
1262
  /* istanbul ignore next - unreachable defensive branch */
1263
- logger$1b.error('task_raised_during_cancellation', {
1263
+ logger$1c.error('task_raised_during_cancellation', {
1264
1264
  task_name: task.name || task.id,
1265
1265
  error: error instanceof Error ? error.message : String(error),
1266
1266
  });
@@ -2353,6 +2353,7 @@ function validateKeyCorrelationTtlSec(ttlSec) {
2353
2353
  * condition/promise and ensure at most one notifier coroutine exists for a
2354
2354
  * flow at any time.
2355
2355
  */
2356
+ const logger$1b = getLogger('naylence.fame.flow.flow_controller');
2356
2357
  /**
2357
2358
  * Simple condition variable implementation for TypeScript/Node.js
2358
2359
  * Similar to Python's asyncio.Condition
@@ -2478,8 +2479,17 @@ class FlowController {
2478
2479
  // clamp into [0, initialWindow]
2479
2480
  const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
2480
2481
  this.credits.set(flowId, newBalance);
2482
+ const crossedZero = prev <= 0 && newBalance > 0;
2483
+ logger$1b.debug('flow_controller_add_credits', {
2484
+ flow_id: flowId,
2485
+ delta,
2486
+ prev_balance: prev,
2487
+ new_balance: newBalance,
2488
+ initial_window: this.initialWindow,
2489
+ crossed_zero: crossedZero,
2490
+ });
2481
2491
  // wake waiters only if we crossed the zero boundary
2482
- if (prev <= 0 && newBalance > 0) {
2492
+ if (crossedZero) {
2483
2493
  this.wakeWaiters(flowId);
2484
2494
  }
2485
2495
  return newBalance;
@@ -2490,11 +2500,27 @@ class FlowController {
2490
2500
  async acquire(flowId) {
2491
2501
  this.ensureFlow(flowId);
2492
2502
  const condition = this.conditions.get(flowId);
2503
+ logger$1b.debug('flow_controller_acquire_attempt', {
2504
+ flow_id: flowId,
2505
+ current_balance: this.credits.get(flowId),
2506
+ });
2493
2507
  while (this.credits.get(flowId) <= 0) {
2508
+ logger$1b.debug('flow_controller_waiting_for_credit', {
2509
+ flow_id: flowId,
2510
+ });
2494
2511
  await condition.wait();
2512
+ logger$1b.debug('flow_controller_woke_with_credit', {
2513
+ flow_id: flowId,
2514
+ balance_after_wake: this.credits.get(flowId),
2515
+ });
2495
2516
  }
2496
2517
  const current = this.credits.get(flowId);
2497
2518
  this.credits.set(flowId, current - 1);
2519
+ logger$1b.debug('flow_controller_credit_consumed', {
2520
+ flow_id: flowId,
2521
+ prev_balance: current,
2522
+ remaining_balance: current - 1,
2523
+ });
2498
2524
  }
2499
2525
  /**
2500
2526
  * Consume *credits* immediately (non-blocking).
@@ -2514,6 +2540,12 @@ class FlowController {
2514
2540
  const current = this.credits.get(flowId);
2515
2541
  const remaining = Math.max(current - credits, 0);
2516
2542
  this.credits.set(flowId, remaining);
2543
+ logger$1b.debug('flow_controller_consume', {
2544
+ flow_id: flowId,
2545
+ requested: credits,
2546
+ prev_balance: current,
2547
+ remaining_balance: remaining,
2548
+ });
2517
2549
  return remaining;
2518
2550
  }
2519
2551
  /**
@@ -2534,6 +2566,10 @@ class FlowController {
2534
2566
  this.windowIds.delete(flowId);
2535
2567
  this.credits.set(flowId, this.initialWindow);
2536
2568
  this.wakeWaiters(flowId);
2569
+ logger$1b.debug('flow_controller_flow_reset', {
2570
+ flow_id: flowId,
2571
+ reset_balance: this.initialWindow,
2572
+ });
2537
2573
  }
2538
2574
  /**
2539
2575
  * Return `[windowId, flags]` for the next outbound envelope.
@@ -9879,6 +9915,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9879
9915
  ? Math.floor(config.inboxCapacity)
9880
9916
  : DEFAULT_INBOX_CAPACITY$7;
9881
9917
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
9918
+ this.inboxCapacity = preferredCapacity;
9882
9919
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
9883
9920
  this.channel = new BroadcastChannel(this.channelName);
9884
9921
  logger$_.debug('broadcast_channel_connector_created', {
@@ -9938,15 +9975,27 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9938
9975
  if (typeof this.inbox.tryEnqueue === 'function') {
9939
9976
  const accepted = this.inbox.tryEnqueue(payload);
9940
9977
  if (accepted) {
9978
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9979
+ source: 'listener',
9980
+ enqueue_strategy: 'try',
9981
+ payload_length: payload.byteLength,
9982
+ });
9941
9983
  return;
9942
9984
  }
9943
9985
  }
9944
9986
  this.inbox.enqueue(payload);
9987
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9988
+ source: 'listener',
9989
+ enqueue_strategy: 'enqueue',
9990
+ payload_length: payload.byteLength,
9991
+ });
9945
9992
  }
9946
9993
  catch (error) {
9947
9994
  if (error instanceof QueueFullError) {
9948
9995
  logger$_.warning('broadcast_channel_receive_queue_full', {
9949
9996
  channel: this.channelName,
9997
+ inbox_capacity: this.inboxCapacity,
9998
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
9950
9999
  });
9951
10000
  }
9952
10001
  else {
@@ -10030,15 +10079,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10030
10079
  if (typeof this.inbox.tryEnqueue === 'function') {
10031
10080
  const accepted = this.inbox.tryEnqueue(item);
10032
10081
  if (accepted) {
10082
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10083
+ enqueue_strategy: 'try',
10084
+ item_type: this._describeInboxItem(item),
10085
+ });
10033
10086
  return;
10034
10087
  }
10035
10088
  }
10036
10089
  this.inbox.enqueue(item);
10090
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10091
+ enqueue_strategy: 'enqueue',
10092
+ item_type: this._describeInboxItem(item),
10093
+ });
10037
10094
  }
10038
10095
  catch (error) {
10039
10096
  if (error instanceof QueueFullError) {
10040
10097
  logger$_.warning('broadcast_channel_push_queue_full', {
10041
10098
  channel: this.channelName,
10099
+ inbox_capacity: this.inboxCapacity,
10100
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10042
10101
  });
10043
10102
  throw error;
10044
10103
  }
@@ -10061,7 +10120,11 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10061
10120
  });
10062
10121
  }
10063
10122
  async _transportReceive() {
10064
- return await this.inbox.dequeue();
10123
+ const item = await this.inbox.dequeue();
10124
+ this.logInboxSnapshot('broadcast_channel_inbox_dequeued', {
10125
+ item_type: this._describeInboxItem(item),
10126
+ });
10127
+ return item;
10065
10128
  }
10066
10129
  async _transportClose(code, reason) {
10067
10130
  logger$_.debug('broadcast_channel_transport_closing', {
@@ -10115,6 +10178,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10115
10178
  }
10116
10179
  return rawOrEnvelope;
10117
10180
  }
10181
+ _describeInboxItem(item) {
10182
+ if (item instanceof Uint8Array) {
10183
+ return 'bytes';
10184
+ }
10185
+ if (item.envelope) {
10186
+ return 'channel_message';
10187
+ }
10188
+ if (item.frame) {
10189
+ return 'envelope';
10190
+ }
10191
+ return 'unknown';
10192
+ }
10193
+ logInboxSnapshot(event, extra = {}) {
10194
+ logger$_.debug(event, {
10195
+ channel: this.channelName,
10196
+ connector_id: this.connectorId,
10197
+ connector_state: this.state,
10198
+ inbox_capacity: this.inboxCapacity,
10199
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10200
+ ...extra,
10201
+ });
10202
+ }
10118
10203
  _shouldSkipDuplicateAck(senderId, payload) {
10119
10204
  const dedupKey = this._extractAckDedupKey(payload);
10120
10205
  if (!dedupKey) {