@naylence/runtime 0.3.5-test.960 → 0.3.5-test.962

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.
@@ -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.960
16
+ // Generated from package.json version: 0.3.5-test.962
17
17
  /**
18
18
  * The package version, injected at build time.
19
19
  * @internal
20
20
  */
21
- const VERSION = '0.3.5-test.960';
21
+ const VERSION = '0.3.5-test.962';
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
- if (typeof busMessage.senderId !== 'string' || busMessage.senderId.length === 0) {
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 (busMessage.senderId === this.connectorId) {
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: busMessage.senderId,
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(busMessage.senderId, payload)) {
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,6 +10273,16 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10176
10273
  const normalizedSenderId = typeof senderId === 'string' && senderId.length > 0
10177
10274
  ? senderId
10178
10275
  : undefined;
10276
+ if (normalizedSenderId && normalizedSenderId !== this.localNodeId) {
10277
+ logger$_.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
10278
+ channel: this.channelName,
10279
+ connector_id: this.connectorId,
10280
+ sender_id: normalizedSenderId,
10281
+ dedup_key: dedupKey,
10282
+ source: 'listener',
10283
+ });
10284
+ return false;
10285
+ }
10179
10286
  logger$_.debug('broadcast_channel_duplicate_ack_check', {
10180
10287
  channel: this.channelName,
10181
10288
  connector_id: this.connectorId,
@@ -10206,6 +10313,16 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10206
10313
  return false;
10207
10314
  }
10208
10315
  const senderId = this._extractSenderIdFromInboxItem(item);
10316
+ if (senderId && senderId !== this.localNodeId) {
10317
+ logger$_.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
10318
+ channel: this.channelName,
10319
+ connector_id: this.connectorId,
10320
+ sender_id: senderId,
10321
+ dedup_key: dedupKey,
10322
+ source: 'inbox_item',
10323
+ });
10324
+ return false;
10325
+ }
10209
10326
  logger$_.debug('broadcast_channel_duplicate_ack_check', {
10210
10327
  channel: this.channelName,
10211
10328
  connector_id: this.connectorId,
@@ -10292,6 +10409,34 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10292
10409
  });
10293
10410
  }
10294
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
+ }
10295
10440
  _trimSeenAcks(now) {
10296
10441
  while (this.seenAckOrder.length > 0) {
10297
10442
  const candidate = this.seenAckOrder[0];
@@ -28666,8 +28811,13 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28666
28811
  }
28667
28812
  const normalized = this._normalizeConfig(config);
28668
28813
  const options = (factoryArgs[0] ?? {});
28814
+ const localNodeId = this._normalizeNodeId(options.localNodeId);
28815
+ if (!localNodeId) {
28816
+ throw new Error('BroadcastChannelConnectorFactory requires a localNodeId in create() options');
28817
+ }
28669
28818
  const channelName = normalized.channelName ?? DEFAULT_CHANNEL$5;
28670
28819
  const inboxCapacity = normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
28820
+ const resolvedTarget = this._normalizeTargetNodeId(options.initialTargetNodeId ?? normalized.initialTargetNodeId);
28671
28821
  const baseConfig = {
28672
28822
  drainTimeout: normalized.drainTimeout,
28673
28823
  flowControl: normalized.flowControl,
@@ -28682,6 +28832,8 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28682
28832
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
28683
28833
  channelName,
28684
28834
  inboxCapacity,
28835
+ localNodeId,
28836
+ initialTargetNodeId: resolvedTarget,
28685
28837
  };
28686
28838
  const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
28687
28839
  if (options.authorization) {
@@ -28705,6 +28857,13 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28705
28857
  normalized.channelName = channel.trim();
28706
28858
  }
28707
28859
  const capacity = candidate.inboxCapacity ?? candidate['inbox_capacity'];
28860
+ const initialTargetNodeId = candidate.initialTargetNodeId ?? candidate['initial_target_node_id'];
28861
+ if (typeof initialTargetNodeId === 'string' && initialTargetNodeId.trim().length > 0) {
28862
+ normalized.initialTargetNodeId = initialTargetNodeId.trim();
28863
+ }
28864
+ else if (initialTargetNodeId === '*') {
28865
+ normalized.initialTargetNodeId = '*';
28866
+ }
28708
28867
  if (typeof capacity === 'number' &&
28709
28868
  Number.isFinite(capacity) &&
28710
28869
  capacity > 0) {
@@ -28748,6 +28907,19 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28748
28907
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
28749
28908
  return normalized;
28750
28909
  }
28910
+ _normalizeNodeId(value) {
28911
+ if (typeof value !== 'string') {
28912
+ return null;
28913
+ }
28914
+ const trimmed = value.trim();
28915
+ return trimmed.length > 0 ? trimmed : null;
28916
+ }
28917
+ _normalizeTargetNodeId(value) {
28918
+ if (value === '*') {
28919
+ return '*';
28920
+ }
28921
+ return this._normalizeNodeId(value) ?? '*';
28922
+ }
28751
28923
  }
