@naylence/runtime 0.3.5-test.942 → 0.3.5-test.944
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.cjs +380 -8
- package/dist/browser/index.mjs +380 -8
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector-factory.js +12 -0
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +69 -1
- package/dist/cjs/naylence/fame/connector/broadcast-channel-listener.js +35 -0
- package/dist/cjs/naylence/fame/connector/inpage-connector-factory.js +12 -0
- package/dist/cjs/naylence/fame/connector/inpage-connector.js +66 -1
- package/dist/cjs/naylence/fame/connector/inpage-listener.js +49 -2
- package/dist/cjs/naylence/fame/connector/transport-frame.js +101 -0
- package/dist/cjs/naylence/fame/grants/broadcast-channel-connection-grant.js +28 -0
- package/dist/cjs/naylence/fame/grants/inpage-connection-grant.js +28 -0
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +12 -0
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +69 -1
- package/dist/esm/naylence/fame/connector/broadcast-channel-listener.js +35 -0
- package/dist/esm/naylence/fame/connector/inpage-connector-factory.js +12 -0
- package/dist/esm/naylence/fame/connector/inpage-connector.js +66 -1
- package/dist/esm/naylence/fame/connector/inpage-listener.js +49 -2
- package/dist/esm/naylence/fame/connector/transport-frame.js +94 -0
- package/dist/esm/naylence/fame/grants/broadcast-channel-connection-grant.js +28 -0
- package/dist/esm/naylence/fame/grants/inpage-connection-grant.js +28 -0
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +380 -8
- package/dist/node/index.mjs +380 -8
- package/dist/node/node.cjs +396 -8
- package/dist/node/node.mjs +396 -8
- package/dist/types/naylence/fame/connector/broadcast-channel-connector-factory.d.ts +2 -0
- package/dist/types/naylence/fame/connector/broadcast-channel-connector.browser.d.ts +4 -0
- package/dist/types/naylence/fame/connector/inpage-connector-factory.d.ts +2 -0
- package/dist/types/naylence/fame/connector/inpage-connector.d.ts +4 -0
- package/dist/types/naylence/fame/connector/inpage-listener.d.ts +1 -0
- package/dist/types/naylence/fame/connector/transport-frame.d.ts +58 -0
- package/dist/types/naylence/fame/grants/broadcast-channel-connection-grant.d.ts +6 -0
- package/dist/types/naylence/fame/grants/inpage-connection-grant.d.ts +8 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/node/index.cjs
CHANGED
|
@@ -14,12 +14,12 @@ var fastify = require('fastify');
|
|
|
14
14
|
var websocketPlugin = require('@fastify/websocket');
|
|
15
15
|
|
|
16
16
|
// This file is auto-generated during build - do not edit manually
|
|
17
|
-
// Generated from package.json version: 0.3.5-test.
|
|
17
|
+
// Generated from package.json version: 0.3.5-test.944
|
|
18
18
|
/**
|
|
19
19
|
* The package version, injected at build time.
|
|
20
20
|
* @internal
|
|
21
21
|
*/
|
|
22
|
-
const VERSION = '0.3.5-test.
|
|
22
|
+
const VERSION = '0.3.5-test.944';
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -9734,6 +9734,85 @@ class BoundedAsyncQueue {
|
|
|
9734
9734
|
}
|
|
9735
9735
|
}
|
|
9736
9736
|
|
|
9737
|
+
/**
|
|
9738
|
+
* Transport frame layer for multiplexing logical links on physical channels.
|
|
9739
|
+
*
|
|
9740
|
+
* This lightweight framing layer wraps raw FAME payloads to enable multiple
|
|
9741
|
+
* logical connections over a single physical channel (BroadcastChannel or InPage bus).
|
|
9742
|
+
*
|
|
9743
|
+
* The transport frame does NOT modify FAME envelopes - it only wraps the raw
|
|
9744
|
+
* Uint8Array payload at the connector level.
|
|
9745
|
+
*/
|
|
9746
|
+
/**
|
|
9747
|
+
* Transport frame version for future compatibility
|
|
9748
|
+
*/
|
|
9749
|
+
const TRANSPORT_FRAME_VERSION = 1;
|
|
9750
|
+
/**
|
|
9751
|
+
* Wrap a raw payload in a transport frame
|
|
9752
|
+
*
|
|
9753
|
+
* @param payload - Raw FAME envelope bytes
|
|
9754
|
+
* @param srcNodeId - Local node ID (this connector)
|
|
9755
|
+
* @param dstNodeId - Remote node ID (target connector)
|
|
9756
|
+
* @returns Transport frame ready for transmission
|
|
9757
|
+
*/
|
|
9758
|
+
function wrapTransportFrame(payload, srcNodeId, dstNodeId) {
|
|
9759
|
+
return {
|
|
9760
|
+
v: TRANSPORT_FRAME_VERSION,
|
|
9761
|
+
src: srcNodeId,
|
|
9762
|
+
dst: dstNodeId,
|
|
9763
|
+
payload,
|
|
9764
|
+
};
|
|
9765
|
+
}
|
|
9766
|
+
/**
|
|
9767
|
+
* Serialize a transport frame for transmission over the bus
|
|
9768
|
+
*
|
|
9769
|
+
* @param frame - Transport frame to serialize
|
|
9770
|
+
* @returns Serialized frame data ready for postMessage/dispatchEvent
|
|
9771
|
+
*/
|
|
9772
|
+
function serializeTransportFrame(frame) {
|
|
9773
|
+
// Convert Uint8Array to regular array for JSON serialization
|
|
9774
|
+
const serializable = {
|
|
9775
|
+
v: frame.v,
|
|
9776
|
+
src: frame.src,
|
|
9777
|
+
dst: frame.dst,
|
|
9778
|
+
payload: Array.from(frame.payload),
|
|
9779
|
+
};
|
|
9780
|
+
return serializable;
|
|
9781
|
+
}
|
|
9782
|
+
/**
|
|
9783
|
+
* Unwrap a transport frame, validating source and destination
|
|
9784
|
+
*
|
|
9785
|
+
* @param raw - Raw data from the bus
|
|
9786
|
+
* @param localNodeId - This connector's node ID
|
|
9787
|
+
* @param remoteNodeId - Expected remote node ID
|
|
9788
|
+
* @returns Unwrapped payload if frame is valid and addressed to us, null otherwise
|
|
9789
|
+
*/
|
|
9790
|
+
function unwrapTransportFrame(raw, localNodeId, remoteNodeId) {
|
|
9791
|
+
// Validate basic structure
|
|
9792
|
+
if (!raw || typeof raw !== 'object') {
|
|
9793
|
+
return null;
|
|
9794
|
+
}
|
|
9795
|
+
const frame = raw;
|
|
9796
|
+
// Check version
|
|
9797
|
+
if (frame.v !== TRANSPORT_FRAME_VERSION) {
|
|
9798
|
+
return null;
|
|
9799
|
+
}
|
|
9800
|
+
// Check src and dst
|
|
9801
|
+
if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
|
|
9802
|
+
return null;
|
|
9803
|
+
}
|
|
9804
|
+
// Only accept frames addressed to us from the expected remote
|
|
9805
|
+
if (frame.dst !== localNodeId || frame.src !== remoteNodeId) {
|
|
9806
|
+
return null;
|
|
9807
|
+
}
|
|
9808
|
+
// Extract payload
|
|
9809
|
+
if (!frame.payload || !Array.isArray(frame.payload)) {
|
|
9810
|
+
return null;
|
|
9811
|
+
}
|
|
9812
|
+
// Convert array back to Uint8Array
|
|
9813
|
+
return Uint8Array.from(frame.payload);
|
|
9814
|
+
}
|
|
9815
|
+
|
|
9737
9816
|
const logger$_ = getLogger('naylence.fame.connector.broadcast_channel_connector');
|
|
9738
9817
|
const BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
|
|
9739
9818
|
const DEFAULT_CHANNEL$7 = 'naylence-fabric';
|
|
@@ -9799,9 +9878,20 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9799
9878
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
9800
9879
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
9801
9880
|
this.channel = new BroadcastChannel(this.channelName);
|
|
9881
|
+
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
9882
|
+
this.localNodeId =
|
|
9883
|
+
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
9884
|
+
? config.localNodeId.trim()
|
|
9885
|
+
: this.connectorId;
|
|
9886
|
+
this.remoteNodeId =
|
|
9887
|
+
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
9888
|
+
? config.remoteNodeId.trim()
|
|
9889
|
+
: '*'; // Accept from any remote if not specified
|
|
9802
9890
|
logger$_.debug('broadcast_channel_connector_created', {
|
|
9803
9891
|
channel: this.channelName,
|
|
9804
9892
|
connector_id: this.connectorId,
|
|
9893
|
+
local_node_id: this.localNodeId,
|
|
9894
|
+
remote_node_id: this.remoteNodeId,
|
|
9805
9895
|
inbox_capacity: preferredCapacity,
|
|
9806
9896
|
timestamp: new Date().toISOString(),
|
|
9807
9897
|
});
|
|
@@ -9834,6 +9924,46 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9834
9924
|
if (busMessage.senderId === this.connectorId) {
|
|
9835
9925
|
return;
|
|
9836
9926
|
}
|
|
9927
|
+
// Try to unwrap as transport frame
|
|
9928
|
+
const unwrapped = unwrapTransportFrame(busMessage.payload, this.localNodeId, this.remoteNodeId === '*' ? busMessage.senderId : this.remoteNodeId);
|
|
9929
|
+
if (unwrapped) {
|
|
9930
|
+
// Successfully unwrapped transport frame
|
|
9931
|
+
logger$_.debug('broadcast_channel_transport_frame_received', {
|
|
9932
|
+
channel: this.channelName,
|
|
9933
|
+
sender_id: busMessage.senderId,
|
|
9934
|
+
connector_id: this.connectorId,
|
|
9935
|
+
local_node_id: this.localNodeId,
|
|
9936
|
+
remote_node_id: this.remoteNodeId,
|
|
9937
|
+
payload_length: unwrapped.byteLength,
|
|
9938
|
+
});
|
|
9939
|
+
if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
|
|
9940
|
+
return;
|
|
9941
|
+
}
|
|
9942
|
+
try {
|
|
9943
|
+
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
9944
|
+
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
9945
|
+
if (accepted) {
|
|
9946
|
+
return;
|
|
9947
|
+
}
|
|
9948
|
+
}
|
|
9949
|
+
this.inbox.enqueue(unwrapped);
|
|
9950
|
+
}
|
|
9951
|
+
catch (error) {
|
|
9952
|
+
if (error instanceof QueueFullError) {
|
|
9953
|
+
logger$_.warning('broadcast_channel_receive_queue_full', {
|
|
9954
|
+
channel: this.channelName,
|
|
9955
|
+
});
|
|
9956
|
+
}
|
|
9957
|
+
else {
|
|
9958
|
+
logger$_.error('broadcast_channel_receive_error', {
|
|
9959
|
+
channel: this.channelName,
|
|
9960
|
+
error: error instanceof Error ? error.message : String(error),
|
|
9961
|
+
});
|
|
9962
|
+
}
|
|
9963
|
+
}
|
|
9964
|
+
return;
|
|
9965
|
+
}
|
|
9966
|
+
// Fall back to legacy format (no transport frame)
|
|
9837
9967
|
const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
|
|
9838
9968
|
if (!payload) {
|
|
9839
9969
|
logger$_.debug('broadcast_channel_payload_rejected', {
|
|
@@ -9972,10 +10102,26 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9972
10102
|
logger$_.debug('broadcast_channel_message_sending', {
|
|
9973
10103
|
channel: this.channelName,
|
|
9974
10104
|
sender_id: this.connectorId,
|
|
9975
|
-
|
|
10105
|
+
local_node_id: this.localNodeId,
|
|
10106
|
+
remote_node_id: this.remoteNodeId,
|
|
10107
|
+
});
|
|
10108
|
+
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
10109
|
+
// (not using default values). This ensures backwards compatibility.
|
|
10110
|
+
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
10111
|
+
this.remoteNodeId !== '*';
|
|
10112
|
+
let payload;
|
|
10113
|
+
if (useTransportFrame) {
|
|
10114
|
+
// Wrap payload in transport frame
|
|
10115
|
+
const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
|
|
10116
|
+
payload = serializeTransportFrame(frame);
|
|
10117
|
+
}
|
|
10118
|
+
else {
|
|
10119
|
+
// Legacy format: send raw payload
|
|
10120
|
+
payload = data;
|
|
10121
|
+
}
|
|
9976
10122
|
this.channel.postMessage({
|
|
9977
10123
|
senderId: this.connectorId,
|
|
9978
|
-
payload
|
|
10124
|
+
payload,
|
|
9979
10125
|
});
|
|
9980
10126
|
}
|
|
9981
10127
|
async _transportReceive() {
|
|
@@ -10268,6 +10414,14 @@ function isBroadcastChannelConnectionGrant(candidate) {
|
|
|
10268
10414
|
record.inboxCapacity <= 0)) {
|
|
10269
10415
|
return false;
|
|
10270
10416
|
}
|
|
10417
|
+
if (record.localNodeId !== undefined &&
|
|
10418
|
+
(typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
|
|
10419
|
+
return false;
|
|
10420
|
+
}
|
|
10421
|
+
if (record.remoteNodeId !== undefined &&
|
|
10422
|
+
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
10423
|
+
return false;
|
|
10424
|
+
}
|
|
10271
10425
|
return true;
|
|
10272
10426
|
}
|
|
10273
10427
|
function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
@@ -10301,6 +10455,20 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
|
10301
10455
|
}
|
|
10302
10456
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
10303
10457
|
}
|
|
10458
|
+
const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
|
|
10459
|
+
if (localNodeIdValue !== undefined) {
|
|
10460
|
+
if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
|
|
10461
|
+
throw new TypeError('BroadcastChannelConnectionGrant "localNodeId" must be a non-empty string when provided');
|
|
10462
|
+
}
|
|
10463
|
+
result.localNodeId = localNodeIdValue.trim();
|
|
10464
|
+
}
|
|
10465
|
+
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
10466
|
+
if (remoteNodeIdValue !== undefined) {
|
|
10467
|
+
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
10468
|
+
throw new TypeError('BroadcastChannelConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
10469
|
+
}
|
|
10470
|
+
result.remoteNodeId = remoteNodeIdValue.trim();
|
|
10471
|
+
}
|
|
10304
10472
|
return result;
|
|
10305
10473
|
}
|
|
10306
10474
|
function broadcastChannelGrantToConnectorConfig(grant) {
|
|
@@ -10314,6 +10482,12 @@ function broadcastChannelGrantToConnectorConfig(grant) {
|
|
|
10314
10482
|
if (normalized.inboxCapacity !== undefined) {
|
|
10315
10483
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
10316
10484
|
}
|
|
10485
|
+
if (normalized.localNodeId) {
|
|
10486
|
+
config.localNodeId = normalized.localNodeId;
|
|
10487
|
+
}
|
|
10488
|
+
if (normalized.remoteNodeId) {
|
|
10489
|
+
config.remoteNodeId = normalized.remoteNodeId;
|
|
10490
|
+
}
|
|
10317
10491
|
return config;
|
|
10318
10492
|
}
|
|
10319
10493
|
|
|
@@ -20260,9 +20434,20 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20260
20434
|
: DEFAULT_INBOX_CAPACITY$6;
|
|
20261
20435
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
20262
20436
|
this.connectorId = InPageConnector.generateConnectorId();
|
|
20437
|
+
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
20438
|
+
this.localNodeId =
|
|
20439
|
+
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
20440
|
+
? config.localNodeId.trim()
|
|
20441
|
+
: this.connectorId;
|
|
20442
|
+
this.remoteNodeId =
|
|
20443
|
+
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
20444
|
+
? config.remoteNodeId.trim()
|
|
20445
|
+
: '*'; // Accept from any remote if not specified
|
|
20263
20446
|
logger$G.debug('inpage_connector_initialized', {
|
|
20264
20447
|
channel: this.channelName,
|
|
20265
20448
|
connector_id: this.connectorId,
|
|
20449
|
+
local_node_id: this.localNodeId,
|
|
20450
|
+
remote_node_id: this.remoteNodeId,
|
|
20266
20451
|
});
|
|
20267
20452
|
this.onMsg = (event) => {
|
|
20268
20453
|
const messageEvent = event;
|
|
@@ -20296,6 +20481,43 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20296
20481
|
if (busMessage.senderId === this.connectorId) {
|
|
20297
20482
|
return;
|
|
20298
20483
|
}
|
|
20484
|
+
// Try to unwrap as transport frame
|
|
20485
|
+
const unwrapped = unwrapTransportFrame(busMessage.payload, this.localNodeId, this.remoteNodeId === '*' ? busMessage.senderId : this.remoteNodeId);
|
|
20486
|
+
if (unwrapped) {
|
|
20487
|
+
// Successfully unwrapped transport frame
|
|
20488
|
+
logger$G.debug('inpage_transport_frame_received', {
|
|
20489
|
+
channel: this.channelName,
|
|
20490
|
+
sender_id: busMessage.senderId,
|
|
20491
|
+
connector_id: this.connectorId,
|
|
20492
|
+
local_node_id: this.localNodeId,
|
|
20493
|
+
remote_node_id: this.remoteNodeId,
|
|
20494
|
+
payload_length: unwrapped.byteLength,
|
|
20495
|
+
});
|
|
20496
|
+
try {
|
|
20497
|
+
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
20498
|
+
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
20499
|
+
if (accepted) {
|
|
20500
|
+
return;
|
|
20501
|
+
}
|
|
20502
|
+
}
|
|
20503
|
+
this.inbox.enqueue(unwrapped);
|
|
20504
|
+
}
|
|
20505
|
+
catch (error) {
|
|
20506
|
+
if (error instanceof QueueFullError) {
|
|
20507
|
+
logger$G.warning('inpage_receive_queue_full', {
|
|
20508
|
+
channel: this.channelName,
|
|
20509
|
+
});
|
|
20510
|
+
}
|
|
20511
|
+
else {
|
|
20512
|
+
logger$G.error('inpage_receive_error', {
|
|
20513
|
+
channel: this.channelName,
|
|
20514
|
+
error: error instanceof Error ? error.message : String(error),
|
|
20515
|
+
});
|
|
20516
|
+
}
|
|
20517
|
+
}
|
|
20518
|
+
return;
|
|
20519
|
+
}
|
|
20520
|
+
// Fall back to legacy format (no transport frame)
|
|
20299
20521
|
const payload = InPageConnector.coercePayload(busMessage.payload);
|
|
20300
20522
|
if (!payload) {
|
|
20301
20523
|
logger$G.debug('inpage_payload_rejected', {
|
|
@@ -20454,11 +20676,27 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20454
20676
|
logger$G.debug('inpage_message_sending', {
|
|
20455
20677
|
channel: this.channelName,
|
|
20456
20678
|
sender_id: this.connectorId,
|
|
20457
|
-
|
|
20679
|
+
local_node_id: this.localNodeId,
|
|
20680
|
+
remote_node_id: this.remoteNodeId,
|
|
20681
|
+
});
|
|
20682
|
+
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
20683
|
+
// (not using default values). This ensures backwards compatibility.
|
|
20684
|
+
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
20685
|
+
this.remoteNodeId !== '*';
|
|
20686
|
+
let payload;
|
|
20687
|
+
if (useTransportFrame) {
|
|
20688
|
+
// Wrap payload in transport frame
|
|
20689
|
+
const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
|
|
20690
|
+
payload = serializeTransportFrame(frame);
|
|
20691
|
+
}
|
|
20692
|
+
else {
|
|
20693
|
+
// Legacy format: send raw payload
|
|
20694
|
+
payload = data;
|
|
20695
|
+
}
|
|
20458
20696
|
const event = new MessageEvent(this.channelName, {
|
|
20459
20697
|
data: {
|
|
20460
20698
|
senderId: this.connectorId,
|
|
20461
|
-
payload
|
|
20699
|
+
payload,
|
|
20462
20700
|
},
|
|
20463
20701
|
});
|
|
20464
20702
|
getSharedBus$1().dispatchEvent(event);
|
|
@@ -27823,6 +28061,14 @@ function isInPageConnectionGrant(candidate) {
|
|
|
27823
28061
|
record.inboxCapacity <= 0)) {
|
|
27824
28062
|
return false;
|
|
27825
28063
|
}
|
|
28064
|
+
if (record.localNodeId !== undefined &&
|
|
28065
|
+
(typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
|
|
28066
|
+
return false;
|
|
28067
|
+
}
|
|
28068
|
+
if (record.remoteNodeId !== undefined &&
|
|
28069
|
+
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
28070
|
+
return false;
|
|
28071
|
+
}
|
|
27826
28072
|
return true;
|
|
27827
28073
|
}
|
|
27828
28074
|
function normalizeInPageConnectionGrant(candidate) {
|
|
@@ -27856,6 +28102,20 @@ function normalizeInPageConnectionGrant(candidate) {
|
|
|
27856
28102
|
}
|
|
27857
28103
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
27858
28104
|
}
|
|
28105
|
+
const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
|
|
28106
|
+
if (localNodeIdValue !== undefined) {
|
|
28107
|
+
if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
|
|
28108
|
+
throw new TypeError('InPageConnectionGrant "localNodeId" must be a non-empty string when provided');
|
|
28109
|
+
}
|
|
28110
|
+
result.localNodeId = localNodeIdValue.trim();
|
|
28111
|
+
}
|
|
28112
|
+
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
28113
|
+
if (remoteNodeIdValue !== undefined) {
|
|
28114
|
+
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
28115
|
+
throw new TypeError('InPageConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
28116
|
+
}
|
|
28117
|
+
result.remoteNodeId = remoteNodeIdValue.trim();
|
|
28118
|
+
}
|
|
27859
28119
|
return result;
|
|
27860
28120
|
}
|
|
27861
28121
|
function inPageGrantToConnectorConfig(grant) {
|
|
@@ -27869,6 +28129,12 @@ function inPageGrantToConnectorConfig(grant) {
|
|
|
27869
28129
|
if (normalized.inboxCapacity !== undefined) {
|
|
27870
28130
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
27871
28131
|
}
|
|
28132
|
+
if (normalized.localNodeId) {
|
|
28133
|
+
config.localNodeId = normalized.localNodeId;
|
|
28134
|
+
}
|
|
28135
|
+
if (normalized.remoteNodeId) {
|
|
28136
|
+
config.remoteNodeId = normalized.remoteNodeId;
|
|
28137
|
+
}
|
|
27872
28138
|
return config;
|
|
27873
28139
|
}
|
|
27874
28140
|
|
|
@@ -28495,6 +28761,8 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28495
28761
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
28496
28762
|
channelName,
|
|
28497
28763
|
inboxCapacity,
|
|
28764
|
+
localNodeId: normalized.localNodeId,
|
|
28765
|
+
remoteNodeId: normalized.remoteNodeId,
|
|
28498
28766
|
};
|
|
28499
28767
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
28500
28768
|
if (options.authorization) {
|
|
@@ -28556,6 +28824,16 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28556
28824
|
if (candidate.authorizationContext !== undefined) {
|
|
28557
28825
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
28558
28826
|
}
|
|
28827
|
+
// Handle localNodeId
|
|
28828
|
+
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
28829
|
+
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
28830
|
+
normalized.localNodeId = localNodeId.trim();
|
|
28831
|
+
}
|
|
28832
|
+
// Handle remoteNodeId
|
|
28833
|
+
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
28834
|
+
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
28835
|
+
normalized.remoteNodeId = remoteNodeId.trim();
|
|
28836
|
+
}
|
|
28559
28837
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$5;
|
|
28560
28838
|
normalized.inboxCapacity =
|
|
28561
28839
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
|
|
@@ -29119,6 +29397,8 @@ class InPageConnectorFactory extends ConnectorFactory {
|
|
|
29119
29397
|
type: INPAGE_CONNECTOR_TYPE,
|
|
29120
29398
|
channelName,
|
|
29121
29399
|
inboxCapacity,
|
|
29400
|
+
localNodeId: normalized.localNodeId,
|
|
29401
|
+
remoteNodeId: normalized.remoteNodeId,
|
|
29122
29402
|
};
|
|
29123
29403
|
const connector = new InPageConnector(connectorConfig, baseConfig);
|
|
29124
29404
|
if (options.authorization) {
|
|
@@ -29187,6 +29467,16 @@ class InPageConnectorFactory extends ConnectorFactory {
|
|
|
29187
29467
|
if (candidate.authorizationContext !== undefined) {
|
|
29188
29468
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
29189
29469
|
}
|
|
29470
|
+
// Handle localNodeId
|
|
29471
|
+
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
29472
|
+
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
29473
|
+
normalized.localNodeId = localNodeId.trim();
|
|
29474
|
+
}
|
|
29475
|
+
// Handle remoteNodeId
|
|
29476
|
+
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
29477
|
+
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
29478
|
+
normalized.remoteNodeId = remoteNodeId.trim();
|
|
29479
|
+
}
|
|
29190
29480
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$3;
|
|
29191
29481
|
normalized.inboxCapacity =
|
|
29192
29482
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$3;
|
|
@@ -36154,6 +36444,26 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36154
36444
|
inboxCapacity: this._inboxCapacity,
|
|
36155
36445
|
};
|
|
36156
36446
|
}
|
|
36447
|
+
// Automatically configure transport frame multiplexing:
|
|
36448
|
+
// Set remoteNodeId to the incoming senderId to target responses back to the specific client/agent
|
|
36449
|
+
const broadcastConfig = connectorConfig;
|
|
36450
|
+
if (!broadcastConfig.remoteNodeId) {
|
|
36451
|
+
broadcastConfig.remoteNodeId = params.senderId;
|
|
36452
|
+
logger$a.debug('broadcast_channel_listener_auto_configured_remote_node_id', {
|
|
36453
|
+
sender_id: params.senderId,
|
|
36454
|
+
system_id: systemId,
|
|
36455
|
+
remote_node_id: params.senderId,
|
|
36456
|
+
local_node_id: broadcastConfig.localNodeId ?? '<not set>',
|
|
36457
|
+
});
|
|
36458
|
+
}
|
|
36459
|
+
else {
|
|
36460
|
+
logger$a.debug('broadcast_channel_listener_using_provided_remote_node_id', {
|
|
36461
|
+
sender_id: params.senderId,
|
|
36462
|
+
system_id: systemId,
|
|
36463
|
+
remote_node_id: broadcastConfig.remoteNodeId,
|
|
36464
|
+
local_node_id: broadcastConfig.localNodeId ?? '<not set>',
|
|
36465
|
+
});
|
|
36466
|
+
}
|
|
36157
36467
|
try {
|
|
36158
36468
|
const connector = await routingNode.createOriginConnector({
|
|
36159
36469
|
originType,
|
|
@@ -36223,6 +36533,21 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36223
36533
|
inboxCandidate > 0) {
|
|
36224
36534
|
config.inboxCapacity = Math.floor(inboxCandidate);
|
|
36225
36535
|
}
|
|
36536
|
+
// Extract transport frame multiplexing node IDs
|
|
36537
|
+
const localNodeIdCandidate = candidate.localNodeId ?? candidate['local_node_id'];
|
|
36538
|
+
if (typeof localNodeIdCandidate === 'string' && localNodeIdCandidate.trim().length > 0) {
|
|
36539
|
+
config.localNodeId = localNodeIdCandidate.trim();
|
|
36540
|
+
logger$a.debug('broadcast_channel_listener_extracted_local_node_id', {
|
|
36541
|
+
local_node_id: config.localNodeId,
|
|
36542
|
+
});
|
|
36543
|
+
}
|
|
36544
|
+
const remoteNodeIdCandidate = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
36545
|
+
if (typeof remoteNodeIdCandidate === 'string' && remoteNodeIdCandidate.trim().length > 0) {
|
|
36546
|
+
config.remoteNodeId = remoteNodeIdCandidate.trim();
|
|
36547
|
+
logger$a.debug('broadcast_channel_listener_extracted_remote_node_id', {
|
|
36548
|
+
remote_node_id: config.remoteNodeId,
|
|
36549
|
+
});
|
|
36550
|
+
}
|
|
36226
36551
|
return config;
|
|
36227
36552
|
}
|
|
36228
36553
|
_monitorConnectorLifecycle(senderId, systemId, connector) {
|
|
@@ -36945,6 +37270,7 @@ class InPageListener extends TransportListener {
|
|
|
36945
37270
|
this._busHandler = null;
|
|
36946
37271
|
this._senderRegistry = new Map();
|
|
36947
37272
|
this._systemToSender = new Map();
|
|
37273
|
+
this._flowIdToSender = new Map();
|
|
36948
37274
|
this._pendingAttachments = new Map();
|
|
36949
37275
|
ensureBrowserEnvironment();
|
|
36950
37276
|
const channelCandidate = options?.channelName;
|
|
@@ -37011,6 +37337,7 @@ class InPageListener extends TransportListener {
|
|
|
37011
37337
|
this._unregisterBusListener();
|
|
37012
37338
|
this._senderRegistry.clear();
|
|
37013
37339
|
this._systemToSender.clear();
|
|
37340
|
+
this._flowIdToSender.clear();
|
|
37014
37341
|
this._pendingAttachments.clear();
|
|
37015
37342
|
logger$7.debug('inpage_listener_stopped', {
|
|
37016
37343
|
channel: this._channelName,
|
|
@@ -37064,10 +37391,25 @@ class InPageListener extends TransportListener {
|
|
|
37064
37391
|
await this._handleAttachFrame(senderId, envelope);
|
|
37065
37392
|
return;
|
|
37066
37393
|
}
|
|
37067
|
-
|
|
37394
|
+
// Try to find connector by sender ID first
|
|
37395
|
+
let entry = this._senderRegistry.get(senderId);
|
|
37396
|
+
// If not found and we have a flowId, try to route based on flow
|
|
37397
|
+
if (!entry && envelope.flowId) {
|
|
37398
|
+
const originalSenderId = this._flowIdToSender.get(envelope.flowId);
|
|
37399
|
+
if (originalSenderId) {
|
|
37400
|
+
entry = this._senderRegistry.get(originalSenderId);
|
|
37401
|
+
logger$7.debug('inpage_listener_routed_by_flow_id', {
|
|
37402
|
+
sender_id: senderId,
|
|
37403
|
+
original_sender_id: originalSenderId,
|
|
37404
|
+
flow_id: envelope.flowId,
|
|
37405
|
+
frame_type: envelope.frame?.type ?? 'unknown',
|
|
37406
|
+
});
|
|
37407
|
+
}
|
|
37408
|
+
}
|
|
37068
37409
|
if (!entry) {
|
|
37069
37410
|
logger$7.debug('inpage_listener_no_connector_for_sender', {
|
|
37070
37411
|
sender_id: senderId,
|
|
37412
|
+
flow_id: envelope.flowId,
|
|
37071
37413
|
frame_type: envelope.frame?.type ?? 'unknown',
|
|
37072
37414
|
});
|
|
37073
37415
|
return;
|
|
@@ -37144,6 +37486,15 @@ class InPageListener extends TransportListener {
|
|
|
37144
37486
|
}
|
|
37145
37487
|
this._senderRegistry.set(senderId, entry);
|
|
37146
37488
|
this._systemToSender.set(entry.systemId, senderId);
|
|
37489
|
+
// Track the flowId if present so we can route responses back
|
|
37490
|
+
if (envelope.flowId) {
|
|
37491
|
+
this._flowIdToSender.set(envelope.flowId, senderId);
|
|
37492
|
+
logger$7.debug('inpage_listener_registered_flow_id', {
|
|
37493
|
+
sender_id: senderId,
|
|
37494
|
+
system_id: entry.systemId,
|
|
37495
|
+
flow_id: envelope.flowId,
|
|
37496
|
+
});
|
|
37497
|
+
}
|
|
37147
37498
|
await this._deliverEnvelope(entry, envelope);
|
|
37148
37499
|
}
|
|
37149
37500
|
async _createConnectorForAttach(params) {
|
|
@@ -37191,7 +37542,7 @@ class InPageListener extends TransportListener {
|
|
|
37191
37542
|
origin_type: originType,
|
|
37192
37543
|
connector_type: connector.constructor?.name ?? 'unknown',
|
|
37193
37544
|
});
|
|
37194
|
-
return { connector, systemId, originType };
|
|
37545
|
+
return { connector, systemId, originType, senderId: params.senderId };
|
|
37195
37546
|
}
|
|
37196
37547
|
catch (error) {
|
|
37197
37548
|
logger$7.error('inpage_listener_connector_creation_failed', {
|
|
@@ -37245,6 +37596,12 @@ class InPageListener extends TransportListener {
|
|
|
37245
37596
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
37246
37597
|
this._systemToSender.delete(systemId);
|
|
37247
37598
|
}
|
|
37599
|
+
// Clean up flowId mappings for this sender
|
|
37600
|
+
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
37601
|
+
if (sid === senderId) {
|
|
37602
|
+
this._flowIdToSender.delete(flowId);
|
|
37603
|
+
}
|
|
37604
|
+
}
|
|
37248
37605
|
})
|
|
37249
37606
|
.catch((error) => {
|
|
37250
37607
|
logger$7.debug('inpage_listener_wait_until_closed_failed', {
|
|
@@ -37256,9 +37613,24 @@ class InPageListener extends TransportListener {
|
|
|
37256
37613
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
37257
37614
|
this._systemToSender.delete(systemId);
|
|
37258
37615
|
}
|
|
37616
|
+
// Clean up flowId mappings for this sender
|
|
37617
|
+
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
37618
|
+
if (sid === senderId) {
|
|
37619
|
+
this._flowIdToSender.delete(flowId);
|
|
37620
|
+
}
|
|
37621
|
+
}
|
|
37259
37622
|
});
|
|
37260
37623
|
}
|
|
37261
37624
|
async _deliverEnvelope(entry, envelope) {
|
|
37625
|
+
// Track flowId for routing responses back
|
|
37626
|
+
if (envelope.flowId && !this._flowIdToSender.has(envelope.flowId)) {
|
|
37627
|
+
this._flowIdToSender.set(envelope.flowId, entry.senderId);
|
|
37628
|
+
logger$7.debug('inpage_listener_registered_flow_id_on_delivery', {
|
|
37629
|
+
sender_id: entry.senderId,
|
|
37630
|
+
system_id: entry.systemId,
|
|
37631
|
+
flow_id: envelope.flowId,
|
|
37632
|
+
});
|
|
37633
|
+
}
|
|
37262
37634
|
const message = this._buildChannelMessage({
|
|
37263
37635
|
envelope,
|
|
37264
37636
|
connector: entry.connector,
|