@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/node.mjs
CHANGED
|
@@ -5562,12 +5562,12 @@ for (const [name, config] of Object.entries(SQLITE_PROFILES)) {
|
|
|
5562
5562
|
}
|
|
5563
5563
|
|
|
5564
5564
|
// This file is auto-generated during build - do not edit manually
|
|
5565
|
-
// Generated from package.json version: 0.3.5-test.
|
|
5565
|
+
// Generated from package.json version: 0.3.5-test.963
|
|
5566
5566
|
/**
|
|
5567
5567
|
* The package version, injected at build time.
|
|
5568
5568
|
* @internal
|
|
5569
5569
|
*/
|
|
5570
|
-
const VERSION = '0.3.5-test.
|
|
5570
|
+
const VERSION = '0.3.5-test.963';
|
|
5571
5571
|
|
|
5572
5572
|
/**
|
|
5573
5573
|
* Fame errors module - Fame protocol specific error classes
|
|
@@ -11598,6 +11598,26 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11598
11598
|
}
|
|
11599
11599
|
return null;
|
|
11600
11600
|
}
|
|
11601
|
+
static normalizeNodeId(value) {
|
|
11602
|
+
if (typeof value !== 'string') {
|
|
11603
|
+
return null;
|
|
11604
|
+
}
|
|
11605
|
+
const trimmed = value.trim();
|
|
11606
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
11607
|
+
}
|
|
11608
|
+
static normalizeTargetNodeId(value) {
|
|
11609
|
+
if (typeof value !== 'string') {
|
|
11610
|
+
return undefined;
|
|
11611
|
+
}
|
|
11612
|
+
const trimmed = value.trim();
|
|
11613
|
+
if (trimmed.length === 0) {
|
|
11614
|
+
return undefined;
|
|
11615
|
+
}
|
|
11616
|
+
if (trimmed === '*') {
|
|
11617
|
+
return '*';
|
|
11618
|
+
}
|
|
11619
|
+
return trimmed;
|
|
11620
|
+
}
|
|
11601
11621
|
constructor(config, baseConfig = {}) {
|
|
11602
11622
|
ensureBroadcastEnvironment();
|
|
11603
11623
|
super(baseConfig);
|
|
@@ -11620,10 +11640,18 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11620
11640
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
11621
11641
|
this.inboxCapacity = preferredCapacity;
|
|
11622
11642
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
11643
|
+
const normalizedLocalNodeId = BroadcastChannelConnector.normalizeNodeId(config.localNodeId);
|
|
11644
|
+
if (!normalizedLocalNodeId) {
|
|
11645
|
+
throw new Error('BroadcastChannelConnector requires a non-empty localNodeId');
|
|
11646
|
+
}
|
|
11647
|
+
this.localNodeId = normalizedLocalNodeId;
|
|
11648
|
+
this.targetNodeId = BroadcastChannelConnector.normalizeTargetNodeId(config.initialTargetNodeId);
|
|
11623
11649
|
this.channel = new BroadcastChannel(this.channelName);
|
|
11624
11650
|
logger$10.debug('broadcast_channel_connector_created', {
|
|
11625
11651
|
channel: this.channelName,
|
|
11626
11652
|
connector_id: this.connectorId,
|
|
11653
|
+
local_node_id: this.localNodeId,
|
|
11654
|
+
target_node_id: this.targetNodeId ?? null,
|
|
11627
11655
|
inbox_capacity: preferredCapacity,
|
|
11628
11656
|
timestamp: new Date().toISOString(),
|
|
11629
11657
|
});
|
|
@@ -11645,15 +11673,32 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11645
11673
|
? message.constructor?.name ?? typeof message
|
|
11646
11674
|
: typeof message,
|
|
11647
11675
|
has_sender_id: Boolean(message?.senderId),
|
|
11676
|
+
has_sender_node_id: Boolean(message?.senderNodeId),
|
|
11648
11677
|
});
|
|
11649
11678
|
if (!message || typeof message !== 'object') {
|
|
11650
11679
|
return;
|
|
11651
11680
|
}
|
|
11652
11681
|
const busMessage = message;
|
|
11653
|
-
|
|
11682
|
+
const senderNodeId = BroadcastChannelConnector.normalizeNodeId(busMessage.senderNodeId);
|
|
11683
|
+
if (!senderNodeId) {
|
|
11684
|
+
logger$10.debug('broadcast_channel_message_rejected', {
|
|
11685
|
+
channel: this.channelName,
|
|
11686
|
+
connector_id: this.connectorId,
|
|
11687
|
+
reason: 'missing_sender_node_id',
|
|
11688
|
+
});
|
|
11654
11689
|
return;
|
|
11655
11690
|
}
|
|
11656
|
-
if (
|
|
11691
|
+
if (senderNodeId === this.localNodeId) {
|
|
11692
|
+
logger$10.debug('broadcast_channel_message_rejected', {
|
|
11693
|
+
channel: this.channelName,
|
|
11694
|
+
connector_id: this.connectorId,
|
|
11695
|
+
reason: 'self_echo',
|
|
11696
|
+
sender_node_id: senderNodeId,
|
|
11697
|
+
});
|
|
11698
|
+
return;
|
|
11699
|
+
}
|
|
11700
|
+
const incomingTargetNodeId = BroadcastChannelConnector.normalizeTargetNodeId(busMessage.targetNodeId);
|
|
11701
|
+
if (!this._shouldAcceptMessageFromBus(senderNodeId, incomingTargetNodeId)) {
|
|
11657
11702
|
return;
|
|
11658
11703
|
}
|
|
11659
11704
|
const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
|
|
@@ -11667,11 +11712,13 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11667
11712
|
}
|
|
11668
11713
|
logger$10.debug('broadcast_channel_message_received', {
|
|
11669
11714
|
channel: this.channelName,
|
|
11670
|
-
sender_id:
|
|
11715
|
+
sender_id: message?.senderId,
|
|
11716
|
+
sender_node_id: senderNodeId,
|
|
11717
|
+
target_node_id: incomingTargetNodeId ?? null,
|
|
11671
11718
|
connector_id: this.connectorId,
|
|
11672
11719
|
payload_length: payload.byteLength,
|
|
11673
11720
|
});
|
|
11674
|
-
if (this._shouldSkipDuplicateAck(
|
|
11721
|
+
if (this._shouldSkipDuplicateAck(senderNodeId, payload)) {
|
|
11675
11722
|
return;
|
|
11676
11723
|
}
|
|
11677
11724
|
try {
|
|
@@ -11815,12 +11862,17 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11815
11862
|
}
|
|
11816
11863
|
async _transportSendBytes(data) {
|
|
11817
11864
|
ensureBroadcastEnvironment();
|
|
11865
|
+
const targetNodeId = this.targetNodeId ?? '*';
|
|
11818
11866
|
logger$10.debug('broadcast_channel_message_sending', {
|
|
11819
11867
|
channel: this.channelName,
|
|
11820
11868
|
sender_id: this.connectorId,
|
|
11869
|
+
sender_node_id: this.localNodeId,
|
|
11870
|
+
target_node_id: targetNodeId,
|
|
11821
11871
|
});
|
|
11822
11872
|
this.channel.postMessage({
|
|
11823
11873
|
senderId: this.connectorId,
|
|
11874
|
+
senderNodeId: this.localNodeId,
|
|
11875
|
+
targetNodeId,
|
|
11824
11876
|
payload: data,
|
|
11825
11877
|
});
|
|
11826
11878
|
}
|
|
@@ -11883,6 +11935,51 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11883
11935
|
}
|
|
11884
11936
|
return rawOrEnvelope;
|
|
11885
11937
|
}
|
|
11938
|
+
_isWildcardTarget() {
|
|
11939
|
+
return this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined';
|
|
11940
|
+
}
|
|
11941
|
+
_shouldAcceptMessageFromBus(senderNodeId, targetNodeId) {
|
|
11942
|
+
if (this._isWildcardTarget()) {
|
|
11943
|
+
if (targetNodeId && targetNodeId !== '*') {
|
|
11944
|
+
logger$10.debug('broadcast_channel_message_rejected', {
|
|
11945
|
+
channel: this.channelName,
|
|
11946
|
+
connector_id: this.connectorId,
|
|
11947
|
+
reason: 'wildcard_target_mismatch',
|
|
11948
|
+
sender_node_id: senderNodeId,
|
|
11949
|
+
target_node_id: targetNodeId,
|
|
11950
|
+
local_node_id: this.localNodeId,
|
|
11951
|
+
});
|
|
11952
|
+
return false;
|
|
11953
|
+
}
|
|
11954
|
+
return true;
|
|
11955
|
+
}
|
|
11956
|
+
const expectedSender = this.targetNodeId;
|
|
11957
|
+
if (expectedSender && expectedSender !== '*' && senderNodeId !== expectedSender) {
|
|
11958
|
+
logger$10.debug('broadcast_channel_message_rejected', {
|
|
11959
|
+
channel: this.channelName,
|
|
11960
|
+
connector_id: this.connectorId,
|
|
11961
|
+
reason: 'unexpected_sender',
|
|
11962
|
+
expected_sender_node_id: expectedSender,
|
|
11963
|
+
sender_node_id: senderNodeId,
|
|
11964
|
+
local_node_id: this.localNodeId,
|
|
11965
|
+
});
|
|
11966
|
+
return false;
|
|
11967
|
+
}
|
|
11968
|
+
if (targetNodeId &&
|
|
11969
|
+
targetNodeId !== '*' &&
|
|
11970
|
+
targetNodeId !== this.localNodeId) {
|
|
11971
|
+
logger$10.debug('broadcast_channel_message_rejected', {
|
|
11972
|
+
channel: this.channelName,
|
|
11973
|
+
connector_id: this.connectorId,
|
|
11974
|
+
reason: 'unexpected_target',
|
|
11975
|
+
sender_node_id: senderNodeId,
|
|
11976
|
+
target_node_id: targetNodeId,
|
|
11977
|
+
local_node_id: this.localNodeId,
|
|
11978
|
+
});
|
|
11979
|
+
return false;
|
|
11980
|
+
}
|
|
11981
|
+
return true;
|
|
11982
|
+
}
|
|
11886
11983
|
_describeInboxItem(item) {
|
|
11887
11984
|
if (item instanceof Uint8Array) {
|
|
11888
11985
|
return 'bytes';
|
|
@@ -11913,7 +12010,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11913
12010
|
const normalizedSenderId = typeof senderId === 'string' && senderId.length > 0
|
|
11914
12011
|
? senderId
|
|
11915
12012
|
: undefined;
|
|
11916
|
-
if (normalizedSenderId && normalizedSenderId !== this.
|
|
12013
|
+
if (normalizedSenderId && normalizedSenderId !== this.localNodeId) {
|
|
11917
12014
|
logger$10.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
|
|
11918
12015
|
channel: this.channelName,
|
|
11919
12016
|
connector_id: this.connectorId,
|
|
@@ -11953,7 +12050,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
11953
12050
|
return false;
|
|
11954
12051
|
}
|
|
11955
12052
|
const senderId = this._extractSenderIdFromInboxItem(item);
|
|
11956
|
-
if (senderId && senderId !== this.
|
|
12053
|
+
if (senderId && senderId !== this.localNodeId) {
|
|
11957
12054
|
logger$10.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
|
|
11958
12055
|
channel: this.channelName,
|
|
11959
12056
|
connector_id: this.connectorId,
|
|
@@ -12049,6 +12146,34 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
12049
12146
|
});
|
|
12050
12147
|
}
|
|
12051
12148
|
}
|
|
12149
|
+
setTargetNodeId(nodeId) {
|
|
12150
|
+
const normalized = BroadcastChannelConnector.normalizeNodeId(nodeId);
|
|
12151
|
+
if (!normalized) {
|
|
12152
|
+
throw new Error('BroadcastChannelConnector target node id must be a non-empty string');
|
|
12153
|
+
}
|
|
12154
|
+
if (normalized === '*') {
|
|
12155
|
+
this.setWildcardTarget();
|
|
12156
|
+
return;
|
|
12157
|
+
}
|
|
12158
|
+
this.targetNodeId = normalized;
|
|
12159
|
+
logger$10.debug('broadcast_channel_target_updated', {
|
|
12160
|
+
channel: this.channelName,
|
|
12161
|
+
connector_id: this.connectorId,
|
|
12162
|
+
local_node_id: this.localNodeId,
|
|
12163
|
+
target_node_id: this.targetNodeId,
|
|
12164
|
+
target_mode: 'direct',
|
|
12165
|
+
});
|
|
12166
|
+
}
|
|
12167
|
+
setWildcardTarget() {
|
|
12168
|
+
this.targetNodeId = '*';
|
|
12169
|
+
logger$10.debug('broadcast_channel_target_updated', {
|
|
12170
|
+
channel: this.channelName,
|
|
12171
|
+
connector_id: this.connectorId,
|
|
12172
|
+
local_node_id: this.localNodeId,
|
|
12173
|
+
target_node_id: this.targetNodeId,
|
|
12174
|
+
target_mode: 'wildcard',
|
|
12175
|
+
});
|
|
12176
|
+
}
|
|
12052
12177
|
_trimSeenAcks(now) {
|
|
12053
12178
|
while (this.seenAckOrder.length > 0) {
|
|
12054
12179
|
const candidate = this.seenAckOrder[0];
|
|
@@ -12475,6 +12600,20 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12475
12600
|
waitEvent(event, signal) {
|
|
12476
12601
|
return signal ? event.wait({ signal }) : event.wait();
|
|
12477
12602
|
}
|
|
12603
|
+
_getLocalNodeId() {
|
|
12604
|
+
const normalized = this._normalizeNodeId(this.node.id);
|
|
12605
|
+
if (!normalized) {
|
|
12606
|
+
throw new Error('UpstreamSessionManager requires node with a stable identifier');
|
|
12607
|
+
}
|
|
12608
|
+
return normalized;
|
|
12609
|
+
}
|
|
12610
|
+
_normalizeNodeId(value) {
|
|
12611
|
+
if (typeof value !== 'string') {
|
|
12612
|
+
return null;
|
|
12613
|
+
}
|
|
12614
|
+
const trimmed = value.trim();
|
|
12615
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
12616
|
+
}
|
|
12478
12617
|
async connectCycle() {
|
|
12479
12618
|
if (!this.admissionClient) {
|
|
12480
12619
|
throw new FameConnectError('Admission client is required to attach upstream');
|
|
@@ -12496,6 +12635,8 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12496
12635
|
await this.onWelcome(welcome.frame);
|
|
12497
12636
|
const connector = await ConnectorFactory.createConnector(grant, {
|
|
12498
12637
|
systemId: welcome.frame.systemId,
|
|
12638
|
+
localNodeId: this._getLocalNodeId(),
|
|
12639
|
+
initialTargetNodeId: '*',
|
|
12499
12640
|
});
|
|
12500
12641
|
await connector.start(this.wrappedHandler);
|
|
12501
12642
|
this.connector = connector;
|
|
@@ -12521,6 +12662,20 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
12521
12662
|
}
|
|
12522
12663
|
const attachInfo = await this.attachClient.attach(this.node, this.outboundOriginType, connector, welcome.frame, this.wrappedHandler, this.getKeys() ?? undefined, callbackGrants);
|
|
12523
12664
|
this.targetSystemId = attachInfo.targetSystemId ?? null;
|
|
12665
|
+
if (this.targetSystemId) {
|
|
12666
|
+
const targetAware = connector;
|
|
12667
|
+
if (typeof targetAware.setTargetNodeId === 'function') {
|
|
12668
|
+
try {
|
|
12669
|
+
targetAware.setTargetNodeId(this.targetSystemId);
|
|
12670
|
+
}
|
|
12671
|
+
catch (error) {
|
|
12672
|
+
logger$$.warning('broadcast_channel_target_apply_failed', {
|
|
12673
|
+
error: error instanceof Error ? error.message : String(error),
|
|
12674
|
+
target_node_id: this.targetSystemId,
|
|
12675
|
+
});
|
|
12676
|
+
}
|
|
12677
|
+
}
|
|
12678
|
+
}
|
|
12524
12679
|
await this.onAttach(attachInfo, connector);
|
|
12525
12680
|
// Close the admission client immediately after attach completes
|
|
12526
12681
|
// This releases HTTP keep-alive connections (Node.js fetch/undici requires explicit cleanup)
|
|
@@ -30619,8 +30774,16 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
30619
30774
|
}
|
|
30620
30775
|
const normalized = this._normalizeConfig(config);
|
|
30621
30776
|
const options = (factoryArgs[0] ?? {});
|
|
30777
|
+
const normalizedLocalNodeFromConfig = this._normalizeNodeId(normalized.localNodeId);
|
|
30778
|
+
const localNodeId = this._normalizeNodeId(options.localNodeId) ?? normalizedLocalNodeFromConfig;
|
|
30779
|
+
if (!localNodeId) {
|
|
30780
|
+
throw new Error('BroadcastChannelConnectorFactory requires a localNodeId from config or create() options');
|
|
30781
|
+
}
|
|
30622
30782
|
const channelName = normalized.channelName ?? DEFAULT_CHANNEL$2;
|
|
30623
30783
|
const inboxCapacity = normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$2;
|
|
30784
|
+
const targetFromOptions = this._normalizeTargetNodeId(options.initialTargetNodeId);
|
|
30785
|
+
const targetFromConfig = this._normalizeTargetNodeId(normalized.initialTargetNodeId);
|
|
30786
|
+
const resolvedTarget = targetFromOptions ?? targetFromConfig ?? '*';
|
|
30624
30787
|
const baseConfig = {
|
|
30625
30788
|
drainTimeout: normalized.drainTimeout,
|
|
30626
30789
|
flowControl: normalized.flowControl,
|
|
@@ -30635,6 +30798,8 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
30635
30798
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE$1,
|
|
30636
30799
|
channelName,
|
|
30637
30800
|
inboxCapacity,
|
|
30801
|
+
localNodeId,
|
|
30802
|
+
initialTargetNodeId: resolvedTarget,
|
|
30638
30803
|
};
|
|
30639
30804
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
30640
30805
|
if (options.authorization) {
|
|
@@ -30658,11 +30823,21 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
30658
30823
|
normalized.channelName = channel.trim();
|
|
30659
30824
|
}
|
|
30660
30825
|
const capacity = candidate.inboxCapacity ?? candidate['inbox_capacity'];
|
|
30826
|
+
const initialTargetNodeId = candidate.initialTargetNodeId ?? candidate['initial_target_node_id'];
|
|
30827
|
+
const normalizedTarget = this._normalizeTargetNodeId(initialTargetNodeId);
|
|
30828
|
+
if (normalizedTarget) {
|
|
30829
|
+
normalized.initialTargetNodeId = normalizedTarget;
|
|
30830
|
+
}
|
|
30661
30831
|
if (typeof capacity === 'number' &&
|
|
30662
30832
|
Number.isFinite(capacity) &&
|
|
30663
30833
|
capacity > 0) {
|
|
30664
30834
|
normalized.inboxCapacity = Math.floor(capacity);
|
|
30665
30835
|
}
|
|
30836
|
+
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
30837
|
+
const normalizedLocalNodeId = this._normalizeNodeId(localNodeId);
|
|
30838
|
+
if (normalizedLocalNodeId) {
|
|
30839
|
+
normalized.localNodeId = normalizedLocalNodeId;
|
|
30840
|
+
}
|
|
30666
30841
|
if (typeof candidate.flowControl === 'boolean') {
|
|
30667
30842
|
normalized.flowControl = candidate.flowControl;
|
|
30668
30843
|
}
|
|
@@ -30701,6 +30876,22 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
30701
30876
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$2;
|
|
30702
30877
|
return normalized;
|
|
30703
30878
|
}
|
|
30879
|
+
_normalizeNodeId(value) {
|
|
30880
|
+
if (typeof value !== 'string') {
|
|
30881
|
+
return null;
|
|
30882
|
+
}
|
|
30883
|
+
const trimmed = value.trim();
|
|
30884
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
30885
|
+
}
|
|
30886
|
+
_normalizeTargetNodeId(value) {
|
|
30887
|
+
if (value === undefined || value === null) {
|
|
30888
|
+
return undefined;
|
|
30889
|
+
}
|
|
30890
|
+
if (value === '*') {
|
|
30891
|
+
return '*';
|
|
30892
|
+
}
|
|
30893
|
+
return this._normalizeNodeId(value) ?? undefined;
|
|
30894
|
+
}
|
|
30704
30895
|
}
|
|
30705
30896
|
|
|
30706
30897
|
var broadcastChannelConnectorFactory = /*#__PURE__*/Object.freeze({
|
|
@@ -32858,7 +33049,7 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
32858
33049
|
node: routingNode,
|
|
32859
33050
|
});
|
|
32860
33051
|
const selection = defaultGrantSelectionPolicy.selectCallbackGrant(selectionContext);
|
|
32861
|
-
connectorConfig = this._grantToConnectorConfig(selection.grant);
|
|
33052
|
+
connectorConfig = this._grantToConnectorConfig(selection.grant, systemId);
|
|
32862
33053
|
}
|
|
32863
33054
|
catch (error) {
|
|
32864
33055
|
logger$n.debug('broadcast_channel_listener_grant_selection_failed', {
|
|
@@ -32867,13 +33058,20 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
32867
33058
|
error: error instanceof Error ? error.message : String(error),
|
|
32868
33059
|
});
|
|
32869
33060
|
connectorConfig =
|
|
32870
|
-
this._extractBroadcastConnectorConfig(frame) ??
|
|
32871
|
-
{
|
|
33061
|
+
this._extractBroadcastConnectorConfig(frame, systemId) ??
|
|
33062
|
+
this._buildConnectorConfigForSystem(systemId, {
|
|
32872
33063
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE$1,
|
|
32873
33064
|
channelName: this._channelName,
|
|
32874
33065
|
inboxCapacity: this._inboxCapacity,
|
|
32875
33066
|
passive: true,
|
|
32876
|
-
};
|
|
33067
|
+
});
|
|
33068
|
+
}
|
|
33069
|
+
if (!connectorConfig) {
|
|
33070
|
+
logger$n.error('broadcast_channel_listener_missing_connector_config', {
|
|
33071
|
+
sender_id: params.senderId,
|
|
33072
|
+
system_id: systemId,
|
|
33073
|
+
});
|
|
33074
|
+
return null;
|
|
32877
33075
|
}
|
|
32878
33076
|
try {
|
|
32879
33077
|
const connector = await routingNode.createOriginConnector({
|
|
@@ -32899,7 +33097,7 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
32899
33097
|
return null;
|
|
32900
33098
|
}
|
|
32901
33099
|
}
|
|
32902
|
-
_extractBroadcastConnectorConfig(frame) {
|
|
33100
|
+
_extractBroadcastConnectorConfig(frame, systemId) {
|
|
32903
33101
|
const rawGrants = frame.callbackGrants;
|
|
32904
33102
|
if (!Array.isArray(rawGrants)) {
|
|
32905
33103
|
return null;
|
|
@@ -32910,7 +33108,10 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
32910
33108
|
(grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE ||
|
|
32911
33109
|
grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE$1)) {
|
|
32912
33110
|
try {
|
|
32913
|
-
|
|
33111
|
+
if (grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE$1) {
|
|
33112
|
+
return this._buildConnectorConfigForSystem(systemId, grant);
|
|
33113
|
+
}
|
|
33114
|
+
return this._buildConnectorConfigForSystem(systemId, broadcastChannelGrantToConnectorConfig(grant));
|
|
32914
33115
|
}
|
|
32915
33116
|
catch (error) {
|
|
32916
33117
|
logger$n.debug('broadcast_channel_listener_grant_normalization_failed', {
|
|
@@ -32921,31 +33122,87 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
32921
33122
|
}
|
|
32922
33123
|
return null;
|
|
32923
33124
|
}
|
|
32924
|
-
_grantToConnectorConfig(grant) {
|
|
32925
|
-
if (grant.type
|
|
32926
|
-
|
|
32927
|
-
|
|
33125
|
+
_grantToConnectorConfig(grant, systemId) {
|
|
33126
|
+
if (grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE$1) {
|
|
33127
|
+
return this._buildConnectorConfigForSystem(systemId, grant);
|
|
33128
|
+
}
|
|
33129
|
+
if (grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE) {
|
|
33130
|
+
return this._buildConnectorConfigForSystem(systemId, broadcastChannelGrantToConnectorConfig(grant));
|
|
33131
|
+
}
|
|
33132
|
+
if ('toConnectorConfig' in grant &&
|
|
33133
|
+
typeof grant.toConnectorConfig ===
|
|
33134
|
+
'function') {
|
|
33135
|
+
const normalized = grant.toConnectorConfig();
|
|
33136
|
+
if (normalized.type !== BROADCAST_CHANNEL_CONNECTOR_TYPE$1) {
|
|
33137
|
+
throw new Error(`Unsupported grant connector type: ${normalized.type}`);
|
|
32928
33138
|
}
|
|
32929
|
-
|
|
33139
|
+
return this._buildConnectorConfigForSystem(systemId, normalized);
|
|
32930
33140
|
}
|
|
32931
|
-
|
|
32932
|
-
|
|
33141
|
+
throw new Error(`Unsupported grant type: ${grant.type}`);
|
|
33142
|
+
}
|
|
33143
|
+
_buildConnectorConfigForSystem(systemId, baseConfig) {
|
|
33144
|
+
const localNodeId = this._requireLocalNodeId();
|
|
33145
|
+
const targetSystemId = this._normalizeNodeId(systemId);
|
|
33146
|
+
if (!targetSystemId) {
|
|
33147
|
+
throw new Error('BroadcastChannelListener requires a valid system id');
|
|
33148
|
+
}
|
|
33149
|
+
const candidate = baseConfig ?? null;
|
|
33150
|
+
const channelCandidate = candidate && 'channelName' in candidate
|
|
33151
|
+
? candidate.channelName
|
|
33152
|
+
: undefined;
|
|
33153
|
+
const inboxCandidate = candidate && 'inboxCapacity' in candidate
|
|
33154
|
+
? candidate.inboxCapacity
|
|
33155
|
+
: undefined;
|
|
33156
|
+
const initialWindowCandidate = candidate && 'initialWindow' in candidate
|
|
33157
|
+
? candidate.initialWindow
|
|
33158
|
+
: undefined;
|
|
33159
|
+
const passiveCandidate = candidate && 'passive' in candidate
|
|
33160
|
+
? candidate.passive
|
|
33161
|
+
: undefined;
|
|
33162
|
+
const targetCandidate = candidate && 'initialTargetNodeId' in candidate
|
|
33163
|
+
? candidate.initialTargetNodeId
|
|
33164
|
+
: undefined;
|
|
33165
|
+
const channelName = typeof channelCandidate === 'string' && channelCandidate.trim().length > 0
|
|
33166
|
+
? channelCandidate.trim()
|
|
33167
|
+
: this._channelName;
|
|
33168
|
+
const inboxCapacity = typeof inboxCandidate === 'number' &&
|
|
33169
|
+
Number.isFinite(inboxCandidate) &&
|
|
33170
|
+
inboxCandidate > 0
|
|
33171
|
+
? Math.floor(inboxCandidate)
|
|
33172
|
+
: this._inboxCapacity;
|
|
33173
|
+
const initialWindow = typeof initialWindowCandidate === 'number' &&
|
|
33174
|
+
Number.isFinite(initialWindowCandidate) &&
|
|
33175
|
+
initialWindowCandidate > 0
|
|
33176
|
+
? Math.floor(initialWindowCandidate)
|
|
33177
|
+
: undefined;
|
|
33178
|
+
const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
|
|
33179
|
+
return {
|
|
32933
33180
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE$1,
|
|
32934
|
-
channelName
|
|
32935
|
-
inboxCapacity
|
|
32936
|
-
passive: true,
|
|
33181
|
+
channelName,
|
|
33182
|
+
inboxCapacity,
|
|
33183
|
+
passive: typeof passiveCandidate === 'boolean' ? passiveCandidate : true,
|
|
33184
|
+
initialWindow,
|
|
33185
|
+
localNodeId,
|
|
33186
|
+
initialTargetNodeId,
|
|
32937
33187
|
};
|
|
32938
|
-
|
|
32939
|
-
|
|
32940
|
-
|
|
33188
|
+
}
|
|
33189
|
+
_requireLocalNodeId() {
|
|
33190
|
+
if (!this._routingNode) {
|
|
33191
|
+
throw new Error('BroadcastChannelListener requires routing node context');
|
|
32941
33192
|
}
|
|
32942
|
-
const
|
|
32943
|
-
|
|
32944
|
-
|
|
32945
|
-
|
|
32946
|
-
config.inboxCapacity = Math.floor(inboxCandidate);
|
|
33193
|
+
const normalized = this._normalizeNodeId(this._routingNode.sid) ??
|
|
33194
|
+
this._normalizeNodeId(this._routingNode.id);
|
|
33195
|
+
if (!normalized) {
|
|
33196
|
+
throw new Error('BroadcastChannelListener requires routing node with a stable identifier');
|
|
32947
33197
|
}
|
|
32948
|
-
return
|
|
33198
|
+
return normalized;
|
|
33199
|
+
}
|
|
33200
|
+
_normalizeNodeId(value) {
|
|
33201
|
+
if (typeof value !== 'string') {
|
|
33202
|
+
return null;
|
|
33203
|
+
}
|
|
33204
|
+
const trimmed = value.trim();
|
|
33205
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
32949
33206
|
}
|
|
32950
33207
|
_monitorConnectorLifecycle(senderId, systemId, connector) {
|
|
32951
33208
|
const maybeClosable = connector;
|
|
@@ -7,9 +7,13 @@ 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
|
+
initialTargetNodeId?: string | '*';
|
|
10
12
|
}
|
|
11
13
|
export interface CreateBroadcastChannelConnectorOptions {
|
|
12
14
|
authorization?: AuthorizationContext;
|
|
15
|
+
localNodeId?: string;
|
|
16
|
+
initialTargetNodeId?: string | '*';
|
|
13
17
|
}
|
|
14
18
|
export declare const FACTORY_META: {
|
|
15
19
|
readonly base: "ConnectorFactory";
|
|
@@ -23,5 +27,7 @@ export declare class BroadcastChannelConnectorFactory extends ConnectorFactory<B
|
|
|
23
27
|
grantFromConfig(config: BroadcastChannelConnectorFactoryConfig | Record<string, unknown>): ConnectionGrant;
|
|
24
28
|
create(config?: BroadcastChannelConnectorFactoryConfig | Record<string, unknown> | null, ...factoryArgs: unknown[]): Promise<BroadcastChannelConnector>;
|
|
25
29
|
private _normalizeConfig;
|
|
30
|
+
private _normalizeNodeId;
|
|
31
|
+
private _normalizeTargetNodeId;
|
|
26
32
|
}
|
|
27
33
|
export default BroadcastChannelConnectorFactory;
|
|
@@ -8,6 +8,8 @@ export interface BroadcastChannelConnectorConfig extends ConnectorConfig {
|
|
|
8
8
|
inboxCapacity?: number;
|
|
9
9
|
initialWindow?: number;
|
|
10
10
|
passive?: boolean;
|
|
11
|
+
localNodeId: string;
|
|
12
|
+
initialTargetNodeId?: string | '*';
|
|
11
13
|
}
|
|
12
14
|
type BroadcastChannelInboxItem = Uint8Array | FameEnvelope | FameChannelMessage;
|
|
13
15
|
export declare class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
@@ -16,6 +18,8 @@ export declare class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
16
18
|
private readonly inboxCapacity;
|
|
17
19
|
private listenerRegistered;
|
|
18
20
|
private readonly connectorId;
|
|
21
|
+
private readonly localNodeId;
|
|
22
|
+
private targetNodeId?;
|
|
19
23
|
private readonly onMsg;
|
|
20
24
|
private readonly channel;
|
|
21
25
|
private readonly seenAckKeys;
|
|
@@ -27,12 +31,16 @@ export declare class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
27
31
|
private visibilityChangeHandler?;
|
|
28
32
|
private static generateConnectorId;
|
|
29
33
|
private static coercePayload;
|
|
34
|
+
private static normalizeNodeId;
|
|
35
|
+
private static normalizeTargetNodeId;
|
|
30
36
|
constructor(config: BroadcastChannelConnectorConfig, baseConfig?: BaseAsyncConnectorConfig);
|
|
31
37
|
pushToReceive(rawOrEnvelope: Uint8Array | FameEnvelope | FameChannelMessage): Promise<void>;
|
|
32
38
|
protected _transportSendBytes(data: Uint8Array): Promise<void>;
|
|
33
39
|
protected _transportReceive(): Promise<BroadcastChannelInboxItem>;
|
|
34
40
|
protected _transportClose(code: number, reason: string): Promise<void>;
|
|
35
41
|
private _normalizeInboxItem;
|
|
42
|
+
private _isWildcardTarget;
|
|
43
|
+
private _shouldAcceptMessageFromBus;
|
|
36
44
|
private _describeInboxItem;
|
|
37
45
|
private logInboxSnapshot;
|
|
38
46
|
private _shouldSkipDuplicateAck;
|
|
@@ -44,6 +52,8 @@ export declare class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
44
52
|
* Override start() to check initial visibility state
|
|
45
53
|
*/
|
|
46
54
|
start(inboundHandler: FameEnvelopeHandler): Promise<void>;
|
|
55
|
+
setTargetNodeId(nodeId: string): void;
|
|
56
|
+
setWildcardTarget(): void;
|
|
47
57
|
private _trimSeenAcks;
|
|
48
58
|
private _extractAckDedupKey;
|
|
49
59
|
}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { BaseAsyncConnector, type BaseAsyncConnectorConfig } from './base-async-connector.js';
|
|
2
|
-
import type { ConnectorConfig } from './connector-config.js';
|
|
3
2
|
import type { FameEnvelope, FameChannelMessage } from '@naylence/core';
|
|
3
|
+
import type { BroadcastChannelConnectorConfig } from './broadcast-channel-connector.browser.js';
|
|
4
4
|
export declare const BROADCAST_CHANNEL_CONNECTOR_TYPE: "broadcast-channel-connector";
|
|
5
|
-
export interface BroadcastChannelConnectorConfig extends ConnectorConfig {
|
|
6
|
-
type: typeof BROADCAST_CHANNEL_CONNECTOR_TYPE;
|
|
7
|
-
channelName?: string;
|
|
8
|
-
inboxCapacity?: number;
|
|
9
|
-
}
|
|
10
5
|
export declare class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
11
6
|
constructor(config: BroadcastChannelConnectorConfig, baseConfig?: BaseAsyncConnectorConfig);
|
|
12
7
|
pushToReceive(_rawOrEnvelope: Uint8Array | FameEnvelope | FameChannelMessage): Promise<void>;
|
|
@@ -33,6 +33,9 @@ export declare class BroadcastChannelListener extends TransportListener {
|
|
|
33
33
|
private _createConnectorForAttach;
|
|
34
34
|
private _extractBroadcastConnectorConfig;
|
|
35
35
|
private _grantToConnectorConfig;
|
|
36
|
+
private _buildConnectorConfigForSystem;
|
|
37
|
+
private _requireLocalNodeId;
|
|
38
|
+
private _normalizeNodeId;
|
|
36
39
|
private _monitorConnectorLifecycle;
|
|
37
40
|
private _deliverEnvelope;
|
|
38
41
|
private _buildChannelMessage;
|
|
@@ -17,7 +17,7 @@ export type BroadcastChannelConnectionGrantLike = ConnectionGrantLike & {
|
|
|
17
17
|
initialWindow?: unknown;
|
|
18
18
|
initial_window?: unknown;
|
|
19
19
|
};
|
|
20
|
-
export type BroadcastChannelConnectorConfigLike = ConnectorConfig & BroadcastChannelConnectorConfig
|
|
20
|
+
export type BroadcastChannelConnectorConfigLike = ConnectorConfig & Partial<BroadcastChannelConnectorConfig>;
|
|
21
21
|
export declare function isBroadcastChannelConnectionGrant(candidate: unknown): candidate is BroadcastChannelConnectionGrant;
|
|
22
22
|
export declare function normalizeBroadcastChannelConnectionGrant(candidate: BroadcastChannelConnectionGrantLike): BroadcastChannelConnectionGrant;
|
|
23
23
|
export declare function broadcastChannelGrantToConnectorConfig(grant: BroadcastChannelConnectionGrantLike): BroadcastChannelConnectorConfigLike;
|
|
@@ -82,6 +82,8 @@ export declare class UpstreamSessionManager extends TaskSpawner implements Sessi
|
|
|
82
82
|
private sleepWithStop;
|
|
83
83
|
private getNodeAttachGrant;
|
|
84
84
|
private waitEvent;
|
|
85
|
+
private _getLocalNodeId;
|
|
86
|
+
private _normalizeNodeId;
|
|
85
87
|
private connectCycle;
|
|
86
88
|
private shouldAdvertiseBroadcastGrant;
|
|
87
89
|
private createBroadcastCallbackGrant;
|
package/dist/types/version.d.ts
CHANGED