@naylence/runtime 0.3.5-test.953 → 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.
Files changed (42) hide show
  1. package/dist/browser/index.cjs +133 -530
  2. package/dist/browser/index.mjs +133 -530
  3. package/dist/cjs/naylence/fame/channel/flow-controller.js +38 -1
  4. package/dist/cjs/naylence/fame/connector/broadcast-channel-connector-factory.js +2 -14
  5. package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +51 -109
  6. package/dist/cjs/naylence/fame/connector/broadcast-channel-listener.js +10 -76
  7. package/dist/cjs/naylence/fame/connector/inpage-connector-factory.js +0 -12
  8. package/dist/cjs/naylence/fame/connector/inpage-connector.js +1 -105
  9. package/dist/cjs/naylence/fame/connector/inpage-listener.js +2 -49
  10. package/dist/cjs/naylence/fame/grants/broadcast-channel-connection-grant.js +12 -23
  11. package/dist/cjs/naylence/fame/grants/inpage-connection-grant.js +0 -28
  12. package/dist/cjs/naylence/fame/node/admission/default-node-attach-client.js +0 -14
  13. package/dist/cjs/naylence/fame/node/upstream-session-manager.js +0 -6
  14. package/dist/cjs/version.js +2 -2
  15. package/dist/esm/naylence/fame/channel/flow-controller.js +38 -1
  16. package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +2 -14
  17. package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +51 -109
  18. package/dist/esm/naylence/fame/connector/broadcast-channel-listener.js +10 -76
  19. package/dist/esm/naylence/fame/connector/inpage-connector-factory.js +0 -12
  20. package/dist/esm/naylence/fame/connector/inpage-connector.js +1 -105
  21. package/dist/esm/naylence/fame/connector/inpage-listener.js +2 -49
  22. package/dist/esm/naylence/fame/grants/broadcast-channel-connection-grant.js +12 -23
  23. package/dist/esm/naylence/fame/grants/inpage-connection-grant.js +0 -28
  24. package/dist/esm/naylence/fame/node/admission/default-node-attach-client.js +0 -14
  25. package/dist/esm/naylence/fame/node/upstream-session-manager.js +0 -6
  26. package/dist/esm/version.js +2 -2
  27. package/dist/node/index.cjs +133 -530
  28. package/dist/node/index.mjs +133 -530
  29. package/dist/node/node.cjs +133 -546
  30. package/dist/node/node.mjs +133 -546
  31. package/dist/types/naylence/fame/connector/broadcast-channel-connector-factory.d.ts +0 -2
  32. package/dist/types/naylence/fame/connector/broadcast-channel-connector.browser.d.ts +4 -9
  33. package/dist/types/naylence/fame/connector/inpage-connector-factory.d.ts +0 -2
  34. package/dist/types/naylence/fame/connector/inpage-connector.d.ts +0 -9
  35. package/dist/types/naylence/fame/connector/inpage-listener.d.ts +0 -1
  36. package/dist/types/naylence/fame/grants/broadcast-channel-connection-grant.d.ts +3 -6
  37. package/dist/types/naylence/fame/grants/inpage-connection-grant.d.ts +0 -8
  38. package/dist/types/version.d.ts +1 -1
  39. package/package.json +1 -1
  40. package/dist/cjs/naylence/fame/connector/transport-frame.js +0 -100
  41. package/dist/esm/naylence/fame/connector/transport-frame.js +0 -93
  42. package/dist/types/naylence/fame/connector/transport-frame.d.ts +0 -56
@@ -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.953
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.953';
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.
@@ -9818,84 +9854,6 @@ class BoundedAsyncQueue {
9818
9854
  }
9819
9855
  }
9820
9856
 
9821
- /**
9822
- * Transport frame layer for multiplexing logical links on physical channels.
9823
- *
9824
- * This lightweight framing layer wraps raw FAME payloads to enable multiple
9825
- * logical connections over a single physical channel (BroadcastChannel or InPage bus).
9826
- *
9827
- * The transport frame does NOT modify FAME envelopes - it only wraps the raw
9828
- * Uint8Array payload at the connector level.
9829
- */
9830
- /**
9831
- * Transport frame version for future compatibility
9832
- */
9833
- const TRANSPORT_FRAME_VERSION = 1;
9834
- /**
9835
- * Wrap a raw payload in a transport frame
9836
- *
9837
- * @param payload - Raw FAME envelope bytes
9838
- * @param srcNodeId - Local node ID (this connector)
9839
- * @param dstNodeId - Remote node ID (target connector)
9840
- * @returns Transport frame ready for transmission
9841
- */
9842
- function wrapTransportFrame(payload, srcNodeId, dstNodeId) {
9843
- return {
9844
- v: TRANSPORT_FRAME_VERSION,
9845
- src: srcNodeId,
9846
- dst: dstNodeId,
9847
- payload,
9848
- };
9849
- }
9850
- /**
9851
- * Serialize a transport frame for transmission over the bus
9852
- *
9853
- * @param frame - Transport frame to serialize
9854
- * @returns Serialized frame data ready for postMessage/dispatchEvent
9855
- */
9856
- function serializeTransportFrame(frame) {
9857
- // Convert Uint8Array to regular array for JSON serialization
9858
- const serializable = {
9859
- v: frame.v,
9860
- src: frame.src,
9861
- dst: frame.dst,
9862
- payload: Array.from(frame.payload),
9863
- };
9864
- return serializable;
9865
- }
9866
- /**
9867
- * Unwrap a transport frame (pure deserializer - no filtering)
9868
- *
9869
- * @param raw - Raw data from the bus
9870
- * @returns Unwrapped frame with payload as Uint8Array, or null if invalid structure
9871
- */
9872
- function unwrapTransportFrame(raw) {
9873
- // Validate basic structure
9874
- if (!raw || typeof raw !== 'object') {
9875
- return null;
9876
- }
9877
- const frame = raw;
9878
- // Check version
9879
- if (frame.v !== TRANSPORT_FRAME_VERSION) {
9880
- return null;
9881
- }
9882
- // Check src and dst
9883
- if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
9884
- return null;
9885
- }
9886
- // Extract payload
9887
- if (!frame.payload || !Array.isArray(frame.payload)) {
9888
- return null;
9889
- }
9890
- // Convert array back to Uint8Array and return full frame
9891
- return {
9892
- v: frame.v,
9893
- src: frame.src,
9894
- dst: frame.dst,
9895
- payload: Uint8Array.from(frame.payload),
9896
- };
9897
- }
9898
-
9899
9857
  const logger$_ = getLogger('naylence.fame.connector.broadcast_channel_connector');
9900
9858
  const BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
9901
9859
  const DEFAULT_CHANNEL$7 = 'naylence-fabric';
@@ -9959,22 +9917,12 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9959
9917
  ? Math.floor(config.inboxCapacity)
9960
9918
  : DEFAULT_INBOX_CAPACITY$7;
9961
9919
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
9920
+ this.inboxCapacity = preferredCapacity;
9962
9921
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
9963
9922
  this.channel = new BroadcastChannel(this.channelName);
9964
- // Set local and remote node IDs (defaults to connector ID for backwards compatibility)
9965
- this.localNodeId =
9966
- typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
9967
- ? config.localNodeId.trim()
9968
- : this.connectorId;
9969
- this.remoteNodeId =
9970
- typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
9971
- ? config.remoteNodeId.trim()
9972
- : '*'; // Accept from any remote if not specified
9973
9923
  logger$_.debug('broadcast_channel_connector_created', {
9974
9924
  channel: this.channelName,
9975
9925
  connector_id: this.connectorId,
9976
- local_node_id: this.localNodeId,
9977
- remote_node_id: this.remoteNodeId,
9978
9926
  inbox_capacity: preferredCapacity,
9979
9927
  timestamp: new Date().toISOString(),
9980
9928
  });
@@ -10007,67 +9955,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10007
9955
  if (busMessage.senderId === this.connectorId) {
10008
9956
  return;
10009
9957
  }
10010
- // Try to unwrap as transport frame
10011
- const frame = unwrapTransportFrame(busMessage.payload);
10012
- if (frame) {
10013
- // Apply connector's filtering policy: strict dst check, src accepts wildcard
10014
- const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
10015
- const dstMatches = frame.dst === this.localNodeId;
10016
- if (dstMatches && srcMatches) {
10017
- // Successfully received and filtered transport frame
10018
- logger$_.debug('broadcast_channel_transport_frame_received', {
10019
- channel: this.channelName,
10020
- sender_id: busMessage.senderId,
10021
- connector_id: this.connectorId,
10022
- local_node_id: this.localNodeId,
10023
- remote_node_id: this.remoteNodeId,
10024
- frame_src: frame.src,
10025
- frame_dst: frame.dst,
10026
- payload_length: frame.payload.byteLength,
10027
- });
10028
- const unwrapped = frame.payload;
10029
- if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
10030
- return;
10031
- }
10032
- try {
10033
- if (typeof this.inbox.tryEnqueue === 'function') {
10034
- const accepted = this.inbox.tryEnqueue(unwrapped);
10035
- if (accepted) {
10036
- return;
10037
- }
10038
- }
10039
- this.inbox.enqueue(unwrapped);
10040
- }
10041
- catch (error) {
10042
- if (error instanceof QueueFullError) {
10043
- logger$_.warning('broadcast_channel_receive_queue_full', {
10044
- channel: this.channelName,
10045
- });
10046
- }
10047
- else {
10048
- logger$_.error('broadcast_channel_receive_error', {
10049
- channel: this.channelName,
10050
- error: error instanceof Error ? error.message : String(error),
10051
- });
10052
- }
10053
- }
10054
- return;
10055
- }
10056
- else {
10057
- // Frame filtered out by addressing rules
10058
- logger$_.debug('broadcast_channel_transport_frame_filtered', {
10059
- channel: this.channelName,
10060
- connector_id: this.connectorId,
10061
- local_node_id: this.localNodeId,
10062
- remote_node_id: this.remoteNodeId,
10063
- frame_src: frame.src,
10064
- frame_dst: frame.dst,
10065
- reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
10066
- });
10067
- return;
10068
- }
10069
- }
10070
- // Fall back to legacy format (no transport frame)
10071
9958
  const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
10072
9959
  if (!payload) {
10073
9960
  logger$_.debug('broadcast_channel_payload_rejected', {
@@ -10090,15 +9977,27 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10090
9977
  if (typeof this.inbox.tryEnqueue === 'function') {
10091
9978
  const accepted = this.inbox.tryEnqueue(payload);
10092
9979
  if (accepted) {
9980
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9981
+ source: 'listener',
9982
+ enqueue_strategy: 'try',
9983
+ payload_length: payload.byteLength,
9984
+ });
10093
9985
  return;
10094
9986
  }
10095
9987
  }
10096
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
+ });
10097
9994
  }
10098
9995
  catch (error) {
10099
9996
  if (error instanceof QueueFullError) {
10100
9997
  logger$_.warning('broadcast_channel_receive_queue_full', {
10101
9998
  channel: this.channelName,
9999
+ inbox_capacity: this.inboxCapacity,
10000
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10102
10001
  });
10103
10002
  }
10104
10003
  else {
@@ -10182,15 +10081,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10182
10081
  if (typeof this.inbox.tryEnqueue === 'function') {
10183
10082
  const accepted = this.inbox.tryEnqueue(item);
10184
10083
  if (accepted) {
10084
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10085
+ enqueue_strategy: 'try',
10086
+ item_type: this._describeInboxItem(item),
10087
+ });
10185
10088
  return;
10186
10089
  }
10187
10090
  }
10188
10091
  this.inbox.enqueue(item);
10092
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10093
+ enqueue_strategy: 'enqueue',
10094
+ item_type: this._describeInboxItem(item),
10095
+ });
10189
10096
  }
10190
10097
  catch (error) {
10191
10098
  if (error instanceof QueueFullError) {
10192
10099
  logger$_.warning('broadcast_channel_push_queue_full', {
10193
10100
  channel: this.channelName,
10101
+ inbox_capacity: this.inboxCapacity,
10102
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10194
10103
  });
10195
10104
  throw error;
10196
10105
  }
@@ -10206,30 +10115,18 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10206
10115
  logger$_.debug('broadcast_channel_message_sending', {
10207
10116
  channel: this.channelName,
10208
10117
  sender_id: this.connectorId,
10209
- local_node_id: this.localNodeId,
10210
- remote_node_id: this.remoteNodeId,
10211
- });
10212
- // Only use transport framing if both localNodeId and remoteNodeId are explicitly set
10213
- // (not using default values). This ensures backwards compatibility.
10214
- const useTransportFrame = this.localNodeId !== this.connectorId ||
10215
- this.remoteNodeId !== '*';
10216
- let payload;
10217
- if (useTransportFrame) {
10218
- // Wrap payload in transport frame
10219
- const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
10220
- payload = serializeTransportFrame(frame);
10221
- }
10222
- else {
10223
- // Legacy format: send raw payload
10224
- payload = data;
10225
- }
10118
+ });
10226
10119
  this.channel.postMessage({
10227
10120
  senderId: this.connectorId,
10228
- payload,
10121
+ payload: data,
10229
10122
  });
10230
10123
  }
10231
10124
  async _transportReceive() {
10232
- 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;
10233
10130
  }
10234
10131
  async _transportClose(code, reason) {
10235
10132
  logger$_.debug('broadcast_channel_transport_closing', {
@@ -10283,6 +10180,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10283
10180
  }
10284
10181
  return rawOrEnvelope;
10285
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
+ }
10286
10205
  _shouldSkipDuplicateAck(senderId, payload) {
10287
10206
  const dedupKey = this._extractAckDedupKey(payload);
10288
10207
  if (!dedupKey) {
@@ -10381,24 +10300,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10381
10300
  });
10382
10301
  }
10383
10302
  }
10384
- /**
10385
- * Update the remote node ID after learning it from NodeAttachAck
10386
- * This allows upstream connectors to switch from wildcard to specific addressing
10387
- */
10388
- updateRemoteNodeId(newRemoteNodeId) {
10389
- if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
10390
- throw new Error('Invalid remote node ID');
10391
- }
10392
- const oldValue = this.remoteNodeId;
10393
- this.remoteNodeId = newRemoteNodeId.trim();
10394
- logger$_.debug('broadcast_channel_connector_remote_node_id_updated', {
10395
- channel: this.channelName,
10396
- connector_id: this.connectorId,
10397
- local_node_id: this.localNodeId,
10398
- old_remote_node_id: oldValue,
10399
- new_remote_node_id: this.remoteNodeId,
10400
- });
10401
- }
10402
10303
  _trimSeenAcks(now) {
10403
10304
  while (this.seenAckOrder.length > 0) {
10404
10305
  const candidate = this.seenAckOrder[0];
@@ -10536,12 +10437,9 @@ function isBroadcastChannelConnectionGrant(candidate) {
10536
10437
  record.inboxCapacity <= 0)) {
10537
10438
  return false;
10538
10439
  }
10539
- if (record.localNodeId !== undefined &&
10540
- (typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
10541
- return false;
10542
- }
10543
- if (record.remoteNodeId !== undefined &&
10544
- (typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
10440
+ if (record.initialWindow !== undefined &&
10441
+ (!Number.isFinite(record.initialWindow) ||
10442
+ record.initialWindow <= 0)) {
10545
10443
  return false;
10546
10444
  }
10547
10445
  return true;
@@ -10577,19 +10475,14 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
10577
10475
  }
10578
10476
  result.inboxCapacity = Math.floor(inboxValue);
10579
10477
  }
10580
- const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
10581
- if (localNodeIdValue !== undefined) {
10582
- if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
10583
- throw new TypeError('BroadcastChannelConnectionGrant "localNodeId" must be a non-empty string when provided');
10584
- }
10585
- result.localNodeId = localNodeIdValue.trim();
10586
- }
10587
- const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
10588
- if (remoteNodeIdValue !== undefined) {
10589
- if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
10590
- throw new TypeError('BroadcastChannelConnectionGrant "remoteNodeId" must be a non-empty string when provided');
10478
+ const windowValue = candidate.initialWindow ?? candidate['initial_window'];
10479
+ if (windowValue !== undefined) {
10480
+ if (typeof windowValue !== 'number' ||
10481
+ !Number.isFinite(windowValue) ||
10482
+ windowValue <= 0) {
10483
+ throw new TypeError('BroadcastChannelConnectionGrant "initialWindow" must be a positive number when provided');
10591
10484
  }
10592
- result.remoteNodeId = remoteNodeIdValue.trim();
10485
+ result.initialWindow = Math.floor(windowValue);
10593
10486
  }
10594
10487
  return result;
10595
10488
  }
@@ -10604,11 +10497,8 @@ function broadcastChannelGrantToConnectorConfig(grant) {
10604
10497
  if (normalized.inboxCapacity !== undefined) {
10605
10498
  config.inboxCapacity = normalized.inboxCapacity;
10606
10499
  }
10607
- if (normalized.localNodeId) {
10608
- config.localNodeId = normalized.localNodeId;
10609
- }
10610
- if (normalized.remoteNodeId) {
10611
- config.remoteNodeId = normalized.remoteNodeId;
10500
+ if (normalized.initialWindow !== undefined) {
10501
+ config.initialWindow = normalized.initialWindow;
10612
10502
  }
10613
10503
  return config;
10614
10504
  }
@@ -10900,12 +10790,6 @@ class UpstreamSessionManager extends TaskSpawner {
10900
10790
  cryptoProvider.prepareForAttach(welcome.frame.systemId, welcome.frame.assignedPath, welcome.frame.acceptedLogicals ?? []);
10901
10791
  }
10902
10792
  await this.onWelcome(welcome.frame);
10903
- // Inject node ID into grant for transport frame multiplexing
10904
- // This ensures localNodeId matches the node's systemId for proper frame filtering
10905
- grant.localNodeId = welcome.frame.systemId;
10906
- if (welcome.frame.targetSystemId) {
10907
- grant.remoteNodeId = welcome.frame.targetSystemId;
10908
- }
10909
10793
  const connector = await ConnectorFactory.createConnector(grant, {
10910
10794
  systemId: welcome.frame.systemId,
10911
10795
  });
@@ -12862,20 +12746,6 @@ class DefaultNodeAttachClient {
12862
12746
  if (!targetSystemId) {
12863
12747
  throw new Error('Target system ID must be set in NodeAttachAckFrame on success');
12864
12748
  }
12865
- // Update connector's remote node ID if it supports it (e.g., BroadcastChannelConnector, InPageConnector)
12866
- // This allows upstream connectors to switch from wildcard '*' to specific node addressing
12867
- const updatableConnector = connector;
12868
- if (typeof updatableConnector.updateRemoteNodeId === 'function') {
12869
- try {
12870
- updatableConnector.updateRemoteNodeId(targetSystemId);
12871
- }
12872
- catch (error) {
12873
- logger$W.debug('connector_remote_node_id_update_failed', {
12874
- target_system_id: targetSystemId,
12875
- error: error instanceof Error ? error.message : String(error),
12876
- });
12877
- }
12878
- }
12879
12749
  try {
12880
12750
  if (this.replicaStickinessManager) {
12881
12751
  this.replicaStickinessManager.accept(ackFrame.stickiness ?? null);
@@ -20576,20 +20446,9 @@ class InPageConnector extends BaseAsyncConnector {
20576
20446
  : DEFAULT_INBOX_CAPACITY$6;
20577
20447
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
20578
20448
  this.connectorId = InPageConnector.generateConnectorId();
20579
- // Set local and remote node IDs (defaults to connector ID for backwards compatibility)
20580
- this.localNodeId =
20581
- typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
20582
- ? config.localNodeId.trim()
20583
- : this.connectorId;
20584
- this.remoteNodeId =
20585
- typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
20586
- ? config.remoteNodeId.trim()
20587
- : '*'; // Accept from any remote if not specified
20588
20449
  logger$G.debug('inpage_connector_initialized', {
20589
20450
  channel: this.channelName,
20590
20451
  connector_id: this.connectorId,
20591
- local_node_id: this.localNodeId,
20592
- remote_node_id: this.remoteNodeId,
20593
20452
  });
20594
20453
  this.onMsg = (event) => {
20595
20454
  const messageEvent = event;
@@ -20623,64 +20482,6 @@ class InPageConnector extends BaseAsyncConnector {
20623
20482
  if (busMessage.senderId === this.connectorId) {
20624
20483
  return;
20625
20484
  }
20626
- // Try to unwrap as transport frame
20627
- const frame = unwrapTransportFrame(busMessage.payload);
20628
- if (frame) {
20629
- // Apply connector's filtering policy: strict dst check, src accepts wildcard
20630
- const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
20631
- const dstMatches = frame.dst === this.localNodeId;
20632
- if (dstMatches && srcMatches) {
20633
- // Successfully received and filtered transport frame
20634
- logger$G.debug('inpage_transport_frame_received', {
20635
- channel: this.channelName,
20636
- sender_id: busMessage.senderId,
20637
- connector_id: this.connectorId,
20638
- local_node_id: this.localNodeId,
20639
- remote_node_id: this.remoteNodeId,
20640
- frame_src: frame.src,
20641
- frame_dst: frame.dst,
20642
- payload_length: frame.payload.byteLength,
20643
- });
20644
- const unwrapped = frame.payload;
20645
- try {
20646
- if (typeof this.inbox.tryEnqueue === 'function') {
20647
- const accepted = this.inbox.tryEnqueue(unwrapped);
20648
- if (accepted) {
20649
- return;
20650
- }
20651
- }
20652
- this.inbox.enqueue(unwrapped);
20653
- }
20654
- catch (error) {
20655
- if (error instanceof QueueFullError) {
20656
- logger$G.warning('inpage_receive_queue_full', {
20657
- channel: this.channelName,
20658
- });
20659
- }
20660
- else {
20661
- logger$G.error('inpage_receive_error', {
20662
- channel: this.channelName,
20663
- error: error instanceof Error ? error.message : String(error),
20664
- });
20665
- }
20666
- }
20667
- return;
20668
- }
20669
- else {
20670
- // Frame filtered out by addressing rules
20671
- logger$G.debug('inpage_transport_frame_filtered', {
20672
- channel: this.channelName,
20673
- connector_id: this.connectorId,
20674
- local_node_id: this.localNodeId,
20675
- remote_node_id: this.remoteNodeId,
20676
- frame_src: frame.src,
20677
- frame_dst: frame.dst,
20678
- reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
20679
- });
20680
- return;
20681
- }
20682
- }
20683
- // Fall back to legacy format (no transport frame)
20684
20485
  const payload = InPageConnector.coercePayload(busMessage.payload);
20685
20486
  if (!payload) {
20686
20487
  logger$G.debug('inpage_payload_rejected', {
@@ -20839,27 +20640,11 @@ class InPageConnector extends BaseAsyncConnector {
20839
20640
  logger$G.debug('inpage_message_sending', {
20840
20641
  channel: this.channelName,
20841
20642
  sender_id: this.connectorId,
20842
- local_node_id: this.localNodeId,
20843
- remote_node_id: this.remoteNodeId,
20844
- });
20845
- // Only use transport framing if both localNodeId and remoteNodeId are explicitly set
20846
- // (not using default values). This ensures backwards compatibility.
20847
- const useTransportFrame = this.localNodeId !== this.connectorId ||
20848
- this.remoteNodeId !== '*';
20849
- let payload;
20850
- if (useTransportFrame) {
20851
- // Wrap payload in transport frame
20852
- const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
20853
- payload = serializeTransportFrame(frame);
20854
- }
20855
- else {
20856
- // Legacy format: send raw payload
20857
- payload = data;
20858
- }
20643
+ });
20859
20644
  const event = new MessageEvent(this.channelName, {
20860
20645
  data: {
20861
20646
  senderId: this.connectorId,
20862
- payload,
20647
+ payload: data,
20863
20648
  },
20864
20649
  });
20865
20650
  getSharedBus$1().dispatchEvent(event);
@@ -20888,24 +20673,6 @@ class InPageConnector extends BaseAsyncConnector {
20888
20673
  }
20889
20674
  return rawOrEnvelope;
20890
20675
  }
20891
- /**
20892
- * Update the remote node ID after learning it from NodeAttachAck
20893
- * This allows upstream connectors to switch from wildcard to specific addressing
20894
- */
20895
- updateRemoteNodeId(newRemoteNodeId) {
20896
- if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
20897
- throw new Error('Invalid remote node ID');
20898
- }
20899
- const oldValue = this.remoteNodeId;
20900
- this.remoteNodeId = newRemoteNodeId.trim();
20901
- logger$G.debug('inpage_connector_remote_node_id_updated', {
20902
- channel: this.channelName,
20903
- connector_id: this.connectorId,
20904
- local_node_id: this.localNodeId,
20905
- old_remote_node_id: oldValue,
20906
- new_remote_node_id: this.remoteNodeId,
20907
- });
20908
- }
20909
20676
  }
20910
20677
 
20911
20678
  const RPC_REGISTRY = Symbol('naylence.rpc.registry');
@@ -28242,14 +28009,6 @@ function isInPageConnectionGrant(candidate) {
28242
28009
  record.inboxCapacity <= 0)) {
28243
28010
  return false;
28244
28011
  }
28245
- if (record.localNodeId !== undefined &&
28246
- (typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
28247
- return false;
28248
- }
28249
- if (record.remoteNodeId !== undefined &&
28250
- (typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
28251
- return false;
28252
- }
28253
28012
  return true;
28254
28013
  }
28255
28014
  function normalizeInPageConnectionGrant(candidate) {
@@ -28283,20 +28042,6 @@ function normalizeInPageConnectionGrant(candidate) {
28283
28042
  }
28284
28043
  result.inboxCapacity = Math.floor(inboxValue);
28285
28044
  }
28286
- const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
28287
- if (localNodeIdValue !== undefined) {
28288
- if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
28289
- throw new TypeError('InPageConnectionGrant "localNodeId" must be a non-empty string when provided');
28290
- }
28291
- result.localNodeId = localNodeIdValue.trim();
28292
- }
28293
- const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
28294
- if (remoteNodeIdValue !== undefined) {
28295
- if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
28296
- throw new TypeError('InPageConnectionGrant "remoteNodeId" must be a non-empty string when provided');
28297
- }
28298
- result.remoteNodeId = remoteNodeIdValue.trim();
28299
- }
28300
28045
  return result;
28301
28046
  }
28302
28047
  function inPageGrantToConnectorConfig(grant) {
@@ -28310,12 +28055,6 @@ function inPageGrantToConnectorConfig(grant) {
28310
28055
  if (normalized.inboxCapacity !== undefined) {
28311
28056
  config.inboxCapacity = normalized.inboxCapacity;
28312
28057
  }
28313
- if (normalized.localNodeId) {
28314
- config.localNodeId = normalized.localNodeId;
28315
- }
28316
- if (normalized.remoteNodeId) {
28317
- config.remoteNodeId = normalized.remoteNodeId;
28318
- }
28319
28058
  return config;
28320
28059
  }
28321
28060
 
@@ -28937,8 +28676,6 @@ class InPageConnectorFactory extends ConnectorFactory {
28937
28676
  type: INPAGE_CONNECTOR_TYPE,
28938
28677
  channelName,
28939
28678
  inboxCapacity,
28940
- localNodeId: normalized.localNodeId,
28941
- remoteNodeId: normalized.remoteNodeId,
28942
28679
  };
28943
28680
  const connector = new InPageConnector(connectorConfig, baseConfig);
28944
28681
  if (options.authorization) {
@@ -29007,16 +28744,6 @@ class InPageConnectorFactory extends ConnectorFactory {
29007
28744
  if (candidate.authorizationContext !== undefined) {
29008
28745
  normalized.authorizationContext = candidate.authorizationContext;
29009
28746
  }
29010
- // Handle localNodeId
29011
- const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
29012
- if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
29013
- normalized.localNodeId = localNodeId.trim();
29014
- }
29015
- // Handle remoteNodeId
29016
- const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
29017
- if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
29018
- normalized.remoteNodeId = remoteNodeId.trim();
29019
- }
29020
28747
  normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$5;
29021
28748
  normalized.inboxCapacity =
29022
28749
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
@@ -29067,8 +28794,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29067
28794
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
29068
28795
  channelName: connectorConfig.channelName,
29069
28796
  inboxCapacity: connectorConfig.inboxCapacity,
29070
- localNodeId: connectorConfig.localNodeId,
29071
- remoteNodeId: connectorConfig.remoteNodeId,
28797
+ initialWindow: connectorConfig.initialWindow,
29072
28798
  };
29073
28799
  }
29074
28800
  const config = {
@@ -29093,6 +28819,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29093
28819
  purpose: 'connection',
29094
28820
  channelName: normalizedConfig.channelName,
29095
28821
  inboxCapacity: normalizedConfig.inboxCapacity,
28822
+ initialWindow: normalizedConfig.initialWindow,
29096
28823
  });
29097
28824
  return grant;
29098
28825
  }
@@ -29118,8 +28845,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29118
28845
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
29119
28846
  channelName,
29120
28847
  inboxCapacity,
29121
- localNodeId: normalized.localNodeId,
29122
- remoteNodeId: normalized.remoteNodeId,
29123
28848
  };
29124
28849
  const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
29125
28850
  if (options.authorization) {
@@ -29181,16 +28906,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29181
28906
  if (candidate.authorizationContext !== undefined) {
29182
28907
  normalized.authorizationContext = candidate.authorizationContext;
29183
28908
  }
29184
- // Handle localNodeId
29185
- const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
29186
- if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
29187
- normalized.localNodeId = localNodeId.trim();
29188
- }
29189
- // Handle remoteNodeId
29190
- const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
29191
- if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
29192
- normalized.remoteNodeId = remoteNodeId.trim();
29193
- }
29194
28909
  normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$4;
29195
28910
  normalized.inboxCapacity =
29196
28911
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$4;
@@ -29559,7 +29274,6 @@ class InPageListener extends TransportListener {
29559
29274
  this._busHandler = null;
29560
29275
  this._senderRegistry = new Map();
29561
29276
  this._systemToSender = new Map();
29562
- this._flowIdToSender = new Map();
29563
29277
  this._pendingAttachments = new Map();
29564
29278
  ensureBrowserEnvironment$1();
29565
29279
  const channelCandidate = options?.channelName;
@@ -29626,7 +29340,6 @@ class InPageListener extends TransportListener {
29626
29340
  this._unregisterBusListener();
29627
29341
  this._senderRegistry.clear();
29628
29342
  this._systemToSender.clear();
29629
- this._flowIdToSender.clear();
29630
29343
  this._pendingAttachments.clear();
29631
29344
  logger$p.debug('inpage_listener_stopped', {
29632
29345
  channel: this._channelName,
@@ -29680,25 +29393,10 @@ class InPageListener extends TransportListener {
29680
29393
  await this._handleAttachFrame(senderId, envelope);
29681
29394
  return;
29682
29395
  }
29683
- // Try to find connector by sender ID first
29684
- let entry = this._senderRegistry.get(senderId);
29685
- // If not found and we have a flowId, try to route based on flow
29686
- if (!entry && envelope.flowId) {
29687
- const originalSenderId = this._flowIdToSender.get(envelope.flowId);
29688
- if (originalSenderId) {
29689
- entry = this._senderRegistry.get(originalSenderId);
29690
- logger$p.debug('inpage_listener_routed_by_flow_id', {
29691
- sender_id: senderId,
29692
- original_sender_id: originalSenderId,
29693
- flow_id: envelope.flowId,
29694
- frame_type: envelope.frame?.type ?? 'unknown',
29695
- });
29696
- }
29697
- }
29396
+ const entry = this._senderRegistry.get(senderId);
29698
29397
  if (!entry) {
29699
29398
  logger$p.debug('inpage_listener_no_connector_for_sender', {
29700
29399
  sender_id: senderId,
29701
- flow_id: envelope.flowId,
29702
29400
  frame_type: envelope.frame?.type ?? 'unknown',
29703
29401
  });
29704
29402
  return;
@@ -29775,15 +29473,6 @@ class InPageListener extends TransportListener {
29775
29473
  }
29776
29474
  this._senderRegistry.set(senderId, entry);
29777
29475
  this._systemToSender.set(entry.systemId, senderId);
29778
- // Track the flowId if present so we can route responses back
29779
- if (envelope.flowId) {
29780
- this._flowIdToSender.set(envelope.flowId, senderId);
29781
- logger$p.debug('inpage_listener_registered_flow_id', {
29782
- sender_id: senderId,
29783
- system_id: entry.systemId,
29784
- flow_id: envelope.flowId,
29785
- });
29786
- }
29787
29476
  await this._deliverEnvelope(entry, envelope);
29788
29477
  }
29789
29478
  async _createConnectorForAttach(params) {
@@ -29831,7 +29520,7 @@ class InPageListener extends TransportListener {
29831
29520
  origin_type: originType,
29832
29521
  connector_type: connector.constructor?.name ?? 'unknown',
29833
29522
  });
29834
- return { connector, systemId, originType, senderId: params.senderId };
29523
+ return { connector, systemId, originType };
29835
29524
  }
29836
29525
  catch (error) {
29837
29526
  logger$p.error('inpage_listener_connector_creation_failed', {
@@ -29885,12 +29574,6 @@ class InPageListener extends TransportListener {
29885
29574
  if (this._systemToSender.get(systemId) === senderId) {
29886
29575
  this._systemToSender.delete(systemId);
29887
29576
  }
29888
- // Clean up flowId mappings for this sender
29889
- for (const [flowId, sid] of this._flowIdToSender.entries()) {
29890
- if (sid === senderId) {
29891
- this._flowIdToSender.delete(flowId);
29892
- }
29893
- }
29894
29577
  })
29895
29578
  .catch((error) => {
29896
29579
  logger$p.debug('inpage_listener_wait_until_closed_failed', {
@@ -29902,24 +29585,9 @@ class InPageListener extends TransportListener {
29902
29585
  if (this._systemToSender.get(systemId) === senderId) {
29903
29586
  this._systemToSender.delete(systemId);
29904
29587
  }
29905
- // Clean up flowId mappings for this sender
29906
- for (const [flowId, sid] of this._flowIdToSender.entries()) {
29907
- if (sid === senderId) {
29908
- this._flowIdToSender.delete(flowId);
29909
- }
29910
- }
29911
29588
  });
29912
29589
  }
29913
29590
  async _deliverEnvelope(entry, envelope) {
29914
- // Track flowId for routing responses back
29915
- if (envelope.flowId && !this._flowIdToSender.has(envelope.flowId)) {
29916
- this._flowIdToSender.set(envelope.flowId, entry.senderId);
29917
- logger$p.debug('inpage_listener_registered_flow_id_on_delivery', {
29918
- sender_id: entry.senderId,
29919
- system_id: entry.systemId,
29920
- flow_id: envelope.flowId,
29921
- });
29922
- }
29923
29591
  const message = this._buildChannelMessage({
29924
29592
  envelope,
29925
29593
  connector: entry.connector,
@@ -30160,18 +29828,13 @@ class BroadcastChannelListener extends TransportListener {
30160
29828
  });
30161
29829
  }
30162
29830
  asCallbackGrant() {
30163
- const grant = {
29831
+ return this.withLegacySnakeCaseKeys({
30164
29832
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
30165
29833
  connectorType: BROADCAST_CHANNEL_CONNECTOR_TYPE,
30166
29834
  connectionGrantType: BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE,
30167
29835
  channelName: this._channelName,
30168
29836
  inboxCapacity: this._inboxCapacity,
30169
- };
30170
- // Include localNodeId for transport frame multiplexing if node is available
30171
- if (this._routingNode) {
30172
- grant.localNodeId = this._routingNode.id;
30173
- }
30174
- return this.withLegacySnakeCaseKeys(grant);
29837
+ });
30175
29838
  }
30176
29839
  _registerChannelListener() {
30177
29840
  if (this._channelHandler) {
@@ -30231,54 +29894,23 @@ class BroadcastChannelListener extends TransportListener {
30231
29894
  if (typeof senderId !== 'string' || senderId.length === 0) {
30232
29895
  return null;
30233
29896
  }
30234
- // Check if payload is a transport frame object first
30235
- let envelopePayload = null;
30236
- if (this._routingNode && record.payload && typeof record.payload === 'object') {
30237
- // Try to unwrap as transport frame
30238
- const frame = unwrapTransportFrame(record.payload);
30239
- if (frame) {
30240
- // Apply listener's filtering policy: accept frames addressed to us OR with wildcard destination
30241
- // Wildcard is needed because downstream nodes don't know the sentinel's ID during initial attach
30242
- const isAddressedToUs = frame.dst === this._routingNode.id || frame.dst === '*';
30243
- if (isAddressedToUs) {
30244
- envelopePayload = frame.payload;
30245
- logger$o.debug('broadcast_channel_listener_unwrapped_transport_frame', {
30246
- sender_id: senderId,
30247
- src: frame.src,
30248
- dst: frame.dst,
30249
- });
30250
- }
30251
- else {
30252
- // Frame addressed to a different node, ignore it
30253
- logger$o.debug('broadcast_channel_listener_ignored_frame_wrong_destination', {
30254
- sender_id: senderId,
30255
- dst: frame.dst,
30256
- expected: this._routingNode.id,
30257
- });
30258
- return null;
30259
- }
30260
- }
30261
- }
30262
- // If not a transport frame, try to coerce as legacy format
30263
- if (!envelopePayload) {
30264
- envelopePayload = coercePayload(record.payload);
30265
- if (!envelopePayload) {
30266
- logger$o.debug('broadcast_channel_listener_ignored_event_without_payload', {
30267
- sender_id: senderId,
30268
- });
30269
- return null;
30270
- }
29897
+ const payload = coercePayload(record.payload);
29898
+ if (!payload) {
29899
+ logger$o.debug('broadcast_channel_listener_ignored_event_without_payload', {
29900
+ sender_id: senderId,
29901
+ });
29902
+ return null;
30271
29903
  }
30272
29904
  let envelope;
30273
29905
  try {
30274
- const decoded = new TextDecoder().decode(envelopePayload);
29906
+ const decoded = new TextDecoder().decode(payload);
30275
29907
  const parsed = JSON.parse(decoded);
30276
29908
  envelope = core.deserializeEnvelope(parsed);
30277
29909
  }
30278
29910
  catch (error) {
30279
29911
  const decoded = (() => {
30280
29912
  try {
30281
- return new TextDecoder().decode(envelopePayload);
29913
+ return new TextDecoder().decode(payload);
30282
29914
  }
30283
29915
  catch {
30284
29916
  return null;
@@ -30398,20 +30030,6 @@ class BroadcastChannelListener extends TransportListener {
30398
30030
  inboxCapacity: this._inboxCapacity,
30399
30031
  };
30400
30032
  }
30401
- // Automatically configure transport frame multiplexing:
30402
- // Use node IDs (not connector IDs) for node-to-node targeting
30403
- const broadcastConfig = connectorConfig;
30404
- // Always force localNodeId to be this listener's node ID
30405
- // This ensures the sentinel sets localNodeId=sentinel, not the child's ID
30406
- broadcastConfig.localNodeId = routingNode.id;
30407
- // Always force remoteNodeId to be the attaching child's system ID
30408
- broadcastConfig.remoteNodeId = systemId;
30409
- logger$o.debug('broadcast_channel_listener_configured_node_ids', {
30410
- sender_id: params.senderId,
30411
- system_id: systemId,
30412
- local_node_id: broadcastConfig.localNodeId,
30413
- remote_node_id: broadcastConfig.remoteNodeId,
30414
- });
30415
30033
  try {
30416
30034
  const connector = await routingNode.createOriginConnector({
30417
30035
  originType,
@@ -30481,21 +30099,6 @@ class BroadcastChannelListener extends TransportListener {
30481
30099
  inboxCandidate > 0) {
30482
30100
  config.inboxCapacity = Math.floor(inboxCandidate);
30483
30101
  }
30484
- // Extract transport frame multiplexing node IDs
30485
- const localNodeIdCandidate = candidate.localNodeId ?? candidate['local_node_id'];
30486
- if (typeof localNodeIdCandidate === 'string' && localNodeIdCandidate.trim().length > 0) {
30487
- config.localNodeId = localNodeIdCandidate.trim();
30488
- logger$o.debug('broadcast_channel_listener_extracted_local_node_id', {
30489
- local_node_id: config.localNodeId,
30490
- });
30491
- }
30492
- const remoteNodeIdCandidate = candidate.remoteNodeId ?? candidate['remote_node_id'];
30493
- if (typeof remoteNodeIdCandidate === 'string' && remoteNodeIdCandidate.trim().length > 0) {
30494
- config.remoteNodeId = remoteNodeIdCandidate.trim();
30495
- logger$o.debug('broadcast_channel_listener_extracted_remote_node_id', {
30496
- remote_node_id: config.remoteNodeId,
30497
- });
30498
- }
30499
30102
  return config;
30500
30103
  }
30501
30104
  _monitorConnectorLifecycle(senderId, systemId, connector) {