@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
@@ -13,12 +13,12 @@ import fastify from 'fastify';
13
13
  import websocketPlugin from '@fastify/websocket';
14
14
 
15
15
  // This file is auto-generated during build - do not edit manually
16
- // Generated from package.json version: 0.3.5-test.953
16
+ // Generated from package.json version: 0.3.5-test.955
17
17
  /**
18
18
  * The package version, injected at build time.
19
19
  * @internal
20
20
  */
21
- const VERSION = '0.3.5-test.953';
21
+ const VERSION = '0.3.5-test.955';
22
22
 
23
23
  /**
24
24
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -836,7 +836,7 @@ class TaskCancelledError extends Error {
836
836
  * Provides functionality similar to Python's asyncio TaskSpawner with proper
837
837
  * error handling, cancellation, and graceful shutdown capabilities.
838
838
  */
839
- const logger$1b = getLogger('naylence.fame.util.task_spawner');
839
+ const logger$1c = getLogger('naylence.fame.util.task_spawner');
840
840
  function firstDefined(source, keys) {
841
841
  for (const key of keys) {
842
842
  if (Object.prototype.hasOwnProperty.call(source, key)) {
@@ -997,7 +997,7 @@ class TaskSpawner {
997
997
  const taskId = `task-${++this._taskCounter}`;
998
998
  const taskName = normalizedOptions.name || `unnamed-${taskId}`;
999
999
  const timeout = normalizedOptions.timeout ?? this._config.defaultTimeout;
1000
- logger$1b.debug('starting_background_task', {
1000
+ logger$1c.debug('starting_background_task', {
1001
1001
  task_name: taskName,
1002
1002
  task_id: taskId,
1003
1003
  });
@@ -1014,7 +1014,7 @@ class TaskSpawner {
1014
1014
  task.promise
1015
1015
  .then(() => {
1016
1016
  if (!this._suppressCompletionLogging) {
1017
- logger$1b.debug('task_completed_successfully', {
1017
+ logger$1c.debug('task_completed_successfully', {
1018
1018
  task_name: taskName,
1019
1019
  task_id: taskId,
1020
1020
  duration_ms: Date.now() - task.startTime,
@@ -1068,7 +1068,7 @@ class TaskSpawner {
1068
1068
  error.name === 'AbortError' ||
1069
1069
  error.message === 'Task cancelled' ||
1070
1070
  error.message === 'Aborted') {
1071
- logger$1b.debug('task_cancelled', {
1071
+ logger$1c.debug('task_cancelled', {
1072
1072
  task_name: taskName,
1073
1073
  note: 'Task cancelled as requested',
1074
1074
  });
@@ -1076,7 +1076,7 @@ class TaskSpawner {
1076
1076
  }
1077
1077
  // Handle timeout
1078
1078
  if (error instanceof TaskTimeoutError) {
1079
- logger$1b.warning('task_timed_out', {
1079
+ logger$1c.warning('task_timed_out', {
1080
1080
  task_name: taskName,
1081
1081
  error: error.message,
1082
1082
  });
@@ -1088,7 +1088,7 @@ class TaskSpawner {
1088
1088
  // Handle known WebSocket shutdown race condition (similar to Python version)
1089
1089
  if (error.message.includes("await wasn't used with future") ||
1090
1090
  error.message.includes('WebSocket closed during receive')) {
1091
- logger$1b.debug('task_shutdown_race_condition_handled', {
1091
+ logger$1c.debug('task_shutdown_race_condition_handled', {
1092
1092
  task_name: taskName,
1093
1093
  note: 'Normal WebSocket close timing during shutdown - not an error',
1094
1094
  });
@@ -1098,7 +1098,7 @@ class TaskSpawner {
1098
1098
  if (error.name === 'FameTransportClose' ||
1099
1099
  error.message.includes('normal closure') ||
1100
1100
  error.message.includes('Connection closed')) {
1101
- logger$1b.debug('task_shutdown_completed_normally', {
1101
+ logger$1c.debug('task_shutdown_completed_normally', {
1102
1102
  task_name: taskName,
1103
1103
  note: 'Task closed normally during shutdown',
1104
1104
  });
@@ -1111,14 +1111,14 @@ class TaskSpawner {
1111
1111
  // Log retriable errors as warnings (they'll be retried by upstream logic)
1112
1112
  // Log non-retriable errors as errors (fatal failures)
1113
1113
  if (isRetriableError) {
1114
- logger$1b.warning('background_task_failed', {
1114
+ logger$1c.warning('background_task_failed', {
1115
1115
  task_name: taskName,
1116
1116
  error: error.message,
1117
1117
  retriable: true,
1118
1118
  });
1119
1119
  }
1120
1120
  else {
1121
- logger$1b.error('background_task_failed', {
1121
+ logger$1c.error('background_task_failed', {
1122
1122
  task_name: taskName,
1123
1123
  error: error.message,
1124
1124
  stack: error.stack,
@@ -1137,11 +1137,11 @@ class TaskSpawner {
1137
1137
  async shutdownTasks(options = {}) {
1138
1138
  const { gracePeriod, cancelHanging, joinTimeout } = normalizeShutdownOptions(options);
1139
1139
  if (this._tasks.size === 0) {
1140
- logger$1b.debug('shutdown_tasks_no_tasks_to_shutdown');
1140
+ logger$1c.debug('shutdown_tasks_no_tasks_to_shutdown');
1141
1141
  return;
1142
1142
  }
1143
1143
  this._suppressCompletionLogging = true;
1144
- logger$1b.debug('shutting_down_tasks', {
1144
+ logger$1c.debug('shutting_down_tasks', {
1145
1145
  task_count: this._tasks.size,
1146
1146
  task_names: Array.from(this._tasks.values()).map((t) => t.name),
1147
1147
  grace_period_ms: gracePeriod,
@@ -1156,7 +1156,7 @@ class TaskSpawner {
1156
1156
  if (cancelHanging) {
1157
1157
  const stillRunning = tasks.filter((task) => task.getState() === TaskState.RUNNING && !completed.has(task));
1158
1158
  if (stillRunning.length > 0) {
1159
- logger$1b.debug('tasks_did_not_complete_within_grace_period', {
1159
+ logger$1c.debug('tasks_did_not_complete_within_grace_period', {
1160
1160
  hanging_count: stillRunning.length,
1161
1161
  });
1162
1162
  // Wait for them to finish with individual timeouts
@@ -1166,7 +1166,7 @@ class TaskSpawner {
1166
1166
  }
1167
1167
  catch (error) {
1168
1168
  if (error instanceof TaskTimeoutError) {
1169
- logger$1b.warning('task_did_not_shutdown', {
1169
+ logger$1c.warning('task_did_not_shutdown', {
1170
1170
  task_name: task.name || task.id,
1171
1171
  join_timeout_ms: joinTimeout,
1172
1172
  });
@@ -1177,7 +1177,7 @@ class TaskSpawner {
1177
1177
  }
1178
1178
  else if (!(error instanceof TaskCancelledError)) {
1179
1179
  /* istanbul ignore next - unreachable defensive branch */
1180
- logger$1b.error('task_raised_during_cancellation', {
1180
+ logger$1c.error('task_raised_during_cancellation', {
1181
1181
  task_name: task.name || task.id,
1182
1182
  error: error instanceof Error ? error.message : String(error),
1183
1183
  });
@@ -2270,6 +2270,7 @@ function validateKeyCorrelationTtlSec(ttlSec) {
2270
2270
  * condition/promise and ensure at most one notifier coroutine exists for a
2271
2271
  * flow at any time.
2272
2272
  */
2273
+ const logger$1b = getLogger('naylence.fame.flow.flow_controller');
2273
2274
  /**
2274
2275
  * Simple condition variable implementation for TypeScript/Node.js
2275
2276
  * Similar to Python's asyncio.Condition
@@ -2395,8 +2396,17 @@ class FlowController {
2395
2396
  // clamp into [0, initialWindow]
2396
2397
  const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
2397
2398
  this.credits.set(flowId, newBalance);
2399
+ const crossedZero = prev <= 0 && newBalance > 0;
2400
+ logger$1b.debug('flow_controller_add_credits', {
2401
+ flow_id: flowId,
2402
+ delta,
2403
+ prev_balance: prev,
2404
+ new_balance: newBalance,
2405
+ initial_window: this.initialWindow,
2406
+ crossed_zero: crossedZero,
2407
+ });
2398
2408
  // wake waiters only if we crossed the zero boundary
2399
- if (prev <= 0 && newBalance > 0) {
2409
+ if (crossedZero) {
2400
2410
  this.wakeWaiters(flowId);
2401
2411
  }
2402
2412
  return newBalance;
@@ -2407,11 +2417,27 @@ class FlowController {
2407
2417
  async acquire(flowId) {
2408
2418
  this.ensureFlow(flowId);
2409
2419
  const condition = this.conditions.get(flowId);
2420
+ logger$1b.debug('flow_controller_acquire_attempt', {
2421
+ flow_id: flowId,
2422
+ current_balance: this.credits.get(flowId),
2423
+ });
2410
2424
  while (this.credits.get(flowId) <= 0) {
2425
+ logger$1b.debug('flow_controller_waiting_for_credit', {
2426
+ flow_id: flowId,
2427
+ });
2411
2428
  await condition.wait();
2429
+ logger$1b.debug('flow_controller_woke_with_credit', {
2430
+ flow_id: flowId,
2431
+ balance_after_wake: this.credits.get(flowId),
2432
+ });
2412
2433
  }
2413
2434
  const current = this.credits.get(flowId);
2414
2435
  this.credits.set(flowId, current - 1);
2436
+ logger$1b.debug('flow_controller_credit_consumed', {
2437
+ flow_id: flowId,
2438
+ prev_balance: current,
2439
+ remaining_balance: current - 1,
2440
+ });
2415
2441
  }
2416
2442
  /**
2417
2443
  * Consume *credits* immediately (non-blocking).
@@ -2431,6 +2457,12 @@ class FlowController {
2431
2457
  const current = this.credits.get(flowId);
2432
2458
  const remaining = Math.max(current - credits, 0);
2433
2459
  this.credits.set(flowId, remaining);
2460
+ logger$1b.debug('flow_controller_consume', {
2461
+ flow_id: flowId,
2462
+ requested: credits,
2463
+ prev_balance: current,
2464
+ remaining_balance: remaining,
2465
+ });
2434
2466
  return remaining;
2435
2467
  }
2436
2468
  /**
@@ -2451,6 +2483,10 @@ class FlowController {
2451
2483
  this.windowIds.delete(flowId);
2452
2484
  this.credits.set(flowId, this.initialWindow);
2453
2485
  this.wakeWaiters(flowId);
2486
+ logger$1b.debug('flow_controller_flow_reset', {
2487
+ flow_id: flowId,
2488
+ reset_balance: this.initialWindow,
2489
+ });
2454
2490
  }
2455
2491
  /**
2456
2492
  * Return `[windowId, flags]` for the next outbound envelope.
@@ -9733,84 +9769,6 @@ class BoundedAsyncQueue {
9733
9769
  }
9734
9770
  }
9735
9771
 
9736
- /**
9737
- * Transport frame layer for multiplexing logical links on physical channels.
9738
- *
9739
- * This lightweight framing layer wraps raw FAME payloads to enable multiple
9740
- * logical connections over a single physical channel (BroadcastChannel or InPage bus).
9741
- *
9742
- * The transport frame does NOT modify FAME envelopes - it only wraps the raw
9743
- * Uint8Array payload at the connector level.
9744
- */
9745
- /**
9746
- * Transport frame version for future compatibility
9747
- */
9748
- const TRANSPORT_FRAME_VERSION = 1;
9749
- /**
9750
- * Wrap a raw payload in a transport frame
9751
- *
9752
- * @param payload - Raw FAME envelope bytes
9753
- * @param srcNodeId - Local node ID (this connector)
9754
- * @param dstNodeId - Remote node ID (target connector)
9755
- * @returns Transport frame ready for transmission
9756
- */
9757
- function wrapTransportFrame(payload, srcNodeId, dstNodeId) {
9758
- return {
9759
- v: TRANSPORT_FRAME_VERSION,
9760
- src: srcNodeId,
9761
- dst: dstNodeId,
9762
- payload,
9763
- };
9764
- }
9765
- /**
9766
- * Serialize a transport frame for transmission over the bus
9767
- *
9768
- * @param frame - Transport frame to serialize
9769
- * @returns Serialized frame data ready for postMessage/dispatchEvent
9770
- */
9771
- function serializeTransportFrame(frame) {
9772
- // Convert Uint8Array to regular array for JSON serialization
9773
- const serializable = {
9774
- v: frame.v,
9775
- src: frame.src,
9776
- dst: frame.dst,
9777
- payload: Array.from(frame.payload),
9778
- };
9779
- return serializable;
9780
- }
9781
- /**
9782
- * Unwrap a transport frame (pure deserializer - no filtering)
9783
- *
9784
- * @param raw - Raw data from the bus
9785
- * @returns Unwrapped frame with payload as Uint8Array, or null if invalid structure
9786
- */
9787
- function unwrapTransportFrame(raw) {
9788
- // Validate basic structure
9789
- if (!raw || typeof raw !== 'object') {
9790
- return null;
9791
- }
9792
- const frame = raw;
9793
- // Check version
9794
- if (frame.v !== TRANSPORT_FRAME_VERSION) {
9795
- return null;
9796
- }
9797
- // Check src and dst
9798
- if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
9799
- return null;
9800
- }
9801
- // Extract payload
9802
- if (!frame.payload || !Array.isArray(frame.payload)) {
9803
- return null;
9804
- }
9805
- // Convert array back to Uint8Array and return full frame
9806
- return {
9807
- v: frame.v,
9808
- src: frame.src,
9809
- dst: frame.dst,
9810
- payload: Uint8Array.from(frame.payload),
9811
- };
9812
- }
9813
-
9814
9772
  const logger$_ = getLogger('naylence.fame.connector.broadcast_channel_connector');
9815
9773
  const BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
9816
9774
  const DEFAULT_CHANNEL$7 = 'naylence-fabric';
@@ -9874,22 +9832,12 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9874
9832
  ? Math.floor(config.inboxCapacity)
9875
9833
  : DEFAULT_INBOX_CAPACITY$7;
9876
9834
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
9835
+ this.inboxCapacity = preferredCapacity;
9877
9836
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
9878
9837
  this.channel = new BroadcastChannel(this.channelName);
9879
- // Set local and remote node IDs (defaults to connector ID for backwards compatibility)
9880
- this.localNodeId =
9881
- typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
9882
- ? config.localNodeId.trim()
9883
- : this.connectorId;
9884
- this.remoteNodeId =
9885
- typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
9886
- ? config.remoteNodeId.trim()
9887
- : '*'; // Accept from any remote if not specified
9888
9838
  logger$_.debug('broadcast_channel_connector_created', {
9889
9839
  channel: this.channelName,
9890
9840
  connector_id: this.connectorId,
9891
- local_node_id: this.localNodeId,
9892
- remote_node_id: this.remoteNodeId,
9893
9841
  inbox_capacity: preferredCapacity,
9894
9842
  timestamp: new Date().toISOString(),
9895
9843
  });
@@ -9922,67 +9870,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9922
9870
  if (busMessage.senderId === this.connectorId) {
9923
9871
  return;
9924
9872
  }
9925
- // Try to unwrap as transport frame
9926
- const frame = unwrapTransportFrame(busMessage.payload);
9927
- if (frame) {
9928
- // Apply connector's filtering policy: strict dst check, src accepts wildcard
9929
- const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
9930
- const dstMatches = frame.dst === this.localNodeId;
9931
- if (dstMatches && srcMatches) {
9932
- // Successfully received and filtered transport frame
9933
- logger$_.debug('broadcast_channel_transport_frame_received', {
9934
- channel: this.channelName,
9935
- sender_id: busMessage.senderId,
9936
- connector_id: this.connectorId,
9937
- local_node_id: this.localNodeId,
9938
- remote_node_id: this.remoteNodeId,
9939
- frame_src: frame.src,
9940
- frame_dst: frame.dst,
9941
- payload_length: frame.payload.byteLength,
9942
- });
9943
- const unwrapped = frame.payload;
9944
- if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
9945
- return;
9946
- }
9947
- try {
9948
- if (typeof this.inbox.tryEnqueue === 'function') {
9949
- const accepted = this.inbox.tryEnqueue(unwrapped);
9950
- if (accepted) {
9951
- return;
9952
- }
9953
- }
9954
- this.inbox.enqueue(unwrapped);
9955
- }
9956
- catch (error) {
9957
- if (error instanceof QueueFullError) {
9958
- logger$_.warning('broadcast_channel_receive_queue_full', {
9959
- channel: this.channelName,
9960
- });
9961
- }
9962
- else {
9963
- logger$_.error('broadcast_channel_receive_error', {
9964
- channel: this.channelName,
9965
- error: error instanceof Error ? error.message : String(error),
9966
- });
9967
- }
9968
- }
9969
- return;
9970
- }
9971
- else {
9972
- // Frame filtered out by addressing rules
9973
- logger$_.debug('broadcast_channel_transport_frame_filtered', {
9974
- channel: this.channelName,
9975
- connector_id: this.connectorId,
9976
- local_node_id: this.localNodeId,
9977
- remote_node_id: this.remoteNodeId,
9978
- frame_src: frame.src,
9979
- frame_dst: frame.dst,
9980
- reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
9981
- });
9982
- return;
9983
- }
9984
- }
9985
- // Fall back to legacy format (no transport frame)
9986
9873
  const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
9987
9874
  if (!payload) {
9988
9875
  logger$_.debug('broadcast_channel_payload_rejected', {
@@ -10005,15 +9892,27 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10005
9892
  if (typeof this.inbox.tryEnqueue === 'function') {
10006
9893
  const accepted = this.inbox.tryEnqueue(payload);
10007
9894
  if (accepted) {
9895
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9896
+ source: 'listener',
9897
+ enqueue_strategy: 'try',
9898
+ payload_length: payload.byteLength,
9899
+ });
10008
9900
  return;
10009
9901
  }
10010
9902
  }
10011
9903
  this.inbox.enqueue(payload);
9904
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9905
+ source: 'listener',
9906
+ enqueue_strategy: 'enqueue',
9907
+ payload_length: payload.byteLength,
9908
+ });
10012
9909
  }
10013
9910
  catch (error) {
10014
9911
  if (error instanceof QueueFullError) {
10015
9912
  logger$_.warning('broadcast_channel_receive_queue_full', {
10016
9913
  channel: this.channelName,
9914
+ inbox_capacity: this.inboxCapacity,
9915
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10017
9916
  });
10018
9917
  }
10019
9918
  else {
@@ -10097,15 +9996,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10097
9996
  if (typeof this.inbox.tryEnqueue === 'function') {
10098
9997
  const accepted = this.inbox.tryEnqueue(item);
10099
9998
  if (accepted) {
9999
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10000
+ enqueue_strategy: 'try',
10001
+ item_type: this._describeInboxItem(item),
10002
+ });
10100
10003
  return;
10101
10004
  }
10102
10005
  }
10103
10006
  this.inbox.enqueue(item);
10007
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10008
+ enqueue_strategy: 'enqueue',
10009
+ item_type: this._describeInboxItem(item),
10010
+ });
10104
10011
  }
10105
10012
  catch (error) {
10106
10013
  if (error instanceof QueueFullError) {
10107
10014
  logger$_.warning('broadcast_channel_push_queue_full', {
10108
10015
  channel: this.channelName,
10016
+ inbox_capacity: this.inboxCapacity,
10017
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10109
10018
  });
10110
10019
  throw error;
10111
10020
  }
@@ -10121,30 +10030,18 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10121
10030
  logger$_.debug('broadcast_channel_message_sending', {
10122
10031
  channel: this.channelName,
10123
10032
  sender_id: this.connectorId,
10124
- local_node_id: this.localNodeId,
10125
- remote_node_id: this.remoteNodeId,
10126
- });
10127
- // Only use transport framing if both localNodeId and remoteNodeId are explicitly set
10128
- // (not using default values). This ensures backwards compatibility.
10129
- const useTransportFrame = this.localNodeId !== this.connectorId ||
10130
- this.remoteNodeId !== '*';
10131
- let payload;
10132
- if (useTransportFrame) {
10133
- // Wrap payload in transport frame
10134
- const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
10135
- payload = serializeTransportFrame(frame);
10136
- }
10137
- else {
10138
- // Legacy format: send raw payload
10139
- payload = data;
10140
- }
10033
+ });
10141
10034
  this.channel.postMessage({
10142
10035
  senderId: this.connectorId,
10143
- payload,
10036
+ payload: data,
10144
10037
  });
10145
10038
  }
10146
10039
  async _transportReceive() {
10147
- return await this.inbox.dequeue();
10040
+ const item = await this.inbox.dequeue();
10041
+ this.logInboxSnapshot('broadcast_channel_inbox_dequeued', {
10042
+ item_type: this._describeInboxItem(item),
10043
+ });
10044
+ return item;
10148
10045
  }
10149
10046
  async _transportClose(code, reason) {
10150
10047
  logger$_.debug('broadcast_channel_transport_closing', {
@@ -10198,6 +10095,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10198
10095
  }
10199
10096
  return rawOrEnvelope;
10200
10097
  }
10098
+ _describeInboxItem(item) {
10099
+ if (item instanceof Uint8Array) {
10100
+ return 'bytes';
10101
+ }
10102
+ if (item.envelope) {
10103
+ return 'channel_message';
10104
+ }
10105
+ if (item.frame) {
10106
+ return 'envelope';
10107
+ }
10108
+ return 'unknown';
10109
+ }
10110
+ logInboxSnapshot(event, extra = {}) {
10111
+ logger$_.debug(event, {
10112
+ channel: this.channelName,
10113
+ connector_id: this.connectorId,
10114
+ connector_state: this.state,
10115
+ inbox_capacity: this.inboxCapacity,
10116
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10117
+ ...extra,
10118
+ });
10119
+ }
10201
10120
  _shouldSkipDuplicateAck(senderId, payload) {
10202
10121
  const dedupKey = this._extractAckDedupKey(payload);
10203
10122
  if (!dedupKey) {
@@ -10296,24 +10215,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10296
10215
  });
10297
10216
  }
10298
10217
  }
10299
- /**
10300
- * Update the remote node ID after learning it from NodeAttachAck
10301
- * This allows upstream connectors to switch from wildcard to specific addressing
10302
- */
10303
- updateRemoteNodeId(newRemoteNodeId) {
10304
- if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
10305
- throw new Error('Invalid remote node ID');
10306
- }
10307
- const oldValue = this.remoteNodeId;
10308
- this.remoteNodeId = newRemoteNodeId.trim();
10309
- logger$_.debug('broadcast_channel_connector_remote_node_id_updated', {
10310
- channel: this.channelName,
10311
- connector_id: this.connectorId,
10312
- local_node_id: this.localNodeId,
10313
- old_remote_node_id: oldValue,
10314
- new_remote_node_id: this.remoteNodeId,
10315
- });
10316
- }
10317
10218
  _trimSeenAcks(now) {
10318
10219
  while (this.seenAckOrder.length > 0) {
10319
10220
  const candidate = this.seenAckOrder[0];
@@ -10451,12 +10352,9 @@ function isBroadcastChannelConnectionGrant(candidate) {
10451
10352
  record.inboxCapacity <= 0)) {
10452
10353
  return false;
10453
10354
  }
10454
- if (record.localNodeId !== undefined &&
10455
- (typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
10456
- return false;
10457
- }
10458
- if (record.remoteNodeId !== undefined &&
10459
- (typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
10355
+ if (record.initialWindow !== undefined &&
10356
+ (!Number.isFinite(record.initialWindow) ||
10357
+ record.initialWindow <= 0)) {
10460
10358
  return false;
10461
10359
  }
10462
10360
  return true;
@@ -10492,19 +10390,14 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
10492
10390
  }
10493
10391
  result.inboxCapacity = Math.floor(inboxValue);
10494
10392
  }
10495
- const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
10496
- if (localNodeIdValue !== undefined) {
10497
- if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
10498
- throw new TypeError('BroadcastChannelConnectionGrant "localNodeId" must be a non-empty string when provided');
10499
- }
10500
- result.localNodeId = localNodeIdValue.trim();
10501
- }
10502
- const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
10503
- if (remoteNodeIdValue !== undefined) {
10504
- if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
10505
- throw new TypeError('BroadcastChannelConnectionGrant "remoteNodeId" must be a non-empty string when provided');
10393
+ const windowValue = candidate.initialWindow ?? candidate['initial_window'];
10394
+ if (windowValue !== undefined) {
10395
+ if (typeof windowValue !== 'number' ||
10396
+ !Number.isFinite(windowValue) ||
10397
+ windowValue <= 0) {
10398
+ throw new TypeError('BroadcastChannelConnectionGrant "initialWindow" must be a positive number when provided');
10506
10399
  }
10507
- result.remoteNodeId = remoteNodeIdValue.trim();
10400
+ result.initialWindow = Math.floor(windowValue);
10508
10401
  }
10509
10402
  return result;
10510
10403
  }
@@ -10519,11 +10412,8 @@ function broadcastChannelGrantToConnectorConfig(grant) {
10519
10412
  if (normalized.inboxCapacity !== undefined) {
10520
10413
  config.inboxCapacity = normalized.inboxCapacity;
10521
10414
  }
10522
- if (normalized.localNodeId) {
10523
- config.localNodeId = normalized.localNodeId;
10524
- }
10525
- if (normalized.remoteNodeId) {
10526
- config.remoteNodeId = normalized.remoteNodeId;
10415
+ if (normalized.initialWindow !== undefined) {
10416
+ config.initialWindow = normalized.initialWindow;
10527
10417
  }
10528
10418
  return config;
10529
10419
  }
@@ -10815,12 +10705,6 @@ class UpstreamSessionManager extends TaskSpawner {
10815
10705
  cryptoProvider.prepareForAttach(welcome.frame.systemId, welcome.frame.assignedPath, welcome.frame.acceptedLogicals ?? []);
10816
10706
  }
10817
10707
  await this.onWelcome(welcome.frame);
10818
- // Inject node ID into grant for transport frame multiplexing
10819
- // This ensures localNodeId matches the node's systemId for proper frame filtering
10820
- grant.localNodeId = welcome.frame.systemId;
10821
- if (welcome.frame.targetSystemId) {
10822
- grant.remoteNodeId = welcome.frame.targetSystemId;
10823
- }
10824
10708
  const connector = await ConnectorFactory.createConnector(grant, {
10825
10709
  systemId: welcome.frame.systemId,
10826
10710
  });
@@ -12777,20 +12661,6 @@ class DefaultNodeAttachClient {
12777
12661
  if (!targetSystemId) {
12778
12662
  throw new Error('Target system ID must be set in NodeAttachAckFrame on success');
12779
12663
  }
12780
- // Update connector's remote node ID if it supports it (e.g., BroadcastChannelConnector, InPageConnector)
12781
- // This allows upstream connectors to switch from wildcard '*' to specific node addressing
12782
- const updatableConnector = connector;
12783
- if (typeof updatableConnector.updateRemoteNodeId === 'function') {
12784
- try {
12785
- updatableConnector.updateRemoteNodeId(targetSystemId);
12786
- }
12787
- catch (error) {
12788
- logger$W.debug('connector_remote_node_id_update_failed', {
12789
- target_system_id: targetSystemId,
12790
- error: error instanceof Error ? error.message : String(error),
12791
- });
12792
- }
12793
- }
12794
12664
  try {
12795
12665
  if (this.replicaStickinessManager) {
12796
12666
  this.replicaStickinessManager.accept(ackFrame.stickiness ?? null);
@@ -20491,20 +20361,9 @@ class InPageConnector extends BaseAsyncConnector {
20491
20361
  : DEFAULT_INBOX_CAPACITY$6;
20492
20362
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
20493
20363
  this.connectorId = InPageConnector.generateConnectorId();
20494
- // Set local and remote node IDs (defaults to connector ID for backwards compatibility)
20495
- this.localNodeId =
20496
- typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
20497
- ? config.localNodeId.trim()
20498
- : this.connectorId;
20499
- this.remoteNodeId =
20500
- typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
20501
- ? config.remoteNodeId.trim()
20502
- : '*'; // Accept from any remote if not specified
20503
20364
  logger$G.debug('inpage_connector_initialized', {
20504
20365
  channel: this.channelName,
20505
20366
  connector_id: this.connectorId,
20506
- local_node_id: this.localNodeId,
20507
- remote_node_id: this.remoteNodeId,
20508
20367
  });
20509
20368
  this.onMsg = (event) => {
20510
20369
  const messageEvent = event;
@@ -20538,64 +20397,6 @@ class InPageConnector extends BaseAsyncConnector {
20538
20397
  if (busMessage.senderId === this.connectorId) {
20539
20398
  return;
20540
20399
  }
20541
- // Try to unwrap as transport frame
20542
- const frame = unwrapTransportFrame(busMessage.payload);
20543
- if (frame) {
20544
- // Apply connector's filtering policy: strict dst check, src accepts wildcard
20545
- const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
20546
- const dstMatches = frame.dst === this.localNodeId;
20547
- if (dstMatches && srcMatches) {
20548
- // Successfully received and filtered transport frame
20549
- logger$G.debug('inpage_transport_frame_received', {
20550
- channel: this.channelName,
20551
- sender_id: busMessage.senderId,
20552
- connector_id: this.connectorId,
20553
- local_node_id: this.localNodeId,
20554
- remote_node_id: this.remoteNodeId,
20555
- frame_src: frame.src,
20556
- frame_dst: frame.dst,
20557
- payload_length: frame.payload.byteLength,
20558
- });
20559
- const unwrapped = frame.payload;
20560
- try {
20561
- if (typeof this.inbox.tryEnqueue === 'function') {
20562
- const accepted = this.inbox.tryEnqueue(unwrapped);
20563
- if (accepted) {
20564
- return;
20565
- }
20566
- }
20567
- this.inbox.enqueue(unwrapped);
20568
- }
20569
- catch (error) {
20570
- if (error instanceof QueueFullError) {
20571
- logger$G.warning('inpage_receive_queue_full', {
20572
- channel: this.channelName,
20573
- });
20574
- }
20575
- else {
20576
- logger$G.error('inpage_receive_error', {
20577
- channel: this.channelName,
20578
- error: error instanceof Error ? error.message : String(error),
20579
- });
20580
- }
20581
- }
20582
- return;
20583
- }
20584
- else {
20585
- // Frame filtered out by addressing rules
20586
- logger$G.debug('inpage_transport_frame_filtered', {
20587
- channel: this.channelName,
20588
- connector_id: this.connectorId,
20589
- local_node_id: this.localNodeId,
20590
- remote_node_id: this.remoteNodeId,
20591
- frame_src: frame.src,
20592
- frame_dst: frame.dst,
20593
- reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
20594
- });
20595
- return;
20596
- }
20597
- }
20598
- // Fall back to legacy format (no transport frame)
20599
20400
  const payload = InPageConnector.coercePayload(busMessage.payload);
20600
20401
  if (!payload) {
20601
20402
  logger$G.debug('inpage_payload_rejected', {
@@ -20754,27 +20555,11 @@ class InPageConnector extends BaseAsyncConnector {
20754
20555
  logger$G.debug('inpage_message_sending', {
20755
20556
  channel: this.channelName,
20756
20557
  sender_id: this.connectorId,
20757
- local_node_id: this.localNodeId,
20758
- remote_node_id: this.remoteNodeId,
20759
- });
20760
- // Only use transport framing if both localNodeId and remoteNodeId are explicitly set
20761
- // (not using default values). This ensures backwards compatibility.
20762
- const useTransportFrame = this.localNodeId !== this.connectorId ||
20763
- this.remoteNodeId !== '*';
20764
- let payload;
20765
- if (useTransportFrame) {
20766
- // Wrap payload in transport frame
20767
- const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
20768
- payload = serializeTransportFrame(frame);
20769
- }
20770
- else {
20771
- // Legacy format: send raw payload
20772
- payload = data;
20773
- }
20558
+ });
20774
20559
  const event = new MessageEvent(this.channelName, {
20775
20560
  data: {
20776
20561
  senderId: this.connectorId,
20777
- payload,
20562
+ payload: data,
20778
20563
  },
20779
20564
  });
20780
20565
  getSharedBus$1().dispatchEvent(event);
@@ -20803,24 +20588,6 @@ class InPageConnector extends BaseAsyncConnector {
20803
20588
  }
20804
20589
  return rawOrEnvelope;
20805
20590
  }
20806
- /**
20807
- * Update the remote node ID after learning it from NodeAttachAck
20808
- * This allows upstream connectors to switch from wildcard to specific addressing
20809
- */
20810
- updateRemoteNodeId(newRemoteNodeId) {
20811
- if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
20812
- throw new Error('Invalid remote node ID');
20813
- }
20814
- const oldValue = this.remoteNodeId;
20815
- this.remoteNodeId = newRemoteNodeId.trim();
20816
- logger$G.debug('inpage_connector_remote_node_id_updated', {
20817
- channel: this.channelName,
20818
- connector_id: this.connectorId,
20819
- local_node_id: this.localNodeId,
20820
- old_remote_node_id: oldValue,
20821
- new_remote_node_id: this.remoteNodeId,
20822
- });
20823
- }
20824
20591
  }
20825
20592
 
20826
20593
  const RPC_REGISTRY = Symbol('naylence.rpc.registry');
@@ -28157,14 +27924,6 @@ function isInPageConnectionGrant(candidate) {
28157
27924
  record.inboxCapacity <= 0)) {
28158
27925
  return false;
28159
27926
  }
28160
- if (record.localNodeId !== undefined &&
28161
- (typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
28162
- return false;
28163
- }
28164
- if (record.remoteNodeId !== undefined &&
28165
- (typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
28166
- return false;
28167
- }
28168
27927
  return true;
28169
27928
  }
28170
27929
  function normalizeInPageConnectionGrant(candidate) {
@@ -28198,20 +27957,6 @@ function normalizeInPageConnectionGrant(candidate) {
28198
27957
  }
28199
27958
  result.inboxCapacity = Math.floor(inboxValue);
28200
27959
  }
28201
- const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
28202
- if (localNodeIdValue !== undefined) {
28203
- if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
28204
- throw new TypeError('InPageConnectionGrant "localNodeId" must be a non-empty string when provided');
28205
- }
28206
- result.localNodeId = localNodeIdValue.trim();
28207
- }
28208
- const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
28209
- if (remoteNodeIdValue !== undefined) {
28210
- if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
28211
- throw new TypeError('InPageConnectionGrant "remoteNodeId" must be a non-empty string when provided');
28212
- }
28213
- result.remoteNodeId = remoteNodeIdValue.trim();
28214
- }
28215
27960
  return result;
28216
27961
  }
28217
27962
  function inPageGrantToConnectorConfig(grant) {
@@ -28225,12 +27970,6 @@ function inPageGrantToConnectorConfig(grant) {
28225
27970
  if (normalized.inboxCapacity !== undefined) {
28226
27971
  config.inboxCapacity = normalized.inboxCapacity;
28227
27972
  }
28228
- if (normalized.localNodeId) {
28229
- config.localNodeId = normalized.localNodeId;
28230
- }
28231
- if (normalized.remoteNodeId) {
28232
- config.remoteNodeId = normalized.remoteNodeId;
28233
- }
28234
27973
  return config;
28235
27974
  }
28236
27975
 
@@ -28808,8 +28547,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28808
28547
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
28809
28548
  channelName: connectorConfig.channelName,
28810
28549
  inboxCapacity: connectorConfig.inboxCapacity,
28811
- localNodeId: connectorConfig.localNodeId,
28812
- remoteNodeId: connectorConfig.remoteNodeId,
28550
+ initialWindow: connectorConfig.initialWindow,
28813
28551
  };
28814
28552
  }
28815
28553
  const config = {
@@ -28834,6 +28572,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28834
28572
  purpose: 'connection',
28835
28573
  channelName: normalizedConfig.channelName,
28836
28574
  inboxCapacity: normalizedConfig.inboxCapacity,
28575
+ initialWindow: normalizedConfig.initialWindow,
28837
28576
  });
28838
28577
  return grant;
28839
28578
  }
@@ -28859,8 +28598,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28859
28598
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
28860
28599
  channelName,
28861
28600
  inboxCapacity,
28862
- localNodeId: normalized.localNodeId,
28863
- remoteNodeId: normalized.remoteNodeId,
28864
28601
  };
28865
28602
  const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
28866
28603
  if (options.authorization) {
@@ -28922,16 +28659,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28922
28659
  if (candidate.authorizationContext !== undefined) {
28923
28660
  normalized.authorizationContext = candidate.authorizationContext;
28924
28661
  }
28925
- // Handle localNodeId
28926
- const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
28927
- if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
28928
- normalized.localNodeId = localNodeId.trim();
28929
- }
28930
- // Handle remoteNodeId
28931
- const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
28932
- if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
28933
- normalized.remoteNodeId = remoteNodeId.trim();
28934
- }
28935
28662
  normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$5;
28936
28663
  normalized.inboxCapacity =
28937
28664
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
@@ -29495,8 +29222,6 @@ class InPageConnectorFactory extends ConnectorFactory {
29495
29222
  type: INPAGE_CONNECTOR_TYPE,
29496
29223
  channelName,
29497
29224
  inboxCapacity,
29498
- localNodeId: normalized.localNodeId,
29499
- remoteNodeId: normalized.remoteNodeId,
29500
29225
  };
29501
29226
  const connector = new InPageConnector(connectorConfig, baseConfig);
29502
29227
  if (options.authorization) {
@@ -29565,16 +29290,6 @@ class InPageConnectorFactory extends ConnectorFactory {
29565
29290
  if (candidate.authorizationContext !== undefined) {
29566
29291
  normalized.authorizationContext = candidate.authorizationContext;
29567
29292
  }
29568
- // Handle localNodeId
29569
- const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
29570
- if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
29571
- normalized.localNodeId = localNodeId.trim();
29572
- }
29573
- // Handle remoteNodeId
29574
- const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
29575
- if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
29576
- normalized.remoteNodeId = remoteNodeId.trim();
29577
- }
29578
29293
  normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$3;
29579
29294
  normalized.inboxCapacity =
29580
29295
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$3;
@@ -36340,18 +36055,13 @@ class BroadcastChannelListener extends TransportListener {
36340
36055
  });
36341
36056
  }
36342
36057
  asCallbackGrant() {
36343
- const grant = {
36058
+ return this.withLegacySnakeCaseKeys({
36344
36059
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
36345
36060
  connectorType: BROADCAST_CHANNEL_CONNECTOR_TYPE,
36346
36061
  connectionGrantType: BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE,
36347
36062
  channelName: this._channelName,
36348
36063
  inboxCapacity: this._inboxCapacity,
36349
- };
36350
- // Include localNodeId for transport frame multiplexing if node is available
36351
- if (this._routingNode) {
36352
- grant.localNodeId = this._routingNode.id;
36353
- }
36354
- return this.withLegacySnakeCaseKeys(grant);
36064
+ });
36355
36065
  }
36356
36066
  _registerChannelListener() {
36357
36067
  if (this._channelHandler) {
@@ -36411,54 +36121,23 @@ class BroadcastChannelListener extends TransportListener {
36411
36121
  if (typeof senderId !== 'string' || senderId.length === 0) {
36412
36122
  return null;
36413
36123
  }
36414
- // Check if payload is a transport frame object first
36415
- let envelopePayload = null;
36416
- if (this._routingNode && record.payload && typeof record.payload === 'object') {
36417
- // Try to unwrap as transport frame
36418
- const frame = unwrapTransportFrame(record.payload);
36419
- if (frame) {
36420
- // Apply listener's filtering policy: accept frames addressed to us OR with wildcard destination
36421
- // Wildcard is needed because downstream nodes don't know the sentinel's ID during initial attach
36422
- const isAddressedToUs = frame.dst === this._routingNode.id || frame.dst === '*';
36423
- if (isAddressedToUs) {
36424
- envelopePayload = frame.payload;
36425
- logger$a.debug('broadcast_channel_listener_unwrapped_transport_frame', {
36426
- sender_id: senderId,
36427
- src: frame.src,
36428
- dst: frame.dst,
36429
- });
36430
- }
36431
- else {
36432
- // Frame addressed to a different node, ignore it
36433
- logger$a.debug('broadcast_channel_listener_ignored_frame_wrong_destination', {
36434
- sender_id: senderId,
36435
- dst: frame.dst,
36436
- expected: this._routingNode.id,
36437
- });
36438
- return null;
36439
- }
36440
- }
36441
- }
36442
- // If not a transport frame, try to coerce as legacy format
36443
- if (!envelopePayload) {
36444
- envelopePayload = coercePayload$1(record.payload);
36445
- if (!envelopePayload) {
36446
- logger$a.debug('broadcast_channel_listener_ignored_event_without_payload', {
36447
- sender_id: senderId,
36448
- });
36449
- return null;
36450
- }
36124
+ const payload = coercePayload$1(record.payload);
36125
+ if (!payload) {
36126
+ logger$a.debug('broadcast_channel_listener_ignored_event_without_payload', {
36127
+ sender_id: senderId,
36128
+ });
36129
+ return null;
36451
36130
  }
36452
36131
  let envelope;
36453
36132
  try {
36454
- const decoded = new TextDecoder().decode(envelopePayload);
36133
+ const decoded = new TextDecoder().decode(payload);
36455
36134
  const parsed = JSON.parse(decoded);
36456
36135
  envelope = deserializeEnvelope(parsed);
36457
36136
  }
36458
36137
  catch (error) {
36459
36138
  const decoded = (() => {
36460
36139
  try {
36461
- return new TextDecoder().decode(envelopePayload);
36140
+ return new TextDecoder().decode(payload);
36462
36141
  }
36463
36142
  catch {
36464
36143
  return null;
@@ -36578,20 +36257,6 @@ class BroadcastChannelListener extends TransportListener {
36578
36257
  inboxCapacity: this._inboxCapacity,
36579
36258
  };
36580
36259
  }
36581
- // Automatically configure transport frame multiplexing:
36582
- // Use node IDs (not connector IDs) for node-to-node targeting
36583
- const broadcastConfig = connectorConfig;
36584
- // Always force localNodeId to be this listener's node ID
36585
- // This ensures the sentinel sets localNodeId=sentinel, not the child's ID
36586
- broadcastConfig.localNodeId = routingNode.id;
36587
- // Always force remoteNodeId to be the attaching child's system ID
36588
- broadcastConfig.remoteNodeId = systemId;
36589
- logger$a.debug('broadcast_channel_listener_configured_node_ids', {
36590
- sender_id: params.senderId,
36591
- system_id: systemId,
36592
- local_node_id: broadcastConfig.localNodeId,
36593
- remote_node_id: broadcastConfig.remoteNodeId,
36594
- });
36595
36260
  try {
36596
36261
  const connector = await routingNode.createOriginConnector({
36597
36262
  originType,
@@ -36661,21 +36326,6 @@ class BroadcastChannelListener extends TransportListener {
36661
36326
  inboxCandidate > 0) {
36662
36327
  config.inboxCapacity = Math.floor(inboxCandidate);
36663
36328
  }
36664
- // Extract transport frame multiplexing node IDs
36665
- const localNodeIdCandidate = candidate.localNodeId ?? candidate['local_node_id'];
36666
- if (typeof localNodeIdCandidate === 'string' && localNodeIdCandidate.trim().length > 0) {
36667
- config.localNodeId = localNodeIdCandidate.trim();
36668
- logger$a.debug('broadcast_channel_listener_extracted_local_node_id', {
36669
- local_node_id: config.localNodeId,
36670
- });
36671
- }
36672
- const remoteNodeIdCandidate = candidate.remoteNodeId ?? candidate['remote_node_id'];
36673
- if (typeof remoteNodeIdCandidate === 'string' && remoteNodeIdCandidate.trim().length > 0) {
36674
- config.remoteNodeId = remoteNodeIdCandidate.trim();
36675
- logger$a.debug('broadcast_channel_listener_extracted_remote_node_id', {
36676
- remote_node_id: config.remoteNodeId,
36677
- });
36678
- }
36679
36329
  return config;
36680
36330
  }
36681
36331
  _monitorConnectorLifecycle(senderId, systemId, connector) {
@@ -37398,7 +37048,6 @@ class InPageListener extends TransportListener {
37398
37048
  this._busHandler = null;
37399
37049
  this._senderRegistry = new Map();
37400
37050
  this._systemToSender = new Map();
37401
- this._flowIdToSender = new Map();
37402
37051
  this._pendingAttachments = new Map();
37403
37052
  ensureBrowserEnvironment();
37404
37053
  const channelCandidate = options?.channelName;
@@ -37465,7 +37114,6 @@ class InPageListener extends TransportListener {
37465
37114
  this._unregisterBusListener();
37466
37115
  this._senderRegistry.clear();
37467
37116
  this._systemToSender.clear();
37468
- this._flowIdToSender.clear();
37469
37117
  this._pendingAttachments.clear();
37470
37118
  logger$7.debug('inpage_listener_stopped', {
37471
37119
  channel: this._channelName,
@@ -37519,25 +37167,10 @@ class InPageListener extends TransportListener {
37519
37167
  await this._handleAttachFrame(senderId, envelope);
37520
37168
  return;
37521
37169
  }
37522
- // Try to find connector by sender ID first
37523
- let entry = this._senderRegistry.get(senderId);
37524
- // If not found and we have a flowId, try to route based on flow
37525
- if (!entry && envelope.flowId) {
37526
- const originalSenderId = this._flowIdToSender.get(envelope.flowId);
37527
- if (originalSenderId) {
37528
- entry = this._senderRegistry.get(originalSenderId);
37529
- logger$7.debug('inpage_listener_routed_by_flow_id', {
37530
- sender_id: senderId,
37531
- original_sender_id: originalSenderId,
37532
- flow_id: envelope.flowId,
37533
- frame_type: envelope.frame?.type ?? 'unknown',
37534
- });
37535
- }
37536
- }
37170
+ const entry = this._senderRegistry.get(senderId);
37537
37171
  if (!entry) {
37538
37172
  logger$7.debug('inpage_listener_no_connector_for_sender', {
37539
37173
  sender_id: senderId,
37540
- flow_id: envelope.flowId,
37541
37174
  frame_type: envelope.frame?.type ?? 'unknown',
37542
37175
  });
37543
37176
  return;
@@ -37614,15 +37247,6 @@ class InPageListener extends TransportListener {
37614
37247
  }
37615
37248
  this._senderRegistry.set(senderId, entry);
37616
37249
  this._systemToSender.set(entry.systemId, senderId);
37617
- // Track the flowId if present so we can route responses back
37618
- if (envelope.flowId) {
37619
- this._flowIdToSender.set(envelope.flowId, senderId);
37620
- logger$7.debug('inpage_listener_registered_flow_id', {
37621
- sender_id: senderId,
37622
- system_id: entry.systemId,
37623
- flow_id: envelope.flowId,
37624
- });
37625
- }
37626
37250
  await this._deliverEnvelope(entry, envelope);
37627
37251
  }
37628
37252
  async _createConnectorForAttach(params) {
@@ -37670,7 +37294,7 @@ class InPageListener extends TransportListener {
37670
37294
  origin_type: originType,
37671
37295
  connector_type: connector.constructor?.name ?? 'unknown',
37672
37296
  });
37673
- return { connector, systemId, originType, senderId: params.senderId };
37297
+ return { connector, systemId, originType };
37674
37298
  }
37675
37299
  catch (error) {
37676
37300
  logger$7.error('inpage_listener_connector_creation_failed', {
@@ -37724,12 +37348,6 @@ class InPageListener extends TransportListener {
37724
37348
  if (this._systemToSender.get(systemId) === senderId) {
37725
37349
  this._systemToSender.delete(systemId);
37726
37350
  }
37727
- // Clean up flowId mappings for this sender
37728
- for (const [flowId, sid] of this._flowIdToSender.entries()) {
37729
- if (sid === senderId) {
37730
- this._flowIdToSender.delete(flowId);
37731
- }
37732
- }
37733
37351
  })
37734
37352
  .catch((error) => {
37735
37353
  logger$7.debug('inpage_listener_wait_until_closed_failed', {
@@ -37741,24 +37359,9 @@ class InPageListener extends TransportListener {
37741
37359
  if (this._systemToSender.get(systemId) === senderId) {
37742
37360
  this._systemToSender.delete(systemId);
37743
37361
  }
37744
- // Clean up flowId mappings for this sender
37745
- for (const [flowId, sid] of this._flowIdToSender.entries()) {
37746
- if (sid === senderId) {
37747
- this._flowIdToSender.delete(flowId);
37748
- }
37749
- }
37750
37362
  });
37751
37363
  }
37752
37364
  async _deliverEnvelope(entry, envelope) {
37753
- // Track flowId for routing responses back
37754
- if (envelope.flowId && !this._flowIdToSender.has(envelope.flowId)) {
37755
- this._flowIdToSender.set(envelope.flowId, entry.senderId);
37756
- logger$7.debug('inpage_listener_registered_flow_id_on_delivery', {
37757
- sender_id: entry.senderId,
37758
- system_id: entry.systemId,
37759
- flow_id: envelope.flowId,
37760
- });
37761
- }
37762
37365
  const message = this._buildChannelMessage({
37763
37366
  envelope,
37764
37367
  connector: entry.connector,