@naylence/runtime 0.3.5-test.961 → 0.3.5-test.963
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 +290 -33
- package/dist/browser/index.mjs +290 -33
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector-factory.js +36 -0
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +131 -6
- package/dist/cjs/naylence/fame/connector/broadcast-channel-listener.js +91 -25
- package/dist/cjs/naylence/fame/node/upstream-session-manager.js +30 -0
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +36 -0
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +131 -6
- package/dist/esm/naylence/fame/connector/broadcast-channel-listener.js +91 -25
- package/dist/esm/naylence/fame/node/upstream-session-manager.js +30 -0
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +290 -33
- package/dist/node/index.mjs +290 -33
- package/dist/node/node.cjs +290 -33
- package/dist/node/node.mjs +290 -33
- package/dist/types/naylence/fame/connector/broadcast-channel-connector-factory.d.ts +6 -0
- package/dist/types/naylence/fame/connector/broadcast-channel-connector.browser.d.ts +10 -0
- package/dist/types/naylence/fame/connector/broadcast-channel-connector.node.d.ts +1 -6
- package/dist/types/naylence/fame/connector/broadcast-channel-listener.d.ts +3 -0
- package/dist/types/naylence/fame/grants/broadcast-channel-connection-grant.d.ts +1 -1
- package/dist/types/naylence/fame/node/upstream-session-manager.d.ts +2 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/node/index.mjs
CHANGED
|
@@ -13,12 +13,12 @@ import fastify from 'fastify';
|
|
|
13
13
|
import websocketPlugin from '@fastify/websocket';
|
|
14
14
|
|
|
15
15
|
// This file is auto-generated during build - do not edit manually
|
|
16
|
-
// Generated from package.json version: 0.3.5-test.
|
|
16
|
+
// Generated from package.json version: 0.3.5-test.963
|
|
17
17
|
/**
|
|
18
18
|
* The package version, injected at build time.
|
|
19
19
|
* @internal
|
|
20
20
|
*/
|
|
21
|
-
const VERSION = '0.3.5-test.
|
|
21
|
+
const VERSION = '0.3.5-test.963';
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -9861,6 +9861,26 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9861
9861
|
}
|
|
9862
9862
|
return null;
|
|
9863
9863
|
}
|
|
9864
|
+
static normalizeNodeId(value) {
|
|
9865
|
+
if (typeof value !== 'string') {
|
|
9866
|
+
return null;
|
|
9867
|
+
}
|
|
9868
|
+
const trimmed = value.trim();
|
|
9869
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
9870
|
+
}
|
|
9871
|
+
static normalizeTargetNodeId(value) {
|
|
9872
|
+
if (typeof value !== 'string') {
|
|
9873
|
+
return undefined;
|
|
9874
|
+
}
|
|
9875
|
+
const trimmed = value.trim();
|
|
9876
|
+
if (trimmed.length === 0) {
|
|
9877
|
+
return undefined;
|
|
9878
|
+
}
|
|
9879
|
+
if (trimmed === '*') {
|
|
9880
|
+
return '*';
|
|
9881
|
+
}
|
|
9882
|
+
return trimmed;
|
|
9883
|
+
}
|
|
9864
9884
|
constructor(config, baseConfig = {}) {
|
|
9865
9885
|
ensureBroadcastEnvironment();
|
|
9866
9886
|
super(baseConfig);
|
|
@@ -9883,10 +9903,18 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9883
9903
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
9884
9904
|
this.inboxCapacity = preferredCapacity;
|
|
9885
9905
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
9906
|
+
const normalizedLocalNodeId = BroadcastChannelConnector.normalizeNodeId(config.localNodeId);
|
|
9907
|
+
if (!normalizedLocalNodeId) {
|
|
9908
|
+
throw new Error('BroadcastChannelConnector requires a non-empty localNodeId');
|
|
9909
|
+
}
|
|
9910
|
+
this.localNodeId = normalizedLocalNodeId;
|
|
9911
|
+
this.targetNodeId = BroadcastChannelConnector.normalizeTargetNodeId(config.initialTargetNodeId);
|
|
9886
9912
|
this.channel = new BroadcastChannel(this.channelName);
|
|
9887
9913
|
logger$_.debug('broadcast_channel_connector_created', {
|
|
9888
9914
|
channel: this.channelName,
|
|
9889
9915
|
connector_id: this.connectorId,
|
|
9916
|
+
local_node_id: this.localNodeId,
|
|
9917
|
+
target_node_id: this.targetNodeId ?? null,
|
|
9890
9918
|
inbox_capacity: preferredCapacity,
|
|
9891
9919
|
timestamp: new Date().toISOString(),
|
|
9892
9920
|
});
|
|
@@ -9908,15 +9936,32 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9908
9936
|
? message.constructor?.name ?? typeof message
|
|
9909
9937
|
: typeof message,
|
|
9910
9938
|
has_sender_id: Boolean(message?.senderId),
|
|
9939
|
+
has_sender_node_id: Boolean(message?.senderNodeId),
|
|
9911
9940
|
});
|
|
9912
9941
|
if (!message || typeof message !== 'object') {
|
|
9913
9942
|
return;
|
|
9914
9943
|
}
|
|
9915
9944
|
const busMessage = message;
|
|
9916
|
-
|
|
9945
|
+
const senderNodeId = BroadcastChannelConnector.normalizeNodeId(busMessage.senderNodeId);
|
|
9946
|
+
if (!senderNodeId) {
|
|
9947
|
+
logger$_.debug('broadcast_channel_message_rejected', {
|
|
9948
|
+
channel: this.channelName,
|
|
9949
|
+
connector_id: this.connectorId,
|
|
9950
|
+
reason: 'missing_sender_node_id',
|
|
9951
|
+
});
|
|
9917
9952
|
return;
|
|
9918
9953
|
}
|
|
9919
|
-
if (
|
|
9954
|
+
if (senderNodeId === this.localNodeId) {
|
|
9955
|
+
logger$_.debug('broadcast_channel_message_rejected', {
|
|
9956
|
+
channel: this.channelName,
|
|
9957
|
+
connector_id: this.connectorId,
|
|
9958
|
+
reason: 'self_echo',
|
|
9959
|
+
sender_node_id: senderNodeId,
|
|
9960
|
+
});
|
|
9961
|
+
return;
|
|
9962
|
+
}
|
|
9963
|
+
const incomingTargetNodeId = BroadcastChannelConnector.normalizeTargetNodeId(busMessage.targetNodeId);
|
|
9964
|
+
if (!this._shouldAcceptMessageFromBus(senderNodeId, incomingTargetNodeId)) {
|
|
9920
9965
|
return;
|
|
9921
9966
|
}
|
|
9922
9967
|
const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
|
|
@@ -9930,11 +9975,13 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9930
9975
|
}
|
|
9931
9976
|
logger$_.debug('broadcast_channel_message_received', {
|
|
9932
9977
|
channel: this.channelName,
|
|
9933
|
-
sender_id:
|
|
9978
|
+
sender_id: message?.senderId,
|
|
9979
|
+
sender_node_id: senderNodeId,
|
|
9980
|
+
target_node_id: incomingTargetNodeId ?? null,
|
|
9934
9981
|
connector_id: this.connectorId,
|
|
9935
9982
|
payload_length: payload.byteLength,
|
|
9936
9983
|
});
|
|
9937
|
-
if (this._shouldSkipDuplicateAck(
|
|
9984
|
+
if (this._shouldSkipDuplicateAck(senderNodeId, payload)) {
|
|
9938
9985
|
return;
|
|
9939
9986
|
}
|
|
9940
9987
|
try {
|
|
@@ -10078,12 +10125,17 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10078
10125
|
}
|
|
10079
10126
|
async _transportSendBytes(data) {
|
|
10080
10127
|
ensureBroadcastEnvironment();
|
|
10128
|
+
const targetNodeId = this.targetNodeId ?? '*';
|
|
10081
10129
|
logger$_.debug('broadcast_channel_message_sending', {
|
|
10082
10130
|
channel: this.channelName,
|
|
10083
10131
|
sender_id: this.connectorId,
|
|
10132
|
+
sender_node_id: this.localNodeId,
|
|
10133
|
+
target_node_id: targetNodeId,
|
|
10084
10134
|
});
|
|
10085
10135
|
this.channel.postMessage({
|
|
10086
10136
|
senderId: this.connectorId,
|
|
10137
|
+
senderNodeId: this.localNodeId,
|
|
10138
|
+
targetNodeId,
|
|
10087
10139
|
payload: data,
|
|
10088
10140
|
});
|
|
10089
10141
|
}
|
|
@@ -10146,6 +10198,51 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10146
10198
|
}
|
|
10147
10199
|
return rawOrEnvelope;
|
|
10148
10200
|
}
|
|
10201
|
+
_isWildcardTarget() {
|
|
10202
|
+
return this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined';
|
|
10203
|
+
}
|
|
10204
|
+
_shouldAcceptMessageFromBus(senderNodeId, targetNodeId) {
|
|
10205
|
+
if (this._isWildcardTarget()) {
|
|
10206
|
+
if (targetNodeId && targetNodeId !== '*') {
|
|
10207
|
+
logger$_.debug('broadcast_channel_message_rejected', {
|
|
10208
|
+
channel: this.channelName,
|
|
10209
|
+
connector_id: this.connectorId,
|
|
10210
|
+
reason: 'wildcard_target_mismatch',
|
|
10211
|
+
sender_node_id: senderNodeId,
|
|
10212
|
+
target_node_id: targetNodeId,
|
|
10213
|
+
local_node_id: this.localNodeId,
|
|
10214
|
+
});
|
|
10215
|
+
return false;
|
|
10216
|
+
}
|
|
10217
|
+
return true;
|
|
10218
|
+
}
|
|
10219
|
+
const expectedSender = this.targetNodeId;
|
|
10220
|
+
if (expectedSender && expectedSender !== '*' && senderNodeId !== expectedSender) {
|
|
10221
|
+
logger$_.debug('broadcast_channel_message_rejected', {
|
|
10222
|
+
channel: this.channelName,
|
|
10223
|
+
connector_id: this.connectorId,
|
|
10224
|
+
reason: 'unexpected_sender',
|
|
10225
|
+
expected_sender_node_id: expectedSender,
|
|
10226
|
+
sender_node_id: senderNodeId,
|
|
10227
|
+
local_node_id: this.localNodeId,
|
|
10228
|
+
});
|
|
10229
|
+
return false;
|
|
10230
|
+
}
|
|
10231
|
+
if (targetNodeId &&
|
|
10232
|
+
targetNodeId !== '*' &&
|
|
10233
|
+
targetNodeId !== this.localNodeId) {
|
|
10234
|
+
logger$_.debug('broadcast_channel_message_rejected', {
|
|
10235
|
+
channel: this.channelName,
|
|
10236
|
+
connector_id: this.connectorId,
|
|
10237
|
+
reason: 'unexpected_target',
|
|
10238
|
+
sender_node_id: senderNodeId,
|
|
10239
|
+
target_node_id: targetNodeId,
|
|
10240
|
+
local_node_id: this.localNodeId,
|
|
10241
|
+
});
|
|
10242
|
+
return false;
|
|
10243
|
+
}
|
|
10244
|
+
return true;
|
|
10245
|
+
}
|
|
10149
10246
|
_describeInboxItem(item) {
|
|
10150
10247
|
if (item instanceof Uint8Array) {
|
|
10151
10248
|
return 'bytes';
|
|
@@ -10176,7 +10273,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10176
10273
|
const normalizedSenderId = typeof senderId === 'string' && senderId.length > 0
|
|
10177
10274
|
? senderId
|
|
10178
10275
|
: undefined;
|
|
10179
|
-
if (normalizedSenderId && normalizedSenderId !== this.
|
|
10276
|
+
if (normalizedSenderId && normalizedSenderId !== this.localNodeId) {
|
|
10180
10277
|
logger$_.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
|
|
10181
10278
|
channel: this.channelName,
|
|
10182
10279
|
connector_id: this.connectorId,
|
|
@@ -10216,7 +10313,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10216
10313
|
return false;
|
|
10217
10314
|
}
|
|
10218
10315
|
const senderId = this._extractSenderIdFromInboxItem(item);
|
|
10219
|
-
if (senderId && senderId !== this.
|
|
10316
|
+
if (senderId && senderId !== this.localNodeId) {
|
|
10220
10317
|
logger$_.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
|
|
10221
10318
|
channel: this.channelName,
|
|
10222
10319
|
connector_id: this.connectorId,
|
|
@@ -10312,6 +10409,34 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10312
10409
|
});
|
|
10313
10410
|
}
|
|
10314
10411
|
}
|
|
10412
|
+
setTargetNodeId(nodeId) {
|
|
10413
|
+
const normalized = BroadcastChannelConnector.normalizeNodeId(nodeId);
|
|
10414
|
+
if (!normalized) {
|
|
10415
|
+
throw new Error('BroadcastChannelConnector target node id must be a non-empty string');
|
|
10416
|
+
}
|
|
10417
|
+
if (normalized === '*') {
|
|
10418
|
+
this.setWildcardTarget();
|
|
10419
|
+
return;
|
|
10420
|
+
}
|
|
10421
|
+
this.targetNodeId = normalized;
|
|
10422
|
+
logger$_.debug('broadcast_channel_target_updated', {
|
|
10423
|
+
channel: this.channelName,
|
|
10424
|
+
connector_id: this.connectorId,
|
|
10425
|
+
local_node_id: this.localNodeId,
|
|
10426
|
+
target_node_id: this.targetNodeId,
|
|
10427
|
+
target_mode: 'direct',
|
|
10428
|
+
});
|
|
10429
|
+
}
|
|
10430
|
+
setWildcardTarget() {
|
|
10431
|
+
this.targetNodeId = '*';
|
|
10432
|
+
logger$_.debug('broadcast_channel_target_updated', {
|
|
10433
|
+
channel: this.channelName,
|
|
10434
|
+
connector_id: this.connectorId,
|
|
10435
|
+
local_node_id: this.localNodeId,
|
|
10436
|
+
target_node_id: this.targetNodeId,
|
|
10437
|
+
target_mode: 'wildcard',
|
|
10438
|
+
});
|
|
10439
|
+
}
|
|
10315
10440
|
_trimSeenAcks(now) {
|
|
10316
10441
|
while (this.seenAckOrder.length > 0) {
|
|
10317
10442
|
const candidate = this.seenAckOrder[0];
|
|
@@ -10783,6 +10908,20 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
10783
10908
|
waitEvent(event, signal) {
|
|
10784
10909
|
return signal ? event.wait({ signal }) : event.wait();
|
|
10785
10910
|
}
|
|
10911
|
+
_getLocalNodeId() {
|
|
10912
|
+
const normalized = this._normalizeNodeId(this.node.id);
|
|
10913
|
+
if (!normalized) {
|
|
10914
|
+
throw new Error('UpstreamSessionManager requires node with a stable identifier');
|
|
10915
|
+
}
|
|
10916
|
+
return normalized;
|
|
10917
|
+
}
|
|
10918
|
+
_normalizeNodeId(value) {
|
|
10919
|
+
if (typeof value !== 'string') {
|
|
10920
|
+
return null;
|
|
10921
|
+
}
|
|
10922
|
+
const trimmed = value.trim();
|
|
10923
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
10924
|
+
}
|
|
10786
10925
|
async connectCycle() {
|
|
10787
10926
|
if (!this.admissionClient) {
|
|
10788
10927
|
throw new FameConnectError('Admission client is required to attach upstream');
|
|
@@ -10804,6 +10943,8 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
10804
10943
|
await this.onWelcome(welcome.frame);
|
|
10805
10944
|
const connector = await ConnectorFactory.createConnector(grant, {
|
|
10806
10945
|
systemId: welcome.frame.systemId,
|
|
10946
|
+
localNodeId: this._getLocalNodeId(),
|
|
10947
|
+
initialTargetNodeId: '*',
|
|
10807
10948
|
});
|
|
10808
10949
|
await connector.start(this.wrappedHandler);
|
|
10809
10950
|
this.connector = connector;
|
|
@@ -10829,6 +10970,20 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
10829
10970
|
}
|
|
10830
10971
|
const attachInfo = await this.attachClient.attach(this.node, this.outboundOriginType, connector, welcome.frame, this.wrappedHandler, this.getKeys() ?? undefined, callbackGrants);
|
|
10831
10972
|
this.targetSystemId = attachInfo.targetSystemId ?? null;
|
|
10973
|
+
if (this.targetSystemId) {
|
|
10974
|
+
const targetAware = connector;
|
|
10975
|
+
if (typeof targetAware.setTargetNodeId === 'function') {
|
|
10976
|
+
try {
|
|
10977
|
+
targetAware.setTargetNodeId(this.targetSystemId);
|
|
10978
|
+
}
|
|
10979
|
+
catch (error) {
|
|
10980
|
+
logger$Z.warning('broadcast_channel_target_apply_failed', {
|
|
10981
|
+
error: error instanceof Error ? error.message : String(error),
|
|
10982
|
+
target_node_id: this.targetSystemId,
|
|
10983
|
+
});
|
|
10984
|
+
}
|
|
10985
|
+
}
|
|
10986
|
+
}
|
|
10832
10987
|
await this.onAttach(attachInfo, connector);
|
|
10833
10988
|
// Close the admission client immediately after attach completes
|
|
10834
10989
|
// This releases HTTP keep-alive connections (Node.js fetch/undici requires explicit cleanup)
|
|
@@ -28686,8 +28841,16 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28686
28841
|
}
|
|
28687
28842
|
const normalized = this._normalizeConfig(config);
|
|
28688
28843
|
const options = (factoryArgs[0] ?? {});
|
|
28844
|
+
const normalizedLocalNodeFromConfig = this._normalizeNodeId(normalized.localNodeId);
|
|
28845
|
+
const localNodeId = this._normalizeNodeId(options.localNodeId) ?? normalizedLocalNodeFromConfig;
|
|
28846
|
+
if (!localNodeId) {
|
|
28847
|
+
throw new Error('BroadcastChannelConnectorFactory requires a localNodeId from config or create() options');
|
|
28848
|
+
}
|
|
28689
28849
|
const channelName = normalized.channelName ?? DEFAULT_CHANNEL$5;
|
|
28690
28850
|
const inboxCapacity = normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
|
|
28851
|
+
const targetFromOptions = this._normalizeTargetNodeId(options.initialTargetNodeId);
|
|
28852
|
+
const targetFromConfig = this._normalizeTargetNodeId(normalized.initialTargetNodeId);
|
|
28853
|
+
const resolvedTarget = targetFromOptions ?? targetFromConfig ?? '*';
|
|
28691
28854
|
const baseConfig = {
|
|
28692
28855
|
drainTimeout: normalized.drainTimeout,
|
|
28693
28856
|
flowControl: normalized.flowControl,
|
|
@@ -28702,6 +28865,8 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28702
28865
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
28703
28866
|
channelName,
|
|
28704
28867
|
inboxCapacity,
|
|
28868
|
+
localNodeId,
|
|
28869
|
+
initialTargetNodeId: resolvedTarget,
|
|
28705
28870
|
};
|
|
28706
28871
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
28707
28872
|
if (options.authorization) {
|
|
@@ -28725,11 +28890,21 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28725
28890
|
normalized.channelName = channel.trim();
|
|
28726
28891
|
}
|
|
28727
28892
|
const capacity = candidate.inboxCapacity ?? candidate['inbox_capacity'];
|
|
28893
|
+
const initialTargetNodeId = candidate.initialTargetNodeId ?? candidate['initial_target_node_id'];
|
|
28894
|
+
const normalizedTarget = this._normalizeTargetNodeId(initialTargetNodeId);
|
|
28895
|
+
if (normalizedTarget) {
|
|
28896
|
+
normalized.initialTargetNodeId = normalizedTarget;
|
|
28897
|
+
}
|
|
28728
28898
|
if (typeof capacity === 'number' &&
|
|
28729
28899
|
Number.isFinite(capacity) &&
|
|
28730
28900
|
capacity > 0) {
|
|
28731
28901
|
normalized.inboxCapacity = Math.floor(capacity);
|
|
28732
28902
|
}
|
|
28903
|
+
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
28904
|
+
const normalizedLocalNodeId = this._normalizeNodeId(localNodeId);
|
|
28905
|
+
if (normalizedLocalNodeId) {
|
|
28906
|
+
normalized.localNodeId = normalizedLocalNodeId;
|
|
28907
|
+
}
|
|
28733
28908
|
if (typeof candidate.flowControl === 'boolean') {
|
|
28734
28909
|
normalized.flowControl = candidate.flowControl;
|
|
28735
28910
|
}
|
|
@@ -28768,6 +28943,22 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28768
28943
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
|
|
28769
28944
|
return normalized;
|
|
28770
28945
|
}
|
|
28946
|
+
_normalizeNodeId(value) {
|
|
28947
|
+
if (typeof value !== 'string') {
|
|
28948
|
+
return null;
|
|
28949
|
+
}
|
|
28950
|
+
const trimmed = value.trim();
|
|
28951
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
28952
|
+
}
|
|
28953
|
+
_normalizeTargetNodeId(value) {
|
|
28954
|
+
if (value === undefined || value === null) {
|
|
28955
|
+
return undefined;
|
|
28956
|
+
}
|
|
28957
|
+
if (value === '*') {
|
|
28958
|
+
return '*';
|
|
28959
|
+
}
|
|
28960
|
+
return this._normalizeNodeId(value) ?? undefined;
|
|
28961
|
+
}
|
|
28771
28962
|
}
|
|
28772
28963
|
|
|
28773
28964
|
var broadcastChannelConnectorFactory = /*#__PURE__*/Object.freeze({
|
|
@@ -36345,7 +36536,7 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36345
36536
|
node: routingNode,
|
|
36346
36537
|
});
|
|
36347
36538
|
const selection = defaultGrantSelectionPolicy.selectCallbackGrant(selectionContext);
|
|
36348
|
-
connectorConfig = this._grantToConnectorConfig(selection.grant);
|
|
36539
|
+
connectorConfig = this._grantToConnectorConfig(selection.grant, systemId);
|
|
36349
36540
|
}
|
|
36350
36541
|
catch (error) {
|
|
36351
36542
|
logger$a.debug('broadcast_channel_listener_grant_selection_failed', {
|
|
@@ -36354,13 +36545,20 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36354
36545
|
error: error instanceof Error ? error.message : String(error),
|
|
36355
36546
|
});
|
|
36356
36547
|
connectorConfig =
|
|
36357
|
-
this._extractBroadcastConnectorConfig(frame) ??
|
|
36358
|
-
{
|
|
36548
|
+
this._extractBroadcastConnectorConfig(frame, systemId) ??
|
|
36549
|
+
this._buildConnectorConfigForSystem(systemId, {
|
|
36359
36550
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
36360
36551
|
channelName: this._channelName,
|
|
36361
36552
|
inboxCapacity: this._inboxCapacity,
|
|
36362
36553
|
passive: true,
|
|
36363
|
-
};
|
|
36554
|
+
});
|
|
36555
|
+
}
|
|
36556
|
+
if (!connectorConfig) {
|
|
36557
|
+
logger$a.error('broadcast_channel_listener_missing_connector_config', {
|
|
36558
|
+
sender_id: params.senderId,
|
|
36559
|
+
system_id: systemId,
|
|
36560
|
+
});
|
|
36561
|
+
return null;
|
|
36364
36562
|
}
|
|
36365
36563
|
try {
|
|
36366
36564
|
const connector = await routingNode.createOriginConnector({
|
|
@@ -36386,7 +36584,7 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36386
36584
|
return null;
|
|
36387
36585
|
}
|
|
36388
36586
|
}
|
|
36389
|
-
_extractBroadcastConnectorConfig(frame) {
|
|
36587
|
+
_extractBroadcastConnectorConfig(frame, systemId) {
|
|
36390
36588
|
const rawGrants = frame.callbackGrants;
|
|
36391
36589
|
if (!Array.isArray(rawGrants)) {
|
|
36392
36590
|
return null;
|
|
@@ -36397,7 +36595,10 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36397
36595
|
(grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE ||
|
|
36398
36596
|
grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE)) {
|
|
36399
36597
|
try {
|
|
36400
|
-
|
|
36598
|
+
if (grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE) {
|
|
36599
|
+
return this._buildConnectorConfigForSystem(systemId, grant);
|
|
36600
|
+
}
|
|
36601
|
+
return this._buildConnectorConfigForSystem(systemId, broadcastChannelGrantToConnectorConfig(grant));
|
|
36401
36602
|
}
|
|
36402
36603
|
catch (error) {
|
|
36403
36604
|
logger$a.debug('broadcast_channel_listener_grant_normalization_failed', {
|
|
@@ -36408,31 +36609,87 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36408
36609
|
}
|
|
36409
36610
|
return null;
|
|
36410
36611
|
}
|
|
36411
|
-
_grantToConnectorConfig(grant) {
|
|
36412
|
-
if (grant.type
|
|
36413
|
-
|
|
36414
|
-
|
|
36612
|
+
_grantToConnectorConfig(grant, systemId) {
|
|
36613
|
+
if (grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE) {
|
|
36614
|
+
return this._buildConnectorConfigForSystem(systemId, grant);
|
|
36615
|
+
}
|
|
36616
|
+
if (grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE) {
|
|
36617
|
+
return this._buildConnectorConfigForSystem(systemId, broadcastChannelGrantToConnectorConfig(grant));
|
|
36618
|
+
}
|
|
36619
|
+
if ('toConnectorConfig' in grant &&
|
|
36620
|
+
typeof grant.toConnectorConfig ===
|
|
36621
|
+
'function') {
|
|
36622
|
+
const normalized = grant.toConnectorConfig();
|
|
36623
|
+
if (normalized.type !== BROADCAST_CHANNEL_CONNECTOR_TYPE) {
|
|
36624
|
+
throw new Error(`Unsupported grant connector type: ${normalized.type}`);
|
|
36415
36625
|
}
|
|
36416
|
-
|
|
36626
|
+
return this._buildConnectorConfigForSystem(systemId, normalized);
|
|
36417
36627
|
}
|
|
36418
|
-
|
|
36419
|
-
|
|
36628
|
+
throw new Error(`Unsupported grant type: ${grant.type}`);
|
|
36629
|
+
}
|
|
36630
|
+
_buildConnectorConfigForSystem(systemId, baseConfig) {
|
|
36631
|
+
const localNodeId = this._requireLocalNodeId();
|
|
36632
|
+
const targetSystemId = this._normalizeNodeId(systemId);
|
|
36633
|
+
if (!targetSystemId) {
|
|
36634
|
+
throw new Error('BroadcastChannelListener requires a valid system id');
|
|
36635
|
+
}
|
|
36636
|
+
const candidate = baseConfig ?? null;
|
|
36637
|
+
const channelCandidate = candidate && 'channelName' in candidate
|
|
36638
|
+
? candidate.channelName
|
|
36639
|
+
: undefined;
|
|
36640
|
+
const inboxCandidate = candidate && 'inboxCapacity' in candidate
|
|
36641
|
+
? candidate.inboxCapacity
|
|
36642
|
+
: undefined;
|
|
36643
|
+
const initialWindowCandidate = candidate && 'initialWindow' in candidate
|
|
36644
|
+
? candidate.initialWindow
|
|
36645
|
+
: undefined;
|
|
36646
|
+
const passiveCandidate = candidate && 'passive' in candidate
|
|
36647
|
+
? candidate.passive
|
|
36648
|
+
: undefined;
|
|
36649
|
+
const targetCandidate = candidate && 'initialTargetNodeId' in candidate
|
|
36650
|
+
? candidate.initialTargetNodeId
|
|
36651
|
+
: undefined;
|
|
36652
|
+
const channelName = typeof channelCandidate === 'string' && channelCandidate.trim().length > 0
|
|
36653
|
+
? channelCandidate.trim()
|
|
36654
|
+
: this._channelName;
|
|
36655
|
+
const inboxCapacity = typeof inboxCandidate === 'number' &&
|
|
36656
|
+
Number.isFinite(inboxCandidate) &&
|
|
36657
|
+
inboxCandidate > 0
|
|
36658
|
+
? Math.floor(inboxCandidate)
|
|
36659
|
+
: this._inboxCapacity;
|
|
36660
|
+
const initialWindow = typeof initialWindowCandidate === 'number' &&
|
|
36661
|
+
Number.isFinite(initialWindowCandidate) &&
|
|
36662
|
+
initialWindowCandidate > 0
|
|
36663
|
+
? Math.floor(initialWindowCandidate)
|
|
36664
|
+
: undefined;
|
|
36665
|
+
const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
|
|
36666
|
+
return {
|
|
36420
36667
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
36421
|
-
channelName
|
|
36422
|
-
inboxCapacity
|
|
36423
|
-
passive: true,
|
|
36668
|
+
channelName,
|
|
36669
|
+
inboxCapacity,
|
|
36670
|
+
passive: typeof passiveCandidate === 'boolean' ? passiveCandidate : true,
|
|
36671
|
+
initialWindow,
|
|
36672
|
+
localNodeId,
|
|
36673
|
+
initialTargetNodeId,
|
|
36424
36674
|
};
|
|
36425
|
-
|
|
36426
|
-
|
|
36427
|
-
|
|
36675
|
+
}
|
|
36676
|
+
_requireLocalNodeId() {
|
|
36677
|
+
if (!this._routingNode) {
|
|
36678
|
+
throw new Error('BroadcastChannelListener requires routing node context');
|
|
36428
36679
|
}
|
|
36429
|
-
const
|
|
36430
|
-
|
|
36431
|
-
|
|
36432
|
-
|
|
36433
|
-
config.inboxCapacity = Math.floor(inboxCandidate);
|
|
36680
|
+
const normalized = this._normalizeNodeId(this._routingNode.sid) ??
|
|
36681
|
+
this._normalizeNodeId(this._routingNode.id);
|
|
36682
|
+
if (!normalized) {
|
|
36683
|
+
throw new Error('BroadcastChannelListener requires routing node with a stable identifier');
|
|
36434
36684
|
}
|
|
36435
|
-
return
|
|
36685
|
+
return normalized;
|
|
36686
|
+
}
|
|
36687
|
+
_normalizeNodeId(value) {
|
|
36688
|
+
if (typeof value !== 'string') {
|
|
36689
|
+
return null;
|
|
36690
|
+
}
|
|
36691
|
+
const trimmed = value.trim();
|
|
36692
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
36436
36693
|
}
|
|
36437
36694
|
_monitorConnectorLifecycle(senderId, systemId, connector) {
|
|
36438
36695
|
const maybeClosable = connector;
|