28752
28924
 
28753
28925
  var broadcastChannelConnectorFactory = /*#__PURE__*/Object.freeze({
@@ -36325,7 +36497,7 @@ class BroadcastChannelListener extends TransportListener {
36325
36497
  node: routingNode,
36326
36498
  });
36327
36499
  const selection = defaultGrantSelectionPolicy.selectCallbackGrant(selectionContext);
36328
- connectorConfig = this._grantToConnectorConfig(selection.grant);
36500
+ connectorConfig = this._grantToConnectorConfig(selection.grant, systemId);
36329
36501
  }
36330
36502
  catch (error) {
36331
36503
  logger$a.debug('broadcast_channel_listener_grant_selection_failed', {
@@ -36334,13 +36506,20 @@ class BroadcastChannelListener extends TransportListener {
36334
36506
  error: error instanceof Error ? error.message : String(error),
36335
36507
  });
36336
36508
  connectorConfig =
36337
- this._extractBroadcastConnectorConfig(frame) ??
36338
- {
36509
+ this._extractBroadcastConnectorConfig(frame, systemId) ??
36510
+ this._buildConnectorConfigForSystem(systemId, {
36339
36511
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
36340
36512
  channelName: this._channelName,
36341
36513
  inboxCapacity: this._inboxCapacity,
36342
36514
  passive: true,
36343
- };
36515
+ });
36516
+ }
36517
+ if (!connectorConfig) {
36518
+ logger$a.error('broadcast_channel_listener_missing_connector_config', {
36519
+ sender_id: params.senderId,
36520
+ system_id: systemId,
36521
+ });
36522
+ return null;
36344
36523
  }
36345
36524
  try {
36346
36525
  const connector = await routingNode.createOriginConnector({
@@ -36366,7 +36545,7 @@ class BroadcastChannelListener extends TransportListener {
36366
36545
  return null;
36367
36546
  }
36368
36547
  }
36369
- _extractBroadcastConnectorConfig(frame) {
36548
+ _extractBroadcastConnectorConfig(frame, systemId) {
36370
36549
  const rawGrants = frame.callbackGrants;
36371
36550
  if (!Array.isArray(rawGrants)) {
36372
36551
  return null;
@@ -36377,7 +36556,10 @@ class BroadcastChannelListener extends TransportListener {
36377
36556
  (grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE ||
36378
36557
  grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE)) {
36379
36558
  try {
36380
- return this._grantToConnectorConfig(grant);
36559
+ if (grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE) {
36560
+ return this._buildConnectorConfigForSystem(systemId, grant);
36561
+ }
36562
+ return this._buildConnectorConfigForSystem(systemId, broadcastChannelGrantToConnectorConfig(grant));
36381
36563
  }
36382
36564
  catch (error) {
36383
36565
  logger$a.debug('broadcast_channel_listener_grant_normalization_failed', {
@@ -36388,31 +36570,87 @@ class BroadcastChannelListener extends TransportListener {
36388
36570
  }
36389
36571
  return null;
36390
36572
  }
36391
- _grantToConnectorConfig(grant) {
36392
- if (grant.type !== BROADCAST_CHANNEL_CONNECTOR_TYPE) {
36393
- if (grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE) {
36394
- return broadcastChannelGrantToConnectorConfig(grant);
36573
+ _grantToConnectorConfig(grant, systemId) {
36574
+ if (grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE) {
36575
+ return this._buildConnectorConfigForSystem(systemId, grant);
36576
+ }
36577
+ if (grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE) {
36578
+ return this._buildConnectorConfigForSystem(systemId, broadcastChannelGrantToConnectorConfig(grant));
36579
+ }
36580
+ if ('toConnectorConfig' in grant &&
36581
+ typeof grant.toConnectorConfig ===
36582
+ 'function') {
36583
+ const normalized = grant.toConnectorConfig();
36584
+ if (normalized.type !== BROADCAST_CHANNEL_CONNECTOR_TYPE) {
36585
+ throw new Error(`Unsupported grant connector type: ${normalized.type}`);
36395
36586
  }
36396
- throw new Error(`Unsupported grant type: ${grant.type}`);
36587
+ return this._buildConnectorConfigForSystem(systemId, normalized);
36397
36588
  }
36398
- const candidate = grant;
36399
- const config = {
36589
+ throw new Error(`Unsupported grant type: ${grant.type}`);
36590
+ }
36591
+ _buildConnectorConfigForSystem(systemId, baseConfig) {
36592
+ const localNodeId = this._requireLocalNodeId();
36593
+ const targetSystemId = this._normalizeNodeId(systemId);
36594
+ if (!targetSystemId) {
36595
+ throw new Error('BroadcastChannelListener requires a valid system id');
36596
+ }
36597
+ const candidate = baseConfig ?? null;
36598
+ const channelCandidate = candidate && 'channelName' in candidate
36599
+ ? candidate.channelName
36600
+ : undefined;
36601
+ const inboxCandidate = candidate && 'inboxCapacity' in candidate
36602
+ ? candidate.inboxCapacity
36603
+ : undefined;
36604
+ const initialWindowCandidate = candidate && 'initialWindow' in candidate
36605
+ ? candidate.initialWindow
36606
+ : undefined;
36607
+ const passiveCandidate = candidate && 'passive' in candidate
36608
+ ? candidate.passive
36609
+ : undefined;
36610
+ const targetCandidate = candidate && 'initialTargetNodeId' in candidate
36611
+ ? candidate.initialTargetNodeId
36612
+ : undefined;
36613
+ const channelName = typeof channelCandidate === 'string' && channelCandidate.trim().length > 0
36614
+ ? channelCandidate.trim()
36615
+ : this._channelName;
36616
+ const inboxCapacity = typeof inboxCandidate === 'number' &&
36617
+ Number.isFinite(inboxCandidate) &&
36618
+ inboxCandidate > 0
36619
+ ? Math.floor(inboxCandidate)
36620
+ : this._inboxCapacity;
36621
+ const initialWindow = typeof initialWindowCandidate === 'number' &&
36622
+ Number.isFinite(initialWindowCandidate) &&
36623
+ initialWindowCandidate > 0
36624
+ ? Math.floor(initialWindowCandidate)
36625
+ : undefined;
36626
+ const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
36627
+ return {
36400
36628
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
36401
- channelName: this._channelName,
36402
- inboxCapacity: this._inboxCapacity,
36403
- passive: true,
36629
+ channelName,
36630
+ inboxCapacity,
36631
+ passive: typeof passiveCandidate === 'boolean' ? passiveCandidate : true,
36632
+ initialWindow,
36633
+ localNodeId,
36634
+ initialTargetNodeId,
36404
36635
  };
36405
- const channelCandidate = candidate.channelName ?? candidate['channel_name'];
36406
- if (typeof channelCandidate === 'string' && channelCandidate.trim().length > 0) {
36407
- config.channelName = channelCandidate.trim();
36636
+ }
36637
+ _requireLocalNodeId() {
36638
+ if (!this._routingNode) {
36639
+ throw new Error('BroadcastChannelListener requires routing node context');
36408
36640
  }
36409
- const inboxCandidate = candidate.inboxCapacity ?? candidate['inbox_capacity'];
36410
- if (typeof inboxCandidate === 'number' &&
36411
- Number.isFinite(inboxCandidate) &&
36412
- inboxCandidate > 0) {
36413
- config.inboxCapacity = Math.floor(inboxCandidate);
36641
+ const normalized = this._normalizeNodeId(this._routingNode.sid) ??
36642
+ this._normalizeNodeId(this._routingNode.id);
36643
+ if (!normalized) {
36644
+ throw new Error('BroadcastChannelListener requires routing node with a stable identifier');
36414
36645
  }
36415
- return config;
36646
+ return normalized;
36647
+ }
36648
+ _normalizeNodeId(value) {
36649
+ if (typeof value !== 'string') {
36650
+ return null;
36651
+ }
36652
+ const trimmed = value.trim();
36653
+ return trimmed.length > 0 ? trimmed : null;
36416
36654
  }
36417
36655
  _monitorConnectorLifecycle(senderId, systemId, connector) {
36418
36656
  const maybeClosable = connector;