@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/node.mjs
CHANGED
|
@@ -5477,12 +5477,12 @@ for (const [name, config] of Object.entries(SQLITE_PROFILES)) {
|
|
|
5477
5477
|
}
|
|
5478
5478
|
|
|
5479
5479
|
// This file is auto-generated during build - do not edit manually
|
|
5480
|
-
// Generated from package.json version: 0.3.5-test.
|
|
5480
|
+
// Generated from package.json version: 0.3.5-test.944
|
|
5481
5481
|
/**
|
|
5482
5482
|
* The package version, injected at build time.
|
|
5483
5483
|
* @internal
|
|
5484
5484
|
*/
|
|
5485
|
-
const VERSION = '0.3.5-test.
|
|
5485
|
+
const VERSION = '0.3.5-test.944';
|
|
5486
5486
|
|
|
5487
5487
|
/**
|
|
5488
5488
|
* Fame errors module - Fame protocol specific error classes
|
|
@@ -11470,6 +11470,101 @@ class BoundedAsyncQueue {
|
|
|
11470
11470
|
}
|
|
11471
11471
|
}
|
|
11472
11472
|
|
|
11473
|
+
/**
|
|
11474
|
+
* Transport frame layer for multiplexing logical links on physical channels.
|
|
11475
|
+
*
|
|
11476
|
+
* This lightweight framing layer wraps raw FAME payloads to enable multiple
|
|
11477
|
+
* logical connections over a single physical channel (BroadcastChannel or InPage bus).
|
|
11478
|
+
*
|
|
11479
|
+
* The transport frame does NOT modify FAME envelopes - it only wraps the raw
|
|
11480
|
+
* Uint8Array payload at the connector level.
|
|
11481
|
+
*/
|
|
11482
|
+
/**
|
|
11483
|
+
* Transport frame version for future compatibility
|
|
11484
|
+
*/
|
|
11485
|
+
const TRANSPORT_FRAME_VERSION = 1;
|
|
11486
|
+
/**
|
|
11487
|
+
* Wrap a raw payload in a transport frame
|
|
11488
|
+
*
|
|
11489
|
+
* @param payload - Raw FAME envelope bytes
|
|
11490
|
+
* @param srcNodeId - Local node ID (this connector)
|
|
11491
|
+
* @param dstNodeId - Remote node ID (target connector)
|
|
11492
|
+
* @returns Transport frame ready for transmission
|
|
11493
|
+
*/
|
|
11494
|
+
function wrapTransportFrame(payload, srcNodeId, dstNodeId) {
|
|
11495
|
+
return {
|
|
11496
|
+
v: TRANSPORT_FRAME_VERSION,
|
|
11497
|
+
src: srcNodeId,
|
|
11498
|
+
dst: dstNodeId,
|
|
11499
|
+
payload,
|
|
11500
|
+
};
|
|
11501
|
+
}
|
|
11502
|
+
/**
|
|
11503
|
+
* Serialize a transport frame for transmission over the bus
|
|
11504
|
+
*
|
|
11505
|
+
* @param frame - Transport frame to serialize
|
|
11506
|
+
* @returns Serialized frame data ready for postMessage/dispatchEvent
|
|
11507
|
+
*/
|
|
11508
|
+
function serializeTransportFrame(frame) {
|
|
11509
|
+
// Convert Uint8Array to regular array for JSON serialization
|
|
11510
|
+
const serializable = {
|
|
11511
|
+
v: frame.v,
|
|
11512
|
+
src: frame.src,
|
|
11513
|
+
dst: frame.dst,
|
|
11514
|
+
payload: Array.from(frame.payload),
|
|
11515
|
+
};
|
|
11516
|
+
return serializable;
|
|
11517
|
+
}
|
|
11518
|
+
/**
|
|
11519
|
+
* Unwrap a transport frame, validating source and destination
|
|
11520
|
+
*
|
|
11521
|
+
* @param raw - Raw data from the bus
|
|
11522
|
+
* @param localNodeId - This connector's node ID
|
|
11523
|
+
* @param remoteNodeId - Expected remote node ID
|
|
11524
|
+
* @returns Unwrapped payload if frame is valid and addressed to us, null otherwise
|
|
11525
|
+
*/
|
|
11526
|
+
function unwrapTransportFrame(raw, localNodeId, remoteNodeId) {
|
|
11527
|
+
// Validate basic structure
|
|
11528
|
+
if (!raw || typeof raw !== 'object') {
|
|
11529
|
+
return null;
|
|
11530
|
+
}
|
|
11531
|
+
const frame = raw;
|
|
11532
|
+
// Check version
|
|
11533
|
+
if (frame.v !== TRANSPORT_FRAME_VERSION) {
|
|
11534
|
+
return null;
|
|
11535
|
+
}
|
|
11536
|
+
// Check src and dst
|
|
11537
|
+
if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
|
|
11538
|
+
return null;
|
|
11539
|
+
}
|
|
11540
|
+
// Only accept frames addressed to us from the expected remote
|
|
11541
|
+
if (frame.dst !== localNodeId || frame.src !== remoteNodeId) {
|
|
11542
|
+
return null;
|
|
11543
|
+
}
|
|
11544
|
+
// Extract payload
|
|
11545
|
+
if (!frame.payload || !Array.isArray(frame.payload)) {
|
|
11546
|
+
return null;
|
|
11547
|
+
}
|
|
11548
|
+
// Convert array back to Uint8Array
|
|
11549
|
+
return Uint8Array.from(frame.payload);
|
|
11550
|
+
}
|
|
11551
|
+
/**
|
|
11552
|
+
* Check if raw data looks like a transport frame
|
|
11553
|
+
*
|
|
11554
|
+
* @param raw - Raw data from the bus
|
|
11555
|
+
* @returns True if this appears to be a transport frame
|
|
11556
|
+
*/
|
|
11557
|
+
function isTransportFrame(raw) {
|
|
11558
|
+
if (!raw || typeof raw !== 'object') {
|
|
11559
|
+
return false;
|
|
11560
|
+
}
|
|
11561
|
+
const frame = raw;
|
|
11562
|
+
return (typeof frame.v === 'number' &&
|
|
11563
|
+
typeof frame.src === 'string' &&
|
|
11564
|
+
typeof frame.dst === 'string' &&
|
|
11565
|
+
Array.isArray(frame.payload));
|
|
11566
|
+
}
|
|
11567
|
+
|
|
11473
11568
|
const logger$10 = getLogger('naylence.fame.connector.broadcast_channel_connector');
|
|
11474
11569
|
const BROADCAST_CHANNEL_CONNECTOR_TYPE$1 = 'broadcast-channel-connector';
|
|
11475
11570
|
const DEFAULT_CHANNEL$7 = 'naylence-fabric';
|
|
@@ -11535,9 +11630,20 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11535
11630
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
11536
11631
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
11537
11632
|
this.channel = new BroadcastChannel(this.channelName);
|
|
11633
|
+
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
11634
|
+
this.localNodeId =
|
|
11635
|
+
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
11636
|
+
? config.localNodeId.trim()
|
|
11637
|
+
: this.connectorId;
|
|
11638
|
+
this.remoteNodeId =
|
|
11639
|
+
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
11640
|
+
? config.remoteNodeId.trim()
|
|
11641
|
+
: '*'; // Accept from any remote if not specified
|
|
11538
11642
|
logger$10.debug('broadcast_channel_connector_created', {
|
|
11539
11643
|
channel: this.channelName,
|
|
11540
11644
|
connector_id: this.connectorId,
|
|
11645
|
+
local_node_id: this.localNodeId,
|
|
11646
|
+
remote_node_id: this.remoteNodeId,
|
|
11541
11647
|
inbox_capacity: preferredCapacity,
|
|
11542
11648
|
timestamp: new Date().toISOString(),
|
|
11543
11649
|
});
|
|
@@ -11570,6 +11676,46 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11570
11676
|
if (busMessage.senderId === this.connectorId) {
|
|
11571
11677
|
return;
|
|
11572
11678
|
}
|
|
11679
|
+
// Try to unwrap as transport frame
|
|
11680
|
+
const unwrapped = unwrapTransportFrame(busMessage.payload, this.localNodeId, this.remoteNodeId === '*' ? busMessage.senderId : this.remoteNodeId);
|
|
11681
|
+
if (unwrapped) {
|
|
11682
|
+
// Successfully unwrapped transport frame
|
|
11683
|
+
logger$10.debug('broadcast_channel_transport_frame_received', {
|
|
11684
|
+
channel: this.channelName,
|
|
11685
|
+
sender_id: busMessage.senderId,
|
|
11686
|
+
connector_id: this.connectorId,
|
|
11687
|
+
local_node_id: this.localNodeId,
|
|
11688
|
+
remote_node_id: this.remoteNodeId,
|
|
11689
|
+
payload_length: unwrapped.byteLength,
|
|
11690
|
+
});
|
|
11691
|
+
if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
|
|
11692
|
+
return;
|
|
11693
|
+
}
|
|
11694
|
+
try {
|
|
11695
|
+
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
11696
|
+
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
11697
|
+
if (accepted) {
|
|
11698
|
+
return;
|
|
11699
|
+
}
|
|
11700
|
+
}
|
|
11701
|
+
this.inbox.enqueue(unwrapped);
|
|
11702
|
+
}
|
|
11703
|
+
catch (error) {
|
|
11704
|
+
if (error instanceof QueueFullError) {
|
|
11705
|
+
logger$10.warning('broadcast_channel_receive_queue_full', {
|
|
11706
|
+
channel: this.channelName,
|
|
11707
|
+
});
|
|
11708
|
+
}
|
|
11709
|
+
else {
|
|
11710
|
+
logger$10.error('broadcast_channel_receive_error', {
|
|
11711
|
+
channel: this.channelName,
|
|
11712
|
+
error: error instanceof Error ? error.message : String(error),
|
|
11713
|
+
});
|
|
11714
|
+
}
|
|
11715
|
+
}
|
|
11716
|
+
return;
|
|
11717
|
+
}
|
|
11718
|
+
// Fall back to legacy format (no transport frame)
|
|
11573
11719
|
const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
|
|
11574
11720
|
if (!payload) {
|
|
11575
11721
|
logger$10.debug('broadcast_channel_payload_rejected', {
|
|
@@ -11708,10 +11854,26 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11708
11854
|
logger$10.debug('broadcast_channel_message_sending', {
|
|
11709
11855
|
channel: this.channelName,
|
|
11710
11856
|
sender_id: this.connectorId,
|
|
11711
|
-
|
|
11857
|
+
local_node_id: this.localNodeId,
|
|
11858
|
+
remote_node_id: this.remoteNodeId,
|
|
11859
|
+
});
|
|
11860
|
+
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
11861
|
+
// (not using default values). This ensures backwards compatibility.
|
|
11862
|
+
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
11863
|
+
this.remoteNodeId !== '*';
|
|
11864
|
+
let payload;
|
|
11865
|
+
if (useTransportFrame) {
|
|
11866
|
+
// Wrap payload in transport frame
|
|
11867
|
+
const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
|
|
11868
|
+
payload = serializeTransportFrame(frame);
|
|
11869
|
+
}
|
|
11870
|
+
else {
|
|
11871
|
+
// Legacy format: send raw payload
|
|
11872
|
+
payload = data;
|
|
11873
|
+
}
|
|
11712
11874
|
this.channel.postMessage({
|
|
11713
11875
|
senderId: this.connectorId,
|
|
11714
|
-
payload
|
|
11876
|
+
payload,
|
|
11715
11877
|
});
|
|
11716
11878
|
}
|
|
11717
11879
|
async _transportReceive() {
|
|
@@ -11959,6 +12121,14 @@ function isBroadcastChannelConnectionGrant(candidate) {
|
|
|
11959
12121
|
record.inboxCapacity <= 0)) {
|
|
11960
12122
|
return false;
|
|
11961
12123
|
}
|
|
12124
|
+
if (record.localNodeId !== undefined &&
|
|
12125
|
+
(typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
|
|
12126
|
+
return false;
|
|
12127
|
+
}
|
|
12128
|
+
if (record.remoteNodeId !== undefined &&
|
|
12129
|
+
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
12130
|
+
return false;
|
|
12131
|
+
}
|
|
11962
12132
|
return true;
|
|
11963
12133
|
}
|
|
11964
12134
|
function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
@@ -11992,6 +12162,20 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
|
11992
12162
|
}
|
|
11993
12163
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
11994
12164
|
}
|
|
12165
|
+
const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
|
|
12166
|
+
if (localNodeIdValue !== undefined) {
|
|
12167
|
+
if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
|
|
12168
|
+
throw new TypeError('BroadcastChannelConnectionGrant "localNodeId" must be a non-empty string when provided');
|
|
12169
|
+
}
|
|
12170
|
+
result.localNodeId = localNodeIdValue.trim();
|
|
12171
|
+
}
|
|
12172
|
+
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
12173
|
+
if (remoteNodeIdValue !== undefined) {
|
|
12174
|
+
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
12175
|
+
throw new TypeError('BroadcastChannelConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
12176
|
+
}
|
|
12177
|
+
result.remoteNodeId = remoteNodeIdValue.trim();
|
|
12178
|
+
}
|
|
11995
12179
|
return result;
|
|
11996
12180
|
}
|
|
11997
12181
|
function broadcastChannelGrantToConnectorConfig(grant) {
|
|
@@ -12005,6 +12189,12 @@ function broadcastChannelGrantToConnectorConfig(grant) {
|
|
|
12005
12189
|
if (normalized.inboxCapacity !== undefined) {
|
|
12006
12190
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
12007
12191
|
}
|
|
12192
|
+
if (normalized.localNodeId) {
|
|
12193
|
+
config.localNodeId = normalized.localNodeId;
|
|
12194
|
+
}
|
|
12195
|
+
if (normalized.remoteNodeId) {
|
|
12196
|
+
config.remoteNodeId = normalized.remoteNodeId;
|
|
12197
|
+
}
|
|
12008
12198
|
return config;
|
|
12009
12199
|
}
|
|
12010
12200
|
|
|
@@ -21437,9 +21627,20 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
21437
21627
|
: DEFAULT_INBOX_CAPACITY$6;
|
|
21438
21628
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
21439
21629
|
this.connectorId = InPageConnector.generateConnectorId();
|
|
21630
|
+
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
21631
|
+
this.localNodeId =
|
|
21632
|
+
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
21633
|
+
? config.localNodeId.trim()
|
|
21634
|
+
: this.connectorId;
|
|
21635
|
+
this.remoteNodeId =
|
|
21636
|
+
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
21637
|
+
? config.remoteNodeId.trim()
|
|
21638
|
+
: '*'; // Accept from any remote if not specified
|
|
21440
21639
|
logger$J.debug('inpage_connector_initialized', {
|
|
21441
21640
|
channel: this.channelName,
|
|
21442
21641
|
connector_id: this.connectorId,
|
|
21642
|
+
local_node_id: this.localNodeId,
|
|
21643
|
+
remote_node_id: this.remoteNodeId,
|
|
21443
21644
|
});
|
|
21444
21645
|
this.onMsg = (event) => {
|
|
21445
21646
|
const messageEvent = event;
|
|
@@ -21473,6 +21674,43 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
21473
21674
|
if (busMessage.senderId === this.connectorId) {
|
|
21474
21675
|
return;
|
|
21475
21676
|
}
|
|
21677
|
+
// Try to unwrap as transport frame
|
|
21678
|
+
const unwrapped = unwrapTransportFrame(busMessage.payload, this.localNodeId, this.remoteNodeId === '*' ? busMessage.senderId : this.remoteNodeId);
|
|
21679
|
+
if (unwrapped) {
|
|
21680
|
+
// Successfully unwrapped transport frame
|
|
21681
|
+
logger$J.debug('inpage_transport_frame_received', {
|
|
21682
|
+
channel: this.channelName,
|
|
21683
|
+
sender_id: busMessage.senderId,
|
|
21684
|
+
connector_id: this.connectorId,
|
|
21685
|
+
local_node_id: this.localNodeId,
|
|
21686
|
+
remote_node_id: this.remoteNodeId,
|
|
21687
|
+
payload_length: unwrapped.byteLength,
|
|
21688
|
+
});
|
|
21689
|
+
try {
|
|
21690
|
+
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
21691
|
+
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
21692
|
+
if (accepted) {
|
|
21693
|
+
return;
|
|
21694
|
+
}
|
|
21695
|
+
}
|
|
21696
|
+
this.inbox.enqueue(unwrapped);
|
|
21697
|
+
}
|
|
21698
|
+
catch (error) {
|
|
21699
|
+
if (error instanceof QueueFullError) {
|
|
21700
|
+
logger$J.warning('inpage_receive_queue_full', {
|
|
21701
|
+
channel: this.channelName,
|
|
21702
|
+
});
|
|
21703
|
+
}
|
|
21704
|
+
else {
|
|
21705
|
+
logger$J.error('inpage_receive_error', {
|
|
21706
|
+
channel: this.channelName,
|
|
21707
|
+
error: error instanceof Error ? error.message : String(error),
|
|
21708
|
+
});
|
|
21709
|
+
}
|
|
21710
|
+
}
|
|
21711
|
+
return;
|
|
21712
|
+
}
|
|
21713
|
+
// Fall back to legacy format (no transport frame)
|
|
21476
21714
|
const payload = InPageConnector.coercePayload(busMessage.payload);
|
|
21477
21715
|
if (!payload) {
|
|
21478
21716
|
logger$J.debug('inpage_payload_rejected', {
|
|
@@ -21631,11 +21869,27 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
21631
21869
|
logger$J.debug('inpage_message_sending', {
|
|
21632
21870
|
channel: this.channelName,
|
|
21633
21871
|
sender_id: this.connectorId,
|
|
21634
|
-
|
|
21872
|
+
local_node_id: this.localNodeId,
|
|
21873
|
+
remote_node_id: this.remoteNodeId,
|
|
21874
|
+
});
|
|
21875
|
+
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
21876
|
+
// (not using default values). This ensures backwards compatibility.
|
|
21877
|
+
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
21878
|
+
this.remoteNodeId !== '*';
|
|
21879
|
+
let payload;
|
|
21880
|
+
if (useTransportFrame) {
|
|
21881
|
+
// Wrap payload in transport frame
|
|
21882
|
+
const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
|
|
21883
|
+
payload = serializeTransportFrame(frame);
|
|
21884
|
+
}
|
|
21885
|
+
else {
|
|
21886
|
+
// Legacy format: send raw payload
|
|
21887
|
+
payload = data;
|
|
21888
|
+
}
|
|
21635
21889
|
const event = new MessageEvent(this.channelName, {
|
|
21636
21890
|
data: {
|
|
21637
21891
|
senderId: this.connectorId,
|
|
21638
|
-
payload
|
|
21892
|
+
payload,
|
|
21639
21893
|
},
|
|
21640
21894
|
});
|
|
21641
21895
|
getSharedBus$1().dispatchEvent(event);
|
|
@@ -28947,6 +29201,14 @@ function isInPageConnectionGrant(candidate) {
|
|
|
28947
29201
|
record.inboxCapacity <= 0)) {
|
|
28948
29202
|
return false;
|
|
28949
29203
|
}
|
|
29204
|
+
if (record.localNodeId !== undefined &&
|
|
29205
|
+
(typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
|
|
29206
|
+
return false;
|
|
29207
|
+
}
|
|
29208
|
+
if (record.remoteNodeId !== undefined &&
|
|
29209
|
+
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
29210
|
+
return false;
|
|
29211
|
+
}
|
|
28950
29212
|
return true;
|
|
28951
29213
|
}
|
|
28952
29214
|
function normalizeInPageConnectionGrant(candidate) {
|
|
@@ -28980,6 +29242,20 @@ function normalizeInPageConnectionGrant(candidate) {
|
|
|
28980
29242
|
}
|
|
28981
29243
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
28982
29244
|
}
|
|
29245
|
+
const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
|
|
29246
|
+
if (localNodeIdValue !== undefined) {
|
|
29247
|
+
if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
|
|
29248
|
+
throw new TypeError('InPageConnectionGrant "localNodeId" must be a non-empty string when provided');
|
|
29249
|
+
}
|
|
29250
|
+
result.localNodeId = localNodeIdValue.trim();
|
|
29251
|
+
}
|
|
29252
|
+
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
29253
|
+
if (remoteNodeIdValue !== undefined) {
|
|
29254
|
+
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
29255
|
+
throw new TypeError('InPageConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
29256
|
+
}
|
|
29257
|
+
result.remoteNodeId = remoteNodeIdValue.trim();
|
|
29258
|
+
}
|
|
28983
29259
|
return result;
|
|
28984
29260
|
}
|
|
28985
29261
|
function inPageGrantToConnectorConfig(grant) {
|
|
@@ -28993,6 +29269,12 @@ function inPageGrantToConnectorConfig(grant) {
|
|
|
28993
29269
|
if (normalized.inboxCapacity !== undefined) {
|
|
28994
29270
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
28995
29271
|
}
|
|
29272
|
+
if (normalized.localNodeId) {
|
|
29273
|
+
config.localNodeId = normalized.localNodeId;
|
|
29274
|
+
}
|
|
29275
|
+
if (normalized.remoteNodeId) {
|
|
29276
|
+
config.remoteNodeId = normalized.remoteNodeId;
|
|
29277
|
+
}
|
|
28996
29278
|
return config;
|
|
28997
29279
|
}
|
|
28998
29280
|
|
|
@@ -30260,6 +30542,8 @@ class InPageConnectorFactory extends ConnectorFactory {
|
|
|
30260
30542
|
type: INPAGE_CONNECTOR_TYPE,
|
|
30261
30543
|
channelName,
|
|
30262
30544
|
inboxCapacity,
|
|
30545
|
+
localNodeId: normalized.localNodeId,
|
|
30546
|
+
remoteNodeId: normalized.remoteNodeId,
|
|
30263
30547
|
};
|
|
30264
30548
|
const connector = new InPageConnector(connectorConfig, baseConfig);
|
|
30265
30549
|
if (options.authorization) {
|
|
@@ -30328,6 +30612,16 @@ class InPageConnectorFactory extends ConnectorFactory {
|
|
|
30328
30612
|
if (candidate.authorizationContext !== undefined) {
|
|
30329
30613
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
30330
30614
|
}
|
|
30615
|
+
// Handle localNodeId
|
|
30616
|
+
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
30617
|
+
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
30618
|
+
normalized.localNodeId = localNodeId.trim();
|
|
30619
|
+
}
|
|
30620
|
+
// Handle remoteNodeId
|
|
30621
|
+
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
30622
|
+
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
30623
|
+
normalized.remoteNodeId = remoteNodeId.trim();
|
|
30624
|
+
}
|
|
30331
30625
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$3;
|
|
30332
30626
|
normalized.inboxCapacity =
|
|
30333
30627
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$3;
|
|
@@ -30427,6 +30721,8 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
30427
30721
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE$1,
|
|
30428
30722
|
channelName,
|
|
30429
30723
|
inboxCapacity,
|
|
30724
|
+
localNodeId: normalized.localNodeId,
|
|
30725
|
+
remoteNodeId: normalized.remoteNodeId,
|
|
30430
30726
|
};
|
|
30431
30727
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
30432
30728
|
if (options.authorization) {
|
|
@@ -30488,6 +30784,16 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
30488
30784
|
if (candidate.authorizationContext !== undefined) {
|
|
30489
30785
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
30490
30786
|
}
|
|
30787
|
+
// Handle localNodeId
|
|
30788
|
+
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
30789
|
+
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
30790
|
+
normalized.localNodeId = localNodeId.trim();
|
|
30791
|
+
}
|
|
30792
|
+
// Handle remoteNodeId
|
|
30793
|
+
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
30794
|
+
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
30795
|
+
normalized.remoteNodeId = remoteNodeId.trim();
|
|
30796
|
+
}
|
|
30491
30797
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$2;
|
|
30492
30798
|
normalized.inboxCapacity =
|
|
30493
30799
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$2;
|
|
@@ -31972,6 +32278,7 @@ class InPageListener extends TransportListener {
|
|
|
31972
32278
|
this._busHandler = null;
|
|
31973
32279
|
this._senderRegistry = new Map();
|
|
31974
32280
|
this._systemToSender = new Map();
|
|
32281
|
+
this._flowIdToSender = new Map();
|
|
31975
32282
|
this._pendingAttachments = new Map();
|
|
31976
32283
|
ensureBrowserEnvironment$1();
|
|
31977
32284
|
const channelCandidate = options?.channelName;
|
|
@@ -32038,6 +32345,7 @@ class InPageListener extends TransportListener {
|
|
|
32038
32345
|
this._unregisterBusListener();
|
|
32039
32346
|
this._senderRegistry.clear();
|
|
32040
32347
|
this._systemToSender.clear();
|
|
32348
|
+
this._flowIdToSender.clear();
|
|
32041
32349
|
this._pendingAttachments.clear();
|
|
32042
32350
|
logger$o.debug('inpage_listener_stopped', {
|
|
32043
32351
|
channel: this._channelName,
|
|
@@ -32091,10 +32399,25 @@ class InPageListener extends TransportListener {
|
|
|
32091
32399
|
await this._handleAttachFrame(senderId, envelope);
|
|
32092
32400
|
return;
|
|
32093
32401
|
}
|
|
32094
|
-
|
|
32402
|
+
// Try to find connector by sender ID first
|
|
32403
|
+
let entry = this._senderRegistry.get(senderId);
|
|
32404
|
+
// If not found and we have a flowId, try to route based on flow
|
|
32405
|
+
if (!entry && envelope.flowId) {
|
|
32406
|
+
const originalSenderId = this._flowIdToSender.get(envelope.flowId);
|
|
32407
|
+
if (originalSenderId) {
|
|
32408
|
+
entry = this._senderRegistry.get(originalSenderId);
|
|
32409
|
+
logger$o.debug('inpage_listener_routed_by_flow_id', {
|
|
32410
|
+
sender_id: senderId,
|
|
32411
|
+
original_sender_id: originalSenderId,
|
|
32412
|
+
flow_id: envelope.flowId,
|
|
32413
|
+
frame_type: envelope.frame?.type ?? 'unknown',
|
|
32414
|
+
});
|
|
32415
|
+
}
|
|
32416
|
+
}
|
|
32095
32417
|
if (!entry) {
|
|
32096
32418
|
logger$o.debug('inpage_listener_no_connector_for_sender', {
|
|
32097
32419
|
sender_id: senderId,
|
|
32420
|
+
flow_id: envelope.flowId,
|
|
32098
32421
|
frame_type: envelope.frame?.type ?? 'unknown',
|
|
32099
32422
|
});
|
|
32100
32423
|
return;
|
|
@@ -32171,6 +32494,15 @@ class InPageListener extends TransportListener {
|
|
|
32171
32494
|
}
|
|
32172
32495
|
this._senderRegistry.set(senderId, entry);
|
|
32173
32496
|
this._systemToSender.set(entry.systemId, senderId);
|
|
32497
|
+
// Track the flowId if present so we can route responses back
|
|
32498
|
+
if (envelope.flowId) {
|
|
32499
|
+
this._flowIdToSender.set(envelope.flowId, senderId);
|
|
32500
|
+
logger$o.debug('inpage_listener_registered_flow_id', {
|
|
32501
|
+
sender_id: senderId,
|
|
32502
|
+
system_id: entry.systemId,
|
|
32503
|
+
flow_id: envelope.flowId,
|
|
32504
|
+
});
|
|
32505
|
+
}
|
|
32174
32506
|
await this._deliverEnvelope(entry, envelope);
|
|
32175
32507
|
}
|
|
32176
32508
|
async _createConnectorForAttach(params) {
|
|
@@ -32218,7 +32550,7 @@ class InPageListener extends TransportListener {
|
|
|
32218
32550
|
origin_type: originType,
|
|
32219
32551
|
connector_type: connector.constructor?.name ?? 'unknown',
|
|
32220
32552
|
});
|
|
32221
|
-
return { connector, systemId, originType };
|
|
32553
|
+
return { connector, systemId, originType, senderId: params.senderId };
|
|
32222
32554
|
}
|
|
32223
32555
|
catch (error) {
|
|
32224
32556
|
logger$o.error('inpage_listener_connector_creation_failed', {
|
|
@@ -32272,6 +32604,12 @@ class InPageListener extends TransportListener {
|
|
|
32272
32604
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
32273
32605
|
this._systemToSender.delete(systemId);
|
|
32274
32606
|
}
|
|
32607
|
+
// Clean up flowId mappings for this sender
|
|
32608
|
+
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
32609
|
+
if (sid === senderId) {
|
|
32610
|
+
this._flowIdToSender.delete(flowId);
|
|
32611
|
+
}
|
|
32612
|
+
}
|
|
32275
32613
|
})
|
|
32276
32614
|
.catch((error) => {
|
|
32277
32615
|
logger$o.debug('inpage_listener_wait_until_closed_failed', {
|
|
@@ -32283,9 +32621,24 @@ class InPageListener extends TransportListener {
|
|
|
32283
32621
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
32284
32622
|
this._systemToSender.delete(systemId);
|
|
32285
32623
|
}
|
|
32624
|
+
// Clean up flowId mappings for this sender
|
|
32625
|
+
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
32626
|
+
if (sid === senderId) {
|
|
32627
|
+
this._flowIdToSender.delete(flowId);
|
|
32628
|
+
}
|
|
32629
|
+
}
|
|
32286
32630
|
});
|
|
32287
32631
|
}
|
|
32288
32632
|
async _deliverEnvelope(entry, envelope) {
|
|
32633
|
+
// Track flowId for routing responses back
|
|
32634
|
+
if (envelope.flowId && !this._flowIdToSender.has(envelope.flowId)) {
|
|
32635
|
+
this._flowIdToSender.set(envelope.flowId, entry.senderId);
|
|
32636
|
+
logger$o.debug('inpage_listener_registered_flow_id_on_delivery', {
|
|
32637
|
+
sender_id: entry.senderId,
|
|
32638
|
+
system_id: entry.systemId,
|
|
32639
|
+
flow_id: envelope.flowId,
|
|
32640
|
+
});
|
|
32641
|
+
}
|
|
32289
32642
|
const message = this._buildChannelMessage({
|
|
32290
32643
|
envelope,
|
|
32291
32644
|
connector: entry.connector,
|
|
@@ -32666,6 +33019,26 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
32666
33019
|
inboxCapacity: this._inboxCapacity,
|
|
32667
33020
|
};
|
|
32668
33021
|
}
|
|
33022
|
+
// Automatically configure transport frame multiplexing:
|
|
33023
|
+
// Set remoteNodeId to the incoming senderId to target responses back to the specific client/agent
|
|
33024
|
+
const broadcastConfig = connectorConfig;
|
|
33025
|
+
if (!broadcastConfig.remoteNodeId) {
|
|
33026
|
+
broadcastConfig.remoteNodeId = params.senderId;
|
|
33027
|
+
logger$n.debug('broadcast_channel_listener_auto_configured_remote_node_id', {
|
|
33028
|
+
sender_id: params.senderId,
|
|
33029
|
+
system_id: systemId,
|
|
33030
|
+
remote_node_id: params.senderId,
|
|
33031
|
+
local_node_id: broadcastConfig.localNodeId ?? '<not set>',
|
|
33032
|
+
});
|
|
33033
|
+
}
|
|
33034
|
+
else {
|
|
33035
|
+
logger$n.debug('broadcast_channel_listener_using_provided_remote_node_id', {
|
|
33036
|
+
sender_id: params.senderId,
|
|
33037
|
+
system_id: systemId,
|
|
33038
|
+
remote_node_id: broadcastConfig.remoteNodeId,
|
|
33039
|
+
local_node_id: broadcastConfig.localNodeId ?? '<not set>',
|
|
33040
|
+
});
|
|
33041
|
+
}
|
|
32669
33042
|
try {
|
|
32670
33043
|
const connector = await routingNode.createOriginConnector({
|
|
32671
33044
|
originType,
|
|
@@ -32735,6 +33108,21 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
32735
33108
|
inboxCandidate > 0) {
|
|
32736
33109
|
config.inboxCapacity = Math.floor(inboxCandidate);
|
|
32737
33110
|
}
|
|
33111
|
+
// Extract transport frame multiplexing node IDs
|
|
33112
|
+
const localNodeIdCandidate = candidate.localNodeId ?? candidate['local_node_id'];
|
|
33113
|
+
if (typeof localNodeIdCandidate === 'string' && localNodeIdCandidate.trim().length > 0) {
|
|
33114
|
+
config.localNodeId = localNodeIdCandidate.trim();
|
|
33115
|
+
logger$n.debug('broadcast_channel_listener_extracted_local_node_id', {
|
|
33116
|
+
local_node_id: config.localNodeId,
|
|
33117
|
+
});
|
|
33118
|
+
}
|
|
33119
|
+
const remoteNodeIdCandidate = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
33120
|
+
if (typeof remoteNodeIdCandidate === 'string' && remoteNodeIdCandidate.trim().length > 0) {
|
|
33121
|
+
config.remoteNodeId = remoteNodeIdCandidate.trim();
|
|
33122
|
+
logger$n.debug('broadcast_channel_listener_extracted_remote_node_id', {
|
|
33123
|
+
remote_node_id: config.remoteNodeId,
|
|
33124
|
+
});
|
|
33125
|
+
}
|
|
32738
33126
|
return config;
|
|
32739
33127
|
}
|
|
32740
33128
|
_monitorConnectorLifecycle(senderId, systemId, connector) {
|
|
@@ -7,6 +7,8 @@ export interface BroadcastChannelConnectorFactoryConfig extends ConnectorConfig,
|
|
|
7
7
|
type: typeof BROADCAST_CHANNEL_CONNECTOR_TYPE;
|
|
8
8
|
channelName?: string;
|
|
9
9
|
inboxCapacity?: number;
|
|
10
|
+
localNodeId?: string;
|
|
11
|
+
remoteNodeId?: string;
|
|
10
12
|
}
|
|
11
13
|
export interface CreateBroadcastChannelConnectorOptions {
|
|
12
14
|
authorization?: AuthorizationContext;
|
|
@@ -6,6 +6,8 @@ export interface BroadcastChannelConnectorConfig extends ConnectorConfig {
|
|
|
6
6
|
type: typeof BROADCAST_CHANNEL_CONNECTOR_TYPE;
|
|
7
7
|
channelName?: string;
|
|
8
8
|
inboxCapacity?: number;
|
|
9
|
+
localNodeId?: string;
|
|
10
|
+
remoteNodeId?: string;
|
|
9
11
|
}
|
|
10
12
|
type BroadcastChannelInboxItem = Uint8Array | FameEnvelope | FameChannelMessage;
|
|
11
13
|
export declare class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
@@ -22,6 +24,8 @@ export declare class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
22
24
|
private readonly textDecoder;
|
|
23
25
|
private visibilityChangeListenerRegistered;
|
|
24
26
|
private visibilityChangeHandler?;
|
|
27
|
+
private readonly localNodeId;
|
|
28
|
+
private readonly remoteNodeId;
|
|
25
29
|
private static generateConnectorId;
|
|
26
30
|
private static coercePayload;
|
|
27
31
|
constructor(config: BroadcastChannelConnectorConfig, baseConfig?: BaseAsyncConnectorConfig);
|
|
@@ -9,6 +9,8 @@ export interface InPageConnectorFactoryConfig extends ConnectorConfig, Partial<B
|
|
|
9
9
|
type: typeof INPAGE_CONNECTOR_TYPE;
|
|
10
10
|
channelName?: string;
|
|
11
11
|
inboxCapacity?: number;
|
|
12
|
+
localNodeId?: string;
|
|
13
|
+
remoteNodeId?: string;
|
|
12
14
|
}
|
|
13
15
|
export interface CreateInPageConnectorOptions {
|
|
14
16
|
systemId?: string;
|
|
@@ -10,6 +10,8 @@ export interface InPageConnectorConfig extends ConnectorConfig {
|
|
|
10
10
|
type: typeof INPAGE_CONNECTOR_TYPE;
|
|
11
11
|
channelName?: string;
|
|
12
12
|
inboxCapacity?: number;
|
|
13
|
+
localNodeId?: string;
|
|
14
|
+
remoteNodeId?: string;
|
|
13
15
|
}
|
|
14
16
|
type InPageInboxItem = Uint8Array | FameEnvelope | FameChannelMessage;
|
|
15
17
|
export declare class InPageConnector extends BaseAsyncConnector {
|
|
@@ -20,6 +22,8 @@ export declare class InPageConnector extends BaseAsyncConnector {
|
|
|
20
22
|
private readonly onMsg;
|
|
21
23
|
private visibilityChangeListenerRegistered;
|
|
22
24
|
private visibilityChangeHandler?;
|
|
25
|
+
private readonly localNodeId;
|
|
26
|
+
private readonly remoteNodeId;
|
|
23
27
|
private static generateConnectorId;
|
|
24
28
|
private static coercePayload;
|
|
25
29
|
constructor(config: InPageConnectorConfig, baseConfig?: BaseAsyncConnectorConfig);
|
|
@@ -14,6 +14,7 @@ export declare class InPageListener extends TransportListener {
|
|
|
14
14
|
private _busHandler;
|
|
15
15
|
private readonly _senderRegistry;
|
|
16
16
|
private readonly _systemToSender;
|
|
17
|
+
private readonly _flowIdToSender;
|
|
17
18
|
private readonly _pendingAttachments;
|
|
18
19
|
constructor(options?: InPageListenerOptions);
|
|
19
20
|
get channelName(): string;
|