@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
@@ -96,12 +96,12 @@ installProcessEnvShim();
96
96
  // --- END ENV SHIM ---
97
97
 
98
98
  // This file is auto-generated during build - do not edit manually
99
- // Generated from package.json version: 0.3.5-test.953
99
+ // Generated from package.json version: 0.3.5-test.955
100
100
  /**
101
101
  * The package version, injected at build time.
102
102
  * @internal
103
103
  */
104
- const VERSION = '0.3.5-test.953';
104
+ const VERSION = '0.3.5-test.955';
105
105
 
106
106
  /**
107
107
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -919,7 +919,7 @@ class TaskCancelledError extends Error {
919
919
  * Provides functionality similar to Python's asyncio TaskSpawner with proper
920
920
  * error handling, cancellation, and graceful shutdown capabilities.
921
921
  */
922
- const logger$1b = getLogger('naylence.fame.util.task_spawner');
922
+ const logger$1c = getLogger('naylence.fame.util.task_spawner');
923
923
  function firstDefined(source, keys) {
924
924
  for (const key of keys) {
925
925
  if (Object.prototype.hasOwnProperty.call(source, key)) {
@@ -1080,7 +1080,7 @@ class TaskSpawner {
1080
1080
  const taskId = `task-${++this._taskCounter}`;
1081
1081
  const taskName = normalizedOptions.name || `unnamed-${taskId}`;
1082
1082
  const timeout = normalizedOptions.timeout ?? this._config.defaultTimeout;
1083
- logger$1b.debug('starting_background_task', {
1083
+ logger$1c.debug('starting_background_task', {
1084
1084
  task_name: taskName,
1085
1085
  task_id: taskId,
1086
1086
  });
@@ -1097,7 +1097,7 @@ class TaskSpawner {
1097
1097
  task.promise
1098
1098
  .then(() => {
1099
1099
  if (!this._suppressCompletionLogging) {
1100
- logger$1b.debug('task_completed_successfully', {
1100
+ logger$1c.debug('task_completed_successfully', {
1101
1101
  task_name: taskName,
1102
1102
  task_id: taskId,
1103
1103
  duration_ms: Date.now() - task.startTime,
@@ -1151,7 +1151,7 @@ class TaskSpawner {
1151
1151
  error.name === 'AbortError' ||
1152
1152
  error.message === 'Task cancelled' ||
1153
1153
  error.message === 'Aborted') {
1154
- logger$1b.debug('task_cancelled', {
1154
+ logger$1c.debug('task_cancelled', {
1155
1155
  task_name: taskName,
1156
1156
  note: 'Task cancelled as requested',
1157
1157
  });
@@ -1159,7 +1159,7 @@ class TaskSpawner {
1159
1159
  }
1160
1160
  // Handle timeout
1161
1161
  if (error instanceof TaskTimeoutError) {
1162
- logger$1b.warning('task_timed_out', {
1162
+ logger$1c.warning('task_timed_out', {
1163
1163
  task_name: taskName,
1164
1164
  error: error.message,
1165
1165
  });
@@ -1171,7 +1171,7 @@ class TaskSpawner {
1171
1171
  // Handle known WebSocket shutdown race condition (similar to Python version)
1172
1172
  if (error.message.includes("await wasn't used with future") ||
1173
1173
  error.message.includes('WebSocket closed during receive')) {
1174
- logger$1b.debug('task_shutdown_race_condition_handled', {
1174
+ logger$1c.debug('task_shutdown_race_condition_handled', {
1175
1175
  task_name: taskName,
1176
1176
  note: 'Normal WebSocket close timing during shutdown - not an error',
1177
1177
  });
@@ -1181,7 +1181,7 @@ class TaskSpawner {
1181
1181
  if (error.name === 'FameTransportClose' ||
1182
1182
  error.message.includes('normal closure') ||
1183
1183
  error.message.includes('Connection closed')) {
1184
- logger$1b.debug('task_shutdown_completed_normally', {
1184
+ logger$1c.debug('task_shutdown_completed_normally', {
1185
1185
  task_name: taskName,
1186
1186
  note: 'Task closed normally during shutdown',
1187
1187
  });
@@ -1194,14 +1194,14 @@ class TaskSpawner {
1194
1194
  // Log retriable errors as warnings (they'll be retried by upstream logic)
1195
1195
  // Log non-retriable errors as errors (fatal failures)
1196
1196
  if (isRetriableError) {
1197
- logger$1b.warning('background_task_failed', {
1197
+ logger$1c.warning('background_task_failed', {
1198
1198
  task_name: taskName,
1199
1199
  error: error.message,
1200
1200
  retriable: true,
1201
1201
  });
1202
1202
  }
1203
1203
  else {
1204
- logger$1b.error('background_task_failed', {
1204
+ logger$1c.error('background_task_failed', {
1205
1205
  task_name: taskName,
1206
1206
  error: error.message,
1207
1207
  stack: error.stack,
@@ -1220,11 +1220,11 @@ class TaskSpawner {
1220
1220
  async shutdownTasks(options = {}) {
1221
1221
  const { gracePeriod, cancelHanging, joinTimeout } = normalizeShutdownOptions(options);
1222
1222
  if (this._tasks.size === 0) {
1223
- logger$1b.debug('shutdown_tasks_no_tasks_to_shutdown');
1223
+ logger$1c.debug('shutdown_tasks_no_tasks_to_shutdown');
1224
1224
  return;
1225
1225
  }
1226
1226
  this._suppressCompletionLogging = true;
1227
- logger$1b.debug('shutting_down_tasks', {
1227
+ logger$1c.debug('shutting_down_tasks', {
1228
1228
  task_count: this._tasks.size,
1229
1229
  task_names: Array.from(this._tasks.values()).map((t) => t.name),
1230
1230
  grace_period_ms: gracePeriod,
@@ -1239,7 +1239,7 @@ class TaskSpawner {
1239
1239
  if (cancelHanging) {
1240
1240
  const stillRunning = tasks.filter((task) => task.getState() === TaskState.RUNNING && !completed.has(task));
1241
1241
  if (stillRunning.length > 0) {
1242
- logger$1b.debug('tasks_did_not_complete_within_grace_period', {
1242
+ logger$1c.debug('tasks_did_not_complete_within_grace_period', {
1243
1243
  hanging_count: stillRunning.length,
1244
1244
  });
1245
1245
  // Wait for them to finish with individual timeouts
@@ -1249,7 +1249,7 @@ class TaskSpawner {
1249
1249
  }
1250
1250
  catch (error) {
1251
1251
  if (error instanceof TaskTimeoutError) {
1252
- logger$1b.warning('task_did_not_shutdown', {
1252
+ logger$1c.warning('task_did_not_shutdown', {
1253
1253
  task_name: task.name || task.id,
1254
1254
  join_timeout_ms: joinTimeout,
1255
1255
  });
@@ -1260,7 +1260,7 @@ class TaskSpawner {
1260
1260
  }
1261
1261
  else if (!(error instanceof TaskCancelledError)) {
1262
1262
  /* istanbul ignore next - unreachable defensive branch */
1263
- logger$1b.error('task_raised_during_cancellation', {
1263
+ logger$1c.error('task_raised_during_cancellation', {
1264
1264
  task_name: task.name || task.id,
1265
1265
  error: error instanceof Error ? error.message : String(error),
1266
1266
  });
@@ -2353,6 +2353,7 @@ function validateKeyCorrelationTtlSec(ttlSec) {
2353
2353
  * condition/promise and ensure at most one notifier coroutine exists for a
2354
2354
  * flow at any time.
2355
2355
  */
2356
+ const logger$1b = getLogger('naylence.fame.flow.flow_controller');
2356
2357
  /**
2357
2358
  * Simple condition variable implementation for TypeScript/Node.js
2358
2359
  * Similar to Python's asyncio.Condition
@@ -2478,8 +2479,17 @@ class FlowController {
2478
2479
  // clamp into [0, initialWindow]
2479
2480
  const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
2480
2481
  this.credits.set(flowId, newBalance);
2482
+ const crossedZero = prev <= 0 && newBalance > 0;
2483
+ logger$1b.debug('flow_controller_add_credits', {
2484
+ flow_id: flowId,
2485
+ delta,
2486
+ prev_balance: prev,
2487
+ new_balance: newBalance,
2488
+ initial_window: this.initialWindow,
2489
+ crossed_zero: crossedZero,
2490
+ });
2481
2491
  // wake waiters only if we crossed the zero boundary
2482
- if (prev <= 0 && newBalance > 0) {
2492
+ if (crossedZero) {
2483
2493
  this.wakeWaiters(flowId);
2484
2494
  }
2485
2495
  return newBalance;
@@ -2490,11 +2500,27 @@ class FlowController {
2490
2500
  async acquire(flowId) {
2491
2501
  this.ensureFlow(flowId);
2492
2502
  const condition = this.conditions.get(flowId);
2503
+ logger$1b.debug('flow_controller_acquire_attempt', {
2504
+ flow_id: flowId,
2505
+ current_balance: this.credits.get(flowId),
2506
+ });
2493
2507
  while (this.credits.get(flowId) <= 0) {
2508
+ logger$1b.debug('flow_controller_waiting_for_credit', {
2509
+ flow_id: flowId,
2510
+ });
2494
2511
  await condition.wait();
2512
+ logger$1b.debug('flow_controller_woke_with_credit', {
2513
+ flow_id: flowId,
2514
+ balance_after_wake: this.credits.get(flowId),
2515
+ });
2495
2516
  }
2496
2517
  const current = this.credits.get(flowId);
2497
2518
  this.credits.set(flowId, current - 1);
2519
+ logger$1b.debug('flow_controller_credit_consumed', {
2520
+ flow_id: flowId,
2521
+ prev_balance: current,
2522
+ remaining_balance: current - 1,
2523
+ });
2498
2524
  }
2499
2525
  /**
2500
2526
  * Consume *credits* immediately (non-blocking).
@@ -2514,6 +2540,12 @@ class FlowController {
2514
2540
  const current = this.credits.get(flowId);
2515
2541
  const remaining = Math.max(current - credits, 0);
2516
2542
  this.credits.set(flowId, remaining);
2543
+ logger$1b.debug('flow_controller_consume', {
2544
+ flow_id: flowId,
2545
+ requested: credits,
2546
+ prev_balance: current,
2547
+ remaining_balance: remaining,
2548
+ });
2517
2549
  return remaining;
2518
2550
  }
2519
2551
  /**
@@ -2534,6 +2566,10 @@ class FlowController {
2534
2566
  this.windowIds.delete(flowId);
2535
2567
  this.credits.set(flowId, this.initialWindow);
2536
2568
  this.wakeWaiters(flowId);
2569
+ logger$1b.debug('flow_controller_flow_reset', {
2570
+ flow_id: flowId,
2571
+ reset_balance: this.initialWindow,
2572
+ });
2537
2573
  }
2538
2574
  /**
2539
2575
  * Return `[windowId, flags]` for the next outbound envelope.
@@ -9816,84 +9852,6 @@ class BoundedAsyncQueue {
9816
9852
  }
9817
9853
  }
9818
9854
 
9819
- /**
9820
- * Transport frame layer for multiplexing logical links on physical channels.
9821
- *
9822
- * This lightweight framing layer wraps raw FAME payloads to enable multiple
9823
- * logical connections over a single physical channel (BroadcastChannel or InPage bus).
9824
- *
9825
- * The transport frame does NOT modify FAME envelopes - it only wraps the raw
9826
- * Uint8Array payload at the connector level.
9827
- */
9828
- /**
9829
- * Transport frame version for future compatibility
9830
- */
9831
- const TRANSPORT_FRAME_VERSION = 1;
9832
- /**
9833
- * Wrap a raw payload in a transport frame
9834
- *
9835
- * @param payload - Raw FAME envelope bytes
9836
- * @param srcNodeId - Local node ID (this connector)
9837
- * @param dstNodeId - Remote node ID (target connector)
9838
- * @returns Transport frame ready for transmission
9839
- */
9840
- function wrapTransportFrame(payload, srcNodeId, dstNodeId) {
9841
- return {
9842
- v: TRANSPORT_FRAME_VERSION,
9843
- src: srcNodeId,
9844
- dst: dstNodeId,
9845
- payload,
9846
- };
9847
- }
9848
- /**
9849
- * Serialize a transport frame for transmission over the bus
9850
- *
9851
- * @param frame - Transport frame to serialize
9852
- * @returns Serialized frame data ready for postMessage/dispatchEvent
9853
- */
9854
- function serializeTransportFrame(frame) {
9855
- // Convert Uint8Array to regular array for JSON serialization
9856
- const serializable = {
9857
- v: frame.v,
9858
- src: frame.src,
9859
- dst: frame.dst,
9860
- payload: Array.from(frame.payload),
9861
- };
9862
- return serializable;
9863
- }
9864
- /**
9865
- * Unwrap a transport frame (pure deserializer - no filtering)
9866
- *
9867
- * @param raw - Raw data from the bus
9868
- * @returns Unwrapped frame with payload as Uint8Array, or null if invalid structure
9869
- */
9870
- function unwrapTransportFrame(raw) {
9871
- // Validate basic structure
9872
- if (!raw || typeof raw !== 'object') {
9873
- return null;
9874
- }
9875
- const frame = raw;
9876
- // Check version
9877
- if (frame.v !== TRANSPORT_FRAME_VERSION) {
9878
- return null;
9879
- }
9880
- // Check src and dst
9881
- if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
9882
- return null;
9883
- }
9884
- // Extract payload
9885
- if (!frame.payload || !Array.isArray(frame.payload)) {
9886
- return null;
9887
- }
9888
- // Convert array back to Uint8Array and return full frame
9889
- return {
9890
- v: frame.v,
9891
- src: frame.src,
9892
- dst: frame.dst,
9893
- payload: Uint8Array.from(frame.payload),
9894
- };
9895
- }
9896
-
9897
9855
  const logger$_ = getLogger('naylence.fame.connector.broadcast_channel_connector');
9898
9856
  const BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
9899
9857
  const DEFAULT_CHANNEL$7 = 'naylence-fabric';
@@ -9957,22 +9915,12 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9957
9915
  ? Math.floor(config.inboxCapacity)
9958
9916
  : DEFAULT_INBOX_CAPACITY$7;
9959
9917
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
9918
+ this.inboxCapacity = preferredCapacity;
9960
9919
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
9961
9920
  this.channel = new BroadcastChannel(this.channelName);
9962
- // Set local and remote node IDs (defaults to connector ID for backwards compatibility)
9963
- this.localNodeId =
9964
- typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
9965
- ? config.localNodeId.trim()
9966
- : this.connectorId;
9967
- this.remoteNodeId =
9968
- typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
9969
- ? config.remoteNodeId.trim()
9970
- : '*'; // Accept from any remote if not specified
9971
9921
  logger$_.debug('broadcast_channel_connector_created', {
9972
9922
  channel: this.channelName,
9973
9923
  connector_id: this.connectorId,
9974
- local_node_id: this.localNodeId,
9975
- remote_node_id: this.remoteNodeId,
9976
9924
  inbox_capacity: preferredCapacity,
9977
9925
  timestamp: new Date().toISOString(),
9978
9926
  });
@@ -10005,67 +9953,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10005
9953
  if (busMessage.senderId === this.connectorId) {
10006
9954
  return;
10007
9955
  }
10008
- // Try to unwrap as transport frame
10009
- const frame = unwrapTransportFrame(busMessage.payload);
10010
- if (frame) {
10011
- // Apply connector's filtering policy: strict dst check, src accepts wildcard
10012
- const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
10013
- const dstMatches = frame.dst === this.localNodeId;
10014
- if (dstMatches && srcMatches) {
10015
- // Successfully received and filtered transport frame
10016
- logger$_.debug('broadcast_channel_transport_frame_received', {
10017
- channel: this.channelName,
10018
- sender_id: busMessage.senderId,
10019
- connector_id: this.connectorId,
10020
- local_node_id: this.localNodeId,
10021
- remote_node_id: this.remoteNodeId,
10022
- frame_src: frame.src,
10023
- frame_dst: frame.dst,
10024
- payload_length: frame.payload.byteLength,
10025
- });
10026
- const unwrapped = frame.payload;
10027
- if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
10028
- return;
10029
- }
10030
- try {
10031
- if (typeof this.inbox.tryEnqueue === 'function') {
10032
- const accepted = this.inbox.tryEnqueue(unwrapped);
10033
- if (accepted) {
10034
- return;
10035
- }
10036
- }
10037
- this.inbox.enqueue(unwrapped);
10038
- }
10039
- catch (error) {
10040
- if (error instanceof QueueFullError) {
10041
- logger$_.warning('broadcast_channel_receive_queue_full', {
10042
- channel: this.channelName,
10043
- });
10044
- }
10045
- else {
10046
- logger$_.error('broadcast_channel_receive_error', {
10047
- channel: this.channelName,
10048
- error: error instanceof Error ? error.message : String(error),
10049
- });
10050
- }
10051
- }
10052
- return;
10053
- }
10054
- else {
10055
- // Frame filtered out by addressing rules
10056
- logger$_.debug('broadcast_channel_transport_frame_filtered', {
10057
- channel: this.channelName,
10058
- connector_id: this.connectorId,
10059
- local_node_id: this.localNodeId,
10060
- remote_node_id: this.remoteNodeId,
10061
- frame_src: frame.src,
10062
- frame_dst: frame.dst,
10063
- reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
10064
- });
10065
- return;
10066
- }
10067
- }
10068
- // Fall back to legacy format (no transport frame)
10069
9956
  const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
10070
9957
  if (!payload) {
10071
9958
  logger$_.debug('broadcast_channel_payload_rejected', {
@@ -10088,15 +9975,27 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10088
9975
  if (typeof this.inbox.tryEnqueue === 'function') {
10089
9976
  const accepted = this.inbox.tryEnqueue(payload);
10090
9977
  if (accepted) {
9978
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9979
+ source: 'listener',
9980
+ enqueue_strategy: 'try',
9981
+ payload_length: payload.byteLength,
9982
+ });
10091
9983
  return;
10092
9984
  }
10093
9985
  }
10094
9986
  this.inbox.enqueue(payload);
9987
+ this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
9988
+ source: 'listener',
9989
+ enqueue_strategy: 'enqueue',
9990
+ payload_length: payload.byteLength,
9991
+ });
10095
9992
  }
10096
9993
  catch (error) {
10097
9994
  if (error instanceof QueueFullError) {
10098
9995
  logger$_.warning('broadcast_channel_receive_queue_full', {
10099
9996
  channel: this.channelName,
9997
+ inbox_capacity: this.inboxCapacity,
9998
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10100
9999
  });
10101
10000
  }
10102
10001
  else {
@@ -10180,15 +10079,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10180
10079
  if (typeof this.inbox.tryEnqueue === 'function') {
10181
10080
  const accepted = this.inbox.tryEnqueue(item);
10182
10081
  if (accepted) {
10082
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10083
+ enqueue_strategy: 'try',
10084
+ item_type: this._describeInboxItem(item),
10085
+ });
10183
10086
  return;
10184
10087
  }
10185
10088
  }
10186
10089
  this.inbox.enqueue(item);
10090
+ this.logInboxSnapshot('broadcast_channel_push_enqueued', {
10091
+ enqueue_strategy: 'enqueue',
10092
+ item_type: this._describeInboxItem(item),
10093
+ });
10187
10094
  }
10188
10095
  catch (error) {
10189
10096
  if (error instanceof QueueFullError) {
10190
10097
  logger$_.warning('broadcast_channel_push_queue_full', {
10191
10098
  channel: this.channelName,
10099
+ inbox_capacity: this.inboxCapacity,
10100
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10192
10101
  });
10193
10102
  throw error;
10194
10103
  }
@@ -10204,30 +10113,18 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10204
10113
  logger$_.debug('broadcast_channel_message_sending', {
10205
10114
  channel: this.channelName,
10206
10115
  sender_id: this.connectorId,
10207
- local_node_id: this.localNodeId,
10208
- remote_node_id: this.remoteNodeId,
10209
- });
10210
- // Only use transport framing if both localNodeId and remoteNodeId are explicitly set
10211
- // (not using default values). This ensures backwards compatibility.
10212
- const useTransportFrame = this.localNodeId !== this.connectorId ||
10213
- this.remoteNodeId !== '*';
10214
- let payload;
10215
- if (useTransportFrame) {
10216
- // Wrap payload in transport frame
10217
- const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
10218
- payload = serializeTransportFrame(frame);
10219
- }
10220
- else {
10221
- // Legacy format: send raw payload
10222
- payload = data;
10223
- }
10116
+ });
10224
10117
  this.channel.postMessage({
10225
10118
  senderId: this.connectorId,
10226
- payload,
10119
+ payload: data,
10227
10120
  });
10228
10121
  }
10229
10122
  async _transportReceive() {
10230
- return await this.inbox.dequeue();
10123
+ const item = await this.inbox.dequeue();
10124
+ this.logInboxSnapshot('broadcast_channel_inbox_dequeued', {
10125
+ item_type: this._describeInboxItem(item),
10126
+ });
10127
+ return item;
10231
10128
  }
10232
10129
  async _transportClose(code, reason) {
10233
10130
  logger$_.debug('broadcast_channel_transport_closing', {
@@ -10281,6 +10178,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10281
10178
  }
10282
10179
  return rawOrEnvelope;
10283
10180
  }
10181
+ _describeInboxItem(item) {
10182
+ if (item instanceof Uint8Array) {
10183
+ return 'bytes';
10184
+ }
10185
+ if (item.envelope) {
10186
+ return 'channel_message';
10187
+ }
10188
+ if (item.frame) {
10189
+ return 'envelope';
10190
+ }
10191
+ return 'unknown';
10192
+ }
10193
+ logInboxSnapshot(event, extra = {}) {
10194
+ logger$_.debug(event, {
10195
+ channel: this.channelName,
10196
+ connector_id: this.connectorId,
10197
+ connector_state: this.state,
10198
+ inbox_capacity: this.inboxCapacity,
10199
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
10200
+ ...extra,
10201
+ });
10202
+ }
10284
10203
  _shouldSkipDuplicateAck(senderId, payload) {
10285
10204
  const dedupKey = this._extractAckDedupKey(payload);
10286
10205
  if (!dedupKey) {
@@ -10379,24 +10298,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10379
10298
  });
10380
10299
  }
10381
10300
  }
10382
- /**
10383
- * Update the remote node ID after learning it from NodeAttachAck
10384
- * This allows upstream connectors to switch from wildcard to specific addressing
10385
- */
10386
- updateRemoteNodeId(newRemoteNodeId) {
10387
- if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
10388
- throw new Error('Invalid remote node ID');
10389
- }
10390
- const oldValue = this.remoteNodeId;
10391
- this.remoteNodeId = newRemoteNodeId.trim();
10392
- logger$_.debug('broadcast_channel_connector_remote_node_id_updated', {
10393
- channel: this.channelName,
10394
- connector_id: this.connectorId,
10395
- local_node_id: this.localNodeId,
10396
- old_remote_node_id: oldValue,
10397
- new_remote_node_id: this.remoteNodeId,
10398
- });
10399
- }
10400
10301
  _trimSeenAcks(now) {
10401
10302
  while (this.seenAckOrder.length > 0) {
10402
10303
  const candidate = this.seenAckOrder[0];
@@ -10534,12 +10435,9 @@ function isBroadcastChannelConnectionGrant(candidate) {
10534
10435
  record.inboxCapacity <= 0)) {
10535
10436
  return false;
10536
10437
  }
10537
- if (record.localNodeId !== undefined &&
10538
- (typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
10539
- return false;
10540
- }
10541
- if (record.remoteNodeId !== undefined &&
10542
- (typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
10438
+ if (record.initialWindow !== undefined &&
10439
+ (!Number.isFinite(record.initialWindow) ||
10440
+ record.initialWindow <= 0)) {
10543
10441
  return false;
10544
10442
  }
10545
10443
  return true;
@@ -10575,19 +10473,14 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
10575
10473
  }
10576
10474
  result.inboxCapacity = Math.floor(inboxValue);
10577
10475
  }
10578
- const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
10579
- if (localNodeIdValue !== undefined) {
10580
- if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
10581
- throw new TypeError('BroadcastChannelConnectionGrant "localNodeId" must be a non-empty string when provided');
10582
- }
10583
- result.localNodeId = localNodeIdValue.trim();
10584
- }
10585
- const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
10586
- if (remoteNodeIdValue !== undefined) {
10587
- if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
10588
- throw new TypeError('BroadcastChannelConnectionGrant "remoteNodeId" must be a non-empty string when provided');
10476
+ const windowValue = candidate.initialWindow ?? candidate['initial_window'];
10477
+ if (windowValue !== undefined) {
10478
+ if (typeof windowValue !== 'number' ||
10479
+ !Number.isFinite(windowValue) ||
10480
+ windowValue <= 0) {
10481
+ throw new TypeError('BroadcastChannelConnectionGrant "initialWindow" must be a positive number when provided');
10589
10482
  }
10590
- result.remoteNodeId = remoteNodeIdValue.trim();
10483
+ result.initialWindow = Math.floor(windowValue);
10591
10484
  }
10592
10485
  return result;
10593
10486
  }
@@ -10602,11 +10495,8 @@ function broadcastChannelGrantToConnectorConfig(grant) {
10602
10495
  if (normalized.inboxCapacity !== undefined) {
10603
10496
  config.inboxCapacity = normalized.inboxCapacity;
10604
10497
  }
10605
- if (normalized.localNodeId) {
10606
- config.localNodeId = normalized.localNodeId;
10607
- }
10608
- if (normalized.remoteNodeId) {
10609
- config.remoteNodeId = normalized.remoteNodeId;
10498
+ if (normalized.initialWindow !== undefined) {
10499
+ config.initialWindow = normalized.initialWindow;
10610
10500
  }
10611
10501
  return config;
10612
10502
  }
@@ -10898,12 +10788,6 @@ class UpstreamSessionManager extends TaskSpawner {
10898
10788
  cryptoProvider.prepareForAttach(welcome.frame.systemId, welcome.frame.assignedPath, welcome.frame.acceptedLogicals ?? []);
10899
10789
  }
10900
10790
  await this.onWelcome(welcome.frame);
10901
- // Inject node ID into grant for transport frame multiplexing
10902
- // This ensures localNodeId matches the node's systemId for proper frame filtering
10903
- grant.localNodeId = welcome.frame.systemId;
10904
- if (welcome.frame.targetSystemId) {
10905
- grant.remoteNodeId = welcome.frame.targetSystemId;
10906
- }
10907
10791
  const connector = await ConnectorFactory.createConnector(grant, {
10908
10792
  systemId: welcome.frame.systemId,
10909
10793
  });
@@ -12860,20 +12744,6 @@ class DefaultNodeAttachClient {
12860
12744
  if (!targetSystemId) {
12861
12745
  throw new Error('Target system ID must be set in NodeAttachAckFrame on success');
12862
12746
  }
12863
- // Update connector's remote node ID if it supports it (e.g., BroadcastChannelConnector, InPageConnector)
12864
- // This allows upstream connectors to switch from wildcard '*' to specific node addressing
12865
- const updatableConnector = connector;
12866
- if (typeof updatableConnector.updateRemoteNodeId === 'function') {
12867
- try {
12868
- updatableConnector.updateRemoteNodeId(targetSystemId);
12869
- }
12870
- catch (error) {
12871
- logger$W.debug('connector_remote_node_id_update_failed', {
12872
- target_system_id: targetSystemId,
12873
- error: error instanceof Error ? error.message : String(error),
12874
- });
12875
- }
12876
- }
12877
12747
  try {
12878
12748
  if (this.replicaStickinessManager) {
12879
12749
  this.replicaStickinessManager.accept(ackFrame.stickiness ?? null);
@@ -20574,20 +20444,9 @@ class InPageConnector extends BaseAsyncConnector {
20574
20444
  : DEFAULT_INBOX_CAPACITY$6;
20575
20445
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
20576
20446
  this.connectorId = InPageConnector.generateConnectorId();
20577
- // Set local and remote node IDs (defaults to connector ID for backwards compatibility)
20578
- this.localNodeId =
20579
- typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
20580
- ? config.localNodeId.trim()
20581
- : this.connectorId;
20582
- this.remoteNodeId =
20583
- typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
20584
- ? config.remoteNodeId.trim()
20585
- : '*'; // Accept from any remote if not specified
20586
20447
  logger$G.debug('inpage_connector_initialized', {
20587
20448
  channel: this.channelName,
20588
20449
  connector_id: this.connectorId,
20589
- local_node_id: this.localNodeId,
20590
- remote_node_id: this.remoteNodeId,
20591
20450
  });
20592
20451
  this.onMsg = (event) => {
20593
20452
  const messageEvent = event;
@@ -20621,64 +20480,6 @@ class InPageConnector extends BaseAsyncConnector {
20621
20480
  if (busMessage.senderId === this.connectorId) {
20622
20481
  return;
20623
20482
  }
20624
- // Try to unwrap as transport frame
20625
- const frame = unwrapTransportFrame(busMessage.payload);
20626
- if (frame) {
20627
- // Apply connector's filtering policy: strict dst check, src accepts wildcard
20628
- const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
20629
- const dstMatches = frame.dst === this.localNodeId;
20630
- if (dstMatches && srcMatches) {
20631
- // Successfully received and filtered transport frame
20632
- logger$G.debug('inpage_transport_frame_received', {
20633
- channel: this.channelName,
20634
- sender_id: busMessage.senderId,
20635
- connector_id: this.connectorId,
20636
- local_node_id: this.localNodeId,
20637
- remote_node_id: this.remoteNodeId,
20638
- frame_src: frame.src,
20639
- frame_dst: frame.dst,
20640
- payload_length: frame.payload.byteLength,
20641
- });
20642
- const unwrapped = frame.payload;
20643
- try {
20644
- if (typeof this.inbox.tryEnqueue === 'function') {
20645
- const accepted = this.inbox.tryEnqueue(unwrapped);
20646
- if (accepted) {
20647
- return;
20648
- }
20649
- }
20650
- this.inbox.enqueue(unwrapped);
20651
- }
20652
- catch (error) {
20653
- if (error instanceof QueueFullError) {
20654
- logger$G.warning('inpage_receive_queue_full', {
20655
- channel: this.channelName,
20656
- });
20657
- }
20658
- else {
20659
- logger$G.error('inpage_receive_error', {
20660
- channel: this.channelName,
20661
- error: error instanceof Error ? error.message : String(error),
20662
- });
20663
- }
20664
- }
20665
- return;
20666
- }
20667
- else {
20668
- // Frame filtered out by addressing rules
20669
- logger$G.debug('inpage_transport_frame_filtered', {
20670
- channel: this.channelName,
20671
- connector_id: this.connectorId,
20672
- local_node_id: this.localNodeId,
20673
- remote_node_id: this.remoteNodeId,
20674
- frame_src: frame.src,
20675
- frame_dst: frame.dst,
20676
- reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
20677
- });
20678
- return;
20679
- }
20680
- }
20681
- // Fall back to legacy format (no transport frame)
20682
20483
  const payload = InPageConnector.coercePayload(busMessage.payload);
20683
20484
  if (!payload) {
20684
20485
  logger$G.debug('inpage_payload_rejected', {
@@ -20837,27 +20638,11 @@ class InPageConnector extends BaseAsyncConnector {
20837
20638
  logger$G.debug('inpage_message_sending', {
20838
20639
  channel: this.channelName,
20839
20640
  sender_id: this.connectorId,
20840
- local_node_id: this.localNodeId,
20841
- remote_node_id: this.remoteNodeId,
20842
- });
20843
- // Only use transport framing if both localNodeId and remoteNodeId are explicitly set
20844
- // (not using default values). This ensures backwards compatibility.
20845
- const useTransportFrame = this.localNodeId !== this.connectorId ||
20846
- this.remoteNodeId !== '*';
20847
- let payload;
20848
- if (useTransportFrame) {
20849
- // Wrap payload in transport frame
20850
- const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
20851
- payload = serializeTransportFrame(frame);
20852
- }
20853
- else {
20854
- // Legacy format: send raw payload
20855
- payload = data;
20856
- }
20641
+ });
20857
20642
  const event = new MessageEvent(this.channelName, {
20858
20643
  data: {
20859
20644
  senderId: this.connectorId,
20860
- payload,
20645
+ payload: data,
20861
20646
  },
20862
20647
  });
20863
20648
  getSharedBus$1().dispatchEvent(event);
@@ -20886,24 +20671,6 @@ class InPageConnector extends BaseAsyncConnector {
20886
20671
  }
20887
20672
  return rawOrEnvelope;
20888
20673
  }
20889
- /**
20890
- * Update the remote node ID after learning it from NodeAttachAck
20891
- * This allows upstream connectors to switch from wildcard to specific addressing
20892
- */
20893
- updateRemoteNodeId(newRemoteNodeId) {
20894
- if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
20895
- throw new Error('Invalid remote node ID');
20896
- }
20897
- const oldValue = this.remoteNodeId;
20898
- this.remoteNodeId = newRemoteNodeId.trim();
20899
- logger$G.debug('inpage_connector_remote_node_id_updated', {
20900
- channel: this.channelName,
20901
- connector_id: this.connectorId,
20902
- local_node_id: this.localNodeId,
20903
- old_remote_node_id: oldValue,
20904
- new_remote_node_id: this.remoteNodeId,
20905
- });
20906
- }
20907
20674
  }
20908
20675
 
20909
20676
  const RPC_REGISTRY = Symbol('naylence.rpc.registry');
@@ -28240,14 +28007,6 @@ function isInPageConnectionGrant(candidate) {
28240
28007
  record.inboxCapacity <= 0)) {
28241
28008
  return false;
28242
28009
  }
28243
- if (record.localNodeId !== undefined &&
28244
- (typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
28245
- return false;
28246
- }
28247
- if (record.remoteNodeId !== undefined &&
28248
- (typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
28249
- return false;
28250
- }
28251
28010
  return true;
28252
28011
  }
28253
28012
  function normalizeInPageConnectionGrant(candidate) {
@@ -28281,20 +28040,6 @@ function normalizeInPageConnectionGrant(candidate) {
28281
28040
  }
28282
28041
  result.inboxCapacity = Math.floor(inboxValue);
28283
28042
  }
28284
- const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
28285
- if (localNodeIdValue !== undefined) {
28286
- if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
28287
- throw new TypeError('InPageConnectionGrant "localNodeId" must be a non-empty string when provided');
28288
- }
28289
- result.localNodeId = localNodeIdValue.trim();
28290
- }
28291
- const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
28292
- if (remoteNodeIdValue !== undefined) {
28293
- if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
28294
- throw new TypeError('InPageConnectionGrant "remoteNodeId" must be a non-empty string when provided');
28295
- }
28296
- result.remoteNodeId = remoteNodeIdValue.trim();
28297
- }
28298
28043
  return result;
28299
28044
  }
28300
28045
  function inPageGrantToConnectorConfig(grant) {
@@ -28308,12 +28053,6 @@ function inPageGrantToConnectorConfig(grant) {
28308
28053
  if (normalized.inboxCapacity !== undefined) {
28309
28054
  config.inboxCapacity = normalized.inboxCapacity;
28310
28055
  }
28311
- if (normalized.localNodeId) {
28312
- config.localNodeId = normalized.localNodeId;
28313
- }
28314
- if (normalized.remoteNodeId) {
28315
- config.remoteNodeId = normalized.remoteNodeId;
28316
- }
28317
28056
  return config;
28318
28057
  }
28319
28058
 
@@ -28935,8 +28674,6 @@ class InPageConnectorFactory extends ConnectorFactory {
28935
28674
  type: INPAGE_CONNECTOR_TYPE,
28936
28675
  channelName,
28937
28676
  inboxCapacity,
28938
- localNodeId: normalized.localNodeId,
28939
- remoteNodeId: normalized.remoteNodeId,
28940
28677
  };
28941
28678
  const connector = new InPageConnector(connectorConfig, baseConfig);
28942
28679
  if (options.authorization) {
@@ -29005,16 +28742,6 @@ class InPageConnectorFactory extends ConnectorFactory {
29005
28742
  if (candidate.authorizationContext !== undefined) {
29006
28743
  normalized.authorizationContext = candidate.authorizationContext;
29007
28744
  }
29008
- // Handle localNodeId
29009
- const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
29010
- if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
29011
- normalized.localNodeId = localNodeId.trim();
29012
- }
29013
- // Handle remoteNodeId
29014
- const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
29015
- if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
29016
- normalized.remoteNodeId = remoteNodeId.trim();
29017
- }
29018
28745
  normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$5;
29019
28746
  normalized.inboxCapacity =
29020
28747
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
@@ -29065,8 +28792,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29065
28792
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
29066
28793
  channelName: connectorConfig.channelName,
29067
28794
  inboxCapacity: connectorConfig.inboxCapacity,
29068
- localNodeId: connectorConfig.localNodeId,
29069
- remoteNodeId: connectorConfig.remoteNodeId,
28795
+ initialWindow: connectorConfig.initialWindow,
29070
28796
  };
29071
28797
  }
29072
28798
  const config = {
@@ -29091,6 +28817,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29091
28817
  purpose: 'connection',
29092
28818
  channelName: normalizedConfig.channelName,
29093
28819
  inboxCapacity: normalizedConfig.inboxCapacity,
28820
+ initialWindow: normalizedConfig.initialWindow,
29094
28821
  });
29095
28822
  return grant;
29096
28823
  }
@@ -29116,8 +28843,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29116
28843
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
29117
28844
  channelName,
29118
28845
  inboxCapacity,
29119
- localNodeId: normalized.localNodeId,
29120
- remoteNodeId: normalized.remoteNodeId,
29121
28846
  };
29122
28847
  const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
29123
28848
  if (options.authorization) {
@@ -29179,16 +28904,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29179
28904
  if (candidate.authorizationContext !== undefined) {
29180
28905
  normalized.authorizationContext = candidate.authorizationContext;
29181
28906
  }
29182
- // Handle localNodeId
29183
- const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
29184
- if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
29185
- normalized.localNodeId = localNodeId.trim();
29186
- }
29187
- // Handle remoteNodeId
29188
- const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
29189
- if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
29190
- normalized.remoteNodeId = remoteNodeId.trim();
29191
- }
29192
28907
  normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$4;
29193
28908
  normalized.inboxCapacity =
29194
28909
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$4;
@@ -29557,7 +29272,6 @@ class InPageListener extends TransportListener {
29557
29272
  this._busHandler = null;
29558
29273
  this._senderRegistry = new Map();
29559
29274
  this._systemToSender = new Map();
29560
- this._flowIdToSender = new Map();
29561
29275
  this._pendingAttachments = new Map();
29562
29276
  ensureBrowserEnvironment$1();
29563
29277
  const channelCandidate = options?.channelName;
@@ -29624,7 +29338,6 @@ class InPageListener extends TransportListener {
29624
29338
  this._unregisterBusListener();
29625
29339
  this._senderRegistry.clear();
29626
29340
  this._systemToSender.clear();
29627
- this._flowIdToSender.clear();
29628
29341
  this._pendingAttachments.clear();
29629
29342
  logger$p.debug('inpage_listener_stopped', {
29630
29343
  channel: this._channelName,
@@ -29678,25 +29391,10 @@ class InPageListener extends TransportListener {
29678
29391
  await this._handleAttachFrame(senderId, envelope);
29679
29392
  return;
29680
29393
  }
29681
- // Try to find connector by sender ID first
29682
- let entry = this._senderRegistry.get(senderId);
29683
- // If not found and we have a flowId, try to route based on flow
29684
- if (!entry && envelope.flowId) {
29685
- const originalSenderId = this._flowIdToSender.get(envelope.flowId);
29686
- if (originalSenderId) {
29687
- entry = this._senderRegistry.get(originalSenderId);
29688
- logger$p.debug('inpage_listener_routed_by_flow_id', {
29689
- sender_id: senderId,
29690
- original_sender_id: originalSenderId,
29691
- flow_id: envelope.flowId,
29692
- frame_type: envelope.frame?.type ?? 'unknown',
29693
- });
29694
- }
29695
- }
29394
+ const entry = this._senderRegistry.get(senderId);
29696
29395
  if (!entry) {
29697
29396
  logger$p.debug('inpage_listener_no_connector_for_sender', {
29698
29397
  sender_id: senderId,
29699
- flow_id: envelope.flowId,
29700
29398
  frame_type: envelope.frame?.type ?? 'unknown',
29701
29399
  });
29702
29400
  return;
@@ -29773,15 +29471,6 @@ class InPageListener extends TransportListener {
29773
29471
  }
29774
29472
  this._senderRegistry.set(senderId, entry);
29775
29473
  this._systemToSender.set(entry.systemId, senderId);
29776
- // Track the flowId if present so we can route responses back
29777
- if (envelope.flowId) {
29778
- this._flowIdToSender.set(envelope.flowId, senderId);
29779
- logger$p.debug('inpage_listener_registered_flow_id', {
29780
- sender_id: senderId,
29781
- system_id: entry.systemId,
29782
- flow_id: envelope.flowId,
29783
- });
29784
- }
29785
29474
  await this._deliverEnvelope(entry, envelope);
29786
29475
  }
29787
29476
  async _createConnectorForAttach(params) {
@@ -29829,7 +29518,7 @@ class InPageListener extends TransportListener {
29829
29518
  origin_type: originType,
29830
29519
  connector_type: connector.constructor?.name ?? 'unknown',
29831
29520
  });
29832
- return { connector, systemId, originType, senderId: params.senderId };
29521
+ return { connector, systemId, originType };
29833
29522
  }
29834
29523
  catch (error) {
29835
29524
  logger$p.error('inpage_listener_connector_creation_failed', {
@@ -29883,12 +29572,6 @@ class InPageListener extends TransportListener {
29883
29572
  if (this._systemToSender.get(systemId) === senderId) {
29884
29573
  this._systemToSender.delete(systemId);
29885
29574
  }
29886
- // Clean up flowId mappings for this sender
29887
- for (const [flowId, sid] of this._flowIdToSender.entries()) {
29888
- if (sid === senderId) {
29889
- this._flowIdToSender.delete(flowId);
29890
- }
29891
- }
29892
29575
  })
29893
29576
  .catch((error) => {
29894
29577
  logger$p.debug('inpage_listener_wait_until_closed_failed', {
@@ -29900,24 +29583,9 @@ class InPageListener extends TransportListener {
29900
29583
  if (this._systemToSender.get(systemId) === senderId) {
29901
29584
  this._systemToSender.delete(systemId);
29902
29585
  }
29903
- // Clean up flowId mappings for this sender
29904
- for (const [flowId, sid] of this._flowIdToSender.entries()) {
29905
- if (sid === senderId) {
29906
- this._flowIdToSender.delete(flowId);
29907
- }
29908
- }
29909
29586
  });
29910
29587
  }
29911
29588
  async _deliverEnvelope(entry, envelope) {
29912
- // Track flowId for routing responses back
29913
- if (envelope.flowId && !this._flowIdToSender.has(envelope.flowId)) {
29914
- this._flowIdToSender.set(envelope.flowId, entry.senderId);
29915
- logger$p.debug('inpage_listener_registered_flow_id_on_delivery', {
29916
- sender_id: entry.senderId,
29917
- system_id: entry.systemId,
29918
- flow_id: envelope.flowId,
29919
- });
29920
- }
29921
29589
  const message = this._buildChannelMessage({
29922
29590
  envelope,
29923
29591
  connector: entry.connector,
@@ -30158,18 +29826,13 @@ class BroadcastChannelListener extends TransportListener {
30158
29826
  });
30159
29827
  }
30160
29828
  asCallbackGrant() {
30161
- const grant = {
29829
+ return this.withLegacySnakeCaseKeys({
30162
29830
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
30163
29831
  connectorType: BROADCAST_CHANNEL_CONNECTOR_TYPE,
30164
29832
  connectionGrantType: BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE,
30165
29833
  channelName: this._channelName,
30166
29834
  inboxCapacity: this._inboxCapacity,
30167
- };
30168
- // Include localNodeId for transport frame multiplexing if node is available
30169
- if (this._routingNode) {
30170
- grant.localNodeId = this._routingNode.id;
30171
- }
30172
- return this.withLegacySnakeCaseKeys(grant);
29835
+ });
30173
29836
  }
30174
29837
  _registerChannelListener() {
30175
29838
  if (this._channelHandler) {
@@ -30229,54 +29892,23 @@ class BroadcastChannelListener extends TransportListener {
30229
29892
  if (typeof senderId !== 'string' || senderId.length === 0) {
30230
29893
  return null;
30231
29894
  }
30232
- // Check if payload is a transport frame object first
30233
- let envelopePayload = null;
30234
- if (this._routingNode && record.payload && typeof record.payload === 'object') {
30235
- // Try to unwrap as transport frame
30236
- const frame = unwrapTransportFrame(record.payload);
30237
- if (frame) {
30238
- // Apply listener's filtering policy: accept frames addressed to us OR with wildcard destination
30239
- // Wildcard is needed because downstream nodes don't know the sentinel's ID during initial attach
30240
- const isAddressedToUs = frame.dst === this._routingNode.id || frame.dst === '*';
30241
- if (isAddressedToUs) {
30242
- envelopePayload = frame.payload;
30243
- logger$o.debug('broadcast_channel_listener_unwrapped_transport_frame', {
30244
- sender_id: senderId,
30245
- src: frame.src,
30246
- dst: frame.dst,
30247
- });
30248
- }
30249
- else {
30250
- // Frame addressed to a different node, ignore it
30251
- logger$o.debug('broadcast_channel_listener_ignored_frame_wrong_destination', {
30252
- sender_id: senderId,
30253
- dst: frame.dst,
30254
- expected: this._routingNode.id,
30255
- });
30256
- return null;
30257
- }
30258
- }
30259
- }
30260
- // If not a transport frame, try to coerce as legacy format
30261
- if (!envelopePayload) {
30262
- envelopePayload = coercePayload(record.payload);
30263
- if (!envelopePayload) {
30264
- logger$o.debug('broadcast_channel_listener_ignored_event_without_payload', {
30265
- sender_id: senderId,
30266
- });
30267
- return null;
30268
- }
29895
+ const payload = coercePayload(record.payload);
29896
+ if (!payload) {
29897
+ logger$o.debug('broadcast_channel_listener_ignored_event_without_payload', {
29898
+ sender_id: senderId,
29899
+ });
29900
+ return null;
30269
29901
  }
30270
29902
  let envelope;
30271
29903
  try {
30272
- const decoded = new TextDecoder().decode(envelopePayload);
29904
+ const decoded = new TextDecoder().decode(payload);
30273
29905
  const parsed = JSON.parse(decoded);
30274
29906
  envelope = deserializeEnvelope(parsed);
30275
29907
  }
30276
29908
  catch (error) {
30277
29909
  const decoded = (() => {
30278
29910
  try {
30279
- return new TextDecoder().decode(envelopePayload);
29911
+ return new TextDecoder().decode(payload);
30280
29912
  }
30281
29913
  catch {
30282
29914
  return null;
@@ -30396,20 +30028,6 @@ class BroadcastChannelListener extends TransportListener {
30396
30028
  inboxCapacity: this._inboxCapacity,
30397
30029
  };
30398
30030
  }
30399
- // Automatically configure transport frame multiplexing:
30400
- // Use node IDs (not connector IDs) for node-to-node targeting
30401
- const broadcastConfig = connectorConfig;
30402
- // Always force localNodeId to be this listener's node ID
30403
- // This ensures the sentinel sets localNodeId=sentinel, not the child's ID
30404
- broadcastConfig.localNodeId = routingNode.id;
30405
- // Always force remoteNodeId to be the attaching child's system ID
30406
- broadcastConfig.remoteNodeId = systemId;
30407
- logger$o.debug('broadcast_channel_listener_configured_node_ids', {
30408
- sender_id: params.senderId,
30409
- system_id: systemId,
30410
- local_node_id: broadcastConfig.localNodeId,
30411
- remote_node_id: broadcastConfig.remoteNodeId,
30412
- });
30413
30031
  try {
30414
30032
  const connector = await routingNode.createOriginConnector({
30415
30033
  originType,
@@ -30479,21 +30097,6 @@ class BroadcastChannelListener extends TransportListener {
30479
30097
  inboxCandidate > 0) {
30480
30098
  config.inboxCapacity = Math.floor(inboxCandidate);
30481
30099
  }
30482
- // Extract transport frame multiplexing node IDs
30483
- const localNodeIdCandidate = candidate.localNodeId ?? candidate['local_node_id'];
30484
- if (typeof localNodeIdCandidate === 'string' && localNodeIdCandidate.trim().length > 0) {
30485
- config.localNodeId = localNodeIdCandidate.trim();
30486
- logger$o.debug('broadcast_channel_listener_extracted_local_node_id', {
30487
- local_node_id: config.localNodeId,
30488
- });
30489
- }
30490
- const remoteNodeIdCandidate = candidate.remoteNodeId ?? candidate['remote_node_id'];
30491
- if (typeof remoteNodeIdCandidate === 'string' && remoteNodeIdCandidate.trim().length > 0) {
30492
- config.remoteNodeId = remoteNodeIdCandidate.trim();
30493
- logger$o.debug('broadcast_channel_listener_extracted_remote_node_id', {
30494
- remote_node_id: config.remoteNodeId,
30495
- });
30496
- }
30497
30100
  return config;
30498
30101
  }
30499
30102
  _monitorConnectorLifecycle(senderId, systemId, connector) {