@naylence/runtime 0.3.5-test.961 → 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.
@@ -98,12 +98,12 @@ installProcessEnvShim();
98
98
  // --- END ENV SHIM ---
99
99
 
100
100
  // This file is auto-generated during build - do not edit manually
101
- // Generated from package.json version: 0.3.5-test.961
101
+ // Generated from package.json version: 0.3.5-test.962
102
102
  /**
103
103
  * The package version, injected at build time.
104
104
  * @internal
105
105
  */
106
- const VERSION = '0.3.5-test.961';
106
+ const VERSION = '0.3.5-test.962';
107
107
 
108
108
  /**
109
109
  * Fame protocol specific error classes with WebSocket close codes and proper inheritance.
@@ -9946,6 +9946,26 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9946
9946
  }
9947
9947
  return null;
9948
9948
  }
9949
+ static normalizeNodeId(value) {
9950
+ if (typeof value !== 'string') {
9951
+ return null;
9952
+ }
9953
+ const trimmed = value.trim();
9954
+ return trimmed.length > 0 ? trimmed : null;
9955
+ }
9956
+ static normalizeTargetNodeId(value) {
9957
+ if (typeof value !== 'string') {
9958
+ return undefined;
9959
+ }
9960
+ const trimmed = value.trim();
9961
+ if (trimmed.length === 0) {
9962
+ return undefined;
9963
+ }
9964
+ if (trimmed === '*') {
9965
+ return '*';
9966
+ }
9967
+ return trimmed;
9968
+ }
9949
9969
  constructor(config, baseConfig = {}) {
9950
9970
  ensureBroadcastEnvironment();
9951
9971
  super(baseConfig);
@@ -9968,10 +9988,18 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9968
9988
  this.inbox = new BoundedAsyncQueue(preferredCapacity);
9969
9989
  this.inboxCapacity = preferredCapacity;
9970
9990
  this.connectorId = BroadcastChannelConnector.generateConnectorId();
9991
+ const normalizedLocalNodeId = BroadcastChannelConnector.normalizeNodeId(config.localNodeId);
9992
+ if (!normalizedLocalNodeId) {
9993
+ throw new Error('BroadcastChannelConnector requires a non-empty localNodeId');
9994
+ }
9995
+ this.localNodeId = normalizedLocalNodeId;
9996
+ this.targetNodeId = BroadcastChannelConnector.normalizeTargetNodeId(config.initialTargetNodeId);
9971
9997
  this.channel = new BroadcastChannel(this.channelName);
9972
9998
  logger$_.debug('broadcast_channel_connector_created', {
9973
9999
  channel: this.channelName,
9974
10000
  connector_id: this.connectorId,
10001
+ local_node_id: this.localNodeId,
10002
+ target_node_id: this.targetNodeId ?? null,
9975
10003
  inbox_capacity: preferredCapacity,
9976
10004
  timestamp: new Date().toISOString(),
9977
10005
  });
@@ -9993,15 +10021,32 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
9993
10021
  ? message.constructor?.name ?? typeof message
9994
10022
  : typeof message,
9995
10023
  has_sender_id: Boolean(message?.senderId),
10024
+ has_sender_node_id: Boolean(message?.senderNodeId),
9996
10025
  });
9997
10026
  if (!message || typeof message !== 'object') {
9998
10027
  return;
9999
10028
  }
10000
10029
  const busMessage = message;
10001
- if (typeof busMessage.senderId !== 'string' || busMessage.senderId.length === 0) {
10030
+ const senderNodeId = BroadcastChannelConnector.normalizeNodeId(busMessage.senderNodeId);
10031
+ if (!senderNodeId) {
10032
+ logger$_.debug('broadcast_channel_message_rejected', {
10033
+ channel: this.channelName,
10034
+ connector_id: this.connectorId,
10035
+ reason: 'missing_sender_node_id',
10036
+ });
10002
10037
  return;
10003
10038
  }
10004
- if (busMessage.senderId === this.connectorId) {
10039
+ if (senderNodeId === this.localNodeId) {
10040
+ logger$_.debug('broadcast_channel_message_rejected', {
10041
+ channel: this.channelName,
10042
+ connector_id: this.connectorId,
10043
+ reason: 'self_echo',
10044
+ sender_node_id: senderNodeId,
10045
+ });
10046
+ return;
10047
+ }
10048
+ const incomingTargetNodeId = BroadcastChannelConnector.normalizeTargetNodeId(busMessage.targetNodeId);
10049
+ if (!this._shouldAcceptMessageFromBus(senderNodeId, incomingTargetNodeId)) {
10005
10050
  return;
10006
10051
  }
10007
10052
  const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
@@ -10015,11 +10060,13 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10015
10060
  }
10016
10061
  logger$_.debug('broadcast_channel_message_received', {
10017
10062
  channel: this.channelName,
10018
- sender_id: busMessage.senderId,
10063
+ sender_id: message?.senderId,
10064
+ sender_node_id: senderNodeId,
10065
+ target_node_id: incomingTargetNodeId ?? null,
10019
10066
  connector_id: this.connectorId,
10020
10067
  payload_length: payload.byteLength,
10021
10068
  });
10022
- if (this._shouldSkipDuplicateAck(busMessage.senderId, payload)) {
10069
+ if (this._shouldSkipDuplicateAck(senderNodeId, payload)) {
10023
10070
  return;
10024
10071
  }
10025
10072
  try {
@@ -10163,12 +10210,17 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10163
10210
  }
10164
10211
  async _transportSendBytes(data) {
10165
10212
  ensureBroadcastEnvironment();
10213
+ const targetNodeId = this.targetNodeId ?? '*';
10166
10214
  logger$_.debug('broadcast_channel_message_sending', {
10167
10215
  channel: this.channelName,
10168
10216
  sender_id: this.connectorId,
10217
+ sender_node_id: this.localNodeId,
10218
+ target_node_id: targetNodeId,
10169
10219
  });
10170
10220
  this.channel.postMessage({
10171
10221
  senderId: this.connectorId,
10222
+ senderNodeId: this.localNodeId,
10223
+ targetNodeId,
10172
10224
  payload: data,
10173
10225
  });
10174
10226
  }
@@ -10231,6 +10283,51 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10231
10283
  }
10232
10284
  return rawOrEnvelope;
10233
10285
  }
10286
+ _isWildcardTarget() {
10287
+ return this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined';
10288
+ }
10289
+ _shouldAcceptMessageFromBus(senderNodeId, targetNodeId) {
10290
+ if (this._isWildcardTarget()) {
10291
+ if (targetNodeId && targetNodeId !== '*') {
10292
+ logger$_.debug('broadcast_channel_message_rejected', {
10293
+ channel: this.channelName,
10294
+ connector_id: this.connectorId,
10295
+ reason: 'wildcard_target_mismatch',
10296
+ sender_node_id: senderNodeId,
10297
+ target_node_id: targetNodeId,
10298
+ local_node_id: this.localNodeId,
10299
+ });
10300
+ return false;
10301
+ }
10302
+ return true;
10303
+ }
10304
+ const expectedSender = this.targetNodeId;
10305
+ if (expectedSender && expectedSender !== '*' && senderNodeId !== expectedSender) {
10306
+ logger$_.debug('broadcast_channel_message_rejected', {
10307
+ channel: this.channelName,
10308
+ connector_id: this.connectorId,
10309
+ reason: 'unexpected_sender',
10310
+ expected_sender_node_id: expectedSender,
10311
+ sender_node_id: senderNodeId,
10312
+ local_node_id: this.localNodeId,
10313
+ });
10314
+ return false;
10315
+ }
10316
+ if (targetNodeId &&
10317
+ targetNodeId !== '*' &&
10318
+ targetNodeId !== this.localNodeId) {
10319
+ logger$_.debug('broadcast_channel_message_rejected', {
10320
+ channel: this.channelName,
10321
+ connector_id: this.connectorId,
10322
+ reason: 'unexpected_target',
10323
+ sender_node_id: senderNodeId,
10324
+ target_node_id: targetNodeId,
10325
+ local_node_id: this.localNodeId,
10326
+ });
10327
+ return false;
10328
+ }
10329
+ return true;
10330
+ }
10234
10331
  _describeInboxItem(item) {
10235
10332
  if (item instanceof Uint8Array) {
10236
10333
  return 'bytes';
@@ -10261,7 +10358,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10261
10358
  const normalizedSenderId = typeof senderId === 'string' && senderId.length > 0
10262
10359
  ? senderId
10263
10360
  : undefined;
10264
- if (normalizedSenderId && normalizedSenderId !== this.connectorId) {
10361
+ if (normalizedSenderId && normalizedSenderId !== this.localNodeId) {
10265
10362
  logger$_.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
10266
10363
  channel: this.channelName,
10267
10364
  connector_id: this.connectorId,
@@ -10301,7 +10398,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10301
10398
  return false;
10302
10399
  }
10303
10400
  const senderId = this._extractSenderIdFromInboxItem(item);
10304
- if (senderId && senderId !== this.connectorId) {
10401
+ if (senderId && senderId !== this.localNodeId) {
10305
10402
  logger$_.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
10306
10403
  channel: this.channelName,
10307
10404
  connector_id: this.connectorId,
@@ -10397,6 +10494,34 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
10397
10494
  });
10398
10495
  }
10399
10496
  }
10497
+ setTargetNodeId(nodeId) {
10498
+ const normalized = BroadcastChannelConnector.normalizeNodeId(nodeId);
10499
+ if (!normalized) {
10500
+ throw new Error('BroadcastChannelConnector target node id must be a non-empty string');
10501
+ }
10502
+ if (normalized === '*') {
10503
+ this.setWildcardTarget();
10504
+ return;
10505
+ }
10506
+ this.targetNodeId = normalized;
10507
+ logger$_.debug('broadcast_channel_target_updated', {
10508
+ channel: this.channelName,
10509
+ connector_id: this.connectorId,
10510
+ local_node_id: this.localNodeId,
10511
+ target_node_id: this.targetNodeId,
10512
+ target_mode: 'direct',
10513
+ });
10514
+ }
10515
+ setWildcardTarget() {
10516
+ this.targetNodeId = '*';
10517
+ logger$_.debug('broadcast_channel_target_updated', {
10518
+ channel: this.channelName,
10519
+ connector_id: this.connectorId,
10520
+ local_node_id: this.localNodeId,
10521
+ target_node_id: this.targetNodeId,
10522
+ target_mode: 'wildcard',
10523
+ });
10524
+ }
10400
10525
  _trimSeenAcks(now) {
10401
10526
  while (this.seenAckOrder.length > 0) {
10402
10527
  const candidate = this.seenAckOrder[0];
@@ -28933,8 +29058,13 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28933
29058
  }
28934
29059
  const normalized = this._normalizeConfig(config);
28935
29060
  const options = (factoryArgs[0] ?? {});
29061
+ const localNodeId = this._normalizeNodeId(options.localNodeId);
29062
+ if (!localNodeId) {
29063
+ throw new Error('BroadcastChannelConnectorFactory requires a localNodeId in create() options');
29064
+ }
28936
29065
  const channelName = normalized.channelName ?? DEFAULT_CHANNEL$4;
28937
29066
  const inboxCapacity = normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$4;
29067
+ const resolvedTarget = this._normalizeTargetNodeId(options.initialTargetNodeId ?? normalized.initialTargetNodeId);
28938
29068
  const baseConfig = {
28939
29069
  drainTimeout: normalized.drainTimeout,
28940
29070
  flowControl: normalized.flowControl,
@@ -28949,6 +29079,8 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28949
29079
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
28950
29080
  channelName,
28951
29081
  inboxCapacity,
29082
+ localNodeId,
29083
+ initialTargetNodeId: resolvedTarget,
28952
29084
  };
28953
29085
  const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
28954
29086
  if (options.authorization) {
@@ -28972,6 +29104,13 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
28972
29104
  normalized.channelName = channel.trim();
28973
29105
  }
28974
29106
  const capacity = candidate.inboxCapacity ?? candidate['inbox_capacity'];
29107
+ const initialTargetNodeId = candidate.initialTargetNodeId ?? candidate['initial_target_node_id'];
29108
+ if (typeof initialTargetNodeId === 'string' && initialTargetNodeId.trim().length > 0) {
29109
+ normalized.initialTargetNodeId = initialTargetNodeId.trim();
29110
+ }
29111
+ else if (initialTargetNodeId === '*') {
29112
+ normalized.initialTargetNodeId = '*';
29113
+ }
28975
29114
  if (typeof capacity === 'number' &&
28976
29115
  Number.isFinite(capacity) &&
28977
29116
  capacity > 0) {
@@ -29015,6 +29154,19 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
29015
29154
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$4;
29016
29155
  return normalized;
29017
29156
  }
29157
+ _normalizeNodeId(value) {
29158
+ if (typeof value !== 'string') {
29159
+ return null;
29160
+ }
29161
+ const trimmed = value.trim();
29162
+ return trimmed.length > 0 ? trimmed : null;
29163
+ }
29164
+ _normalizeTargetNodeId(value) {
29165
+ if (value === '*') {
29166
+ return '*';
29167
+ }
29168
+ return this._normalizeNodeId(value) ?? '*';
29169
+ }
29018
29170
  }
29019
29171
 
29020
29172
  var broadcastChannelConnectorFactory = /*#__PURE__*/Object.freeze({
@@ -30118,7 +30270,7 @@ class BroadcastChannelListener extends TransportListener {
30118
30270
  node: routingNode,
30119
30271
  });
30120
30272
  const selection = defaultGrantSelectionPolicy.selectCallbackGrant(selectionContext);
30121
- connectorConfig = this._grantToConnectorConfig(selection.grant);
30273
+ connectorConfig = this._grantToConnectorConfig(selection.grant, systemId);
30122
30274
  }
30123
30275
  catch (error) {
30124
30276
  logger$o.debug('broadcast_channel_listener_grant_selection_failed', {
@@ -30127,13 +30279,20 @@ class BroadcastChannelListener extends TransportListener {
30127
30279
  error: error instanceof Error ? error.message : String(error),
30128
30280
  });
30129
30281
  connectorConfig =
30130
- this._extractBroadcastConnectorConfig(frame) ??
30131
- {
30282
+ this._extractBroadcastConnectorConfig(frame, systemId) ??
30283
+ this._buildConnectorConfigForSystem(systemId, {
30132
30284
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
30133
30285
  channelName: this._channelName,
30134
30286
  inboxCapacity: this._inboxCapacity,
30135
30287
  passive: true,
30136
- };
30288
+ });
30289
+ }
30290
+ if (!connectorConfig) {
30291
+ logger$o.error('broadcast_channel_listener_missing_connector_config', {
30292
+ sender_id: params.senderId,
30293
+ system_id: systemId,
30294
+ });
30295
+ return null;
30137
30296
  }
30138
30297
  try {
30139
30298
  const connector = await routingNode.createOriginConnector({
@@ -30159,7 +30318,7 @@ class BroadcastChannelListener extends TransportListener {
30159
30318
  return null;
30160
30319
  }
30161
30320
  }
30162
- _extractBroadcastConnectorConfig(frame) {
30321
+ _extractBroadcastConnectorConfig(frame, systemId) {
30163
30322
  const rawGrants = frame.callbackGrants;
30164
30323
  if (!Array.isArray(rawGrants)) {
30165
30324
  return null;
@@ -30170,7 +30329,10 @@ class BroadcastChannelListener extends TransportListener {
30170
30329
  (grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE ||
30171
30330
  grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE)) {
30172
30331
  try {
30173
- return this._grantToConnectorConfig(grant);
30332
+ if (grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE) {
30333
+ return this._buildConnectorConfigForSystem(systemId, grant);
30334
+ }
30335
+ return this._buildConnectorConfigForSystem(systemId, broadcastChannelGrantToConnectorConfig(grant));
30174
30336
  }
30175
30337
  catch (error) {
30176
30338
  logger$o.debug('broadcast_channel_listener_grant_normalization_failed', {
@@ -30181,31 +30343,87 @@ class BroadcastChannelListener extends TransportListener {
30181
30343
  }
30182
30344
  return null;
30183
30345
  }
30184
- _grantToConnectorConfig(grant) {
30185
- if (grant.type !== BROADCAST_CHANNEL_CONNECTOR_TYPE) {
30186
- if (grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE) {
30187
- return broadcastChannelGrantToConnectorConfig(grant);
30346
+ _grantToConnectorConfig(grant, systemId) {
30347
+ if (grant.type === BROADCAST_CHANNEL_CONNECTOR_TYPE) {
30348
+ return this._buildConnectorConfigForSystem(systemId, grant);
30349
+ }
30350
+ if (grant.type === BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE) {
30351
+ return this._buildConnectorConfigForSystem(systemId, broadcastChannelGrantToConnectorConfig(grant));
30352
+ }
30353
+ if ('toConnectorConfig' in grant &&
30354
+ typeof grant.toConnectorConfig ===
30355
+ 'function') {
30356
+ const normalized = grant.toConnectorConfig();
30357
+ if (normalized.type !== BROADCAST_CHANNEL_CONNECTOR_TYPE) {
30358
+ throw new Error(`Unsupported grant connector type: ${normalized.type}`);
30188
30359
  }
30189
- throw new Error(`Unsupported grant type: ${grant.type}`);
30360
+ return this._buildConnectorConfigForSystem(systemId, normalized);
30190
30361
  }
30191
- const candidate = grant;
30192
- const config = {
30362
+ throw new Error(`Unsupported grant type: ${grant.type}`);
30363
+ }
30364
+ _buildConnectorConfigForSystem(systemId, baseConfig) {
30365
+ const localNodeId = this._requireLocalNodeId();
30366
+ const targetSystemId = this._normalizeNodeId(systemId);
30367
+ if (!targetSystemId) {
30368
+ throw new Error('BroadcastChannelListener requires a valid system id');
30369
+ }
30370
+ const candidate = baseConfig ?? null;
30371
+ const channelCandidate = candidate && 'channelName' in candidate
30372
+ ? candidate.channelName
30373
+ : undefined;
30374
+ const inboxCandidate = candidate && 'inboxCapacity' in candidate
30375
+ ? candidate.inboxCapacity
30376
+ : undefined;
30377
+ const initialWindowCandidate = candidate && 'initialWindow' in candidate
30378
+ ? candidate.initialWindow
30379
+ : undefined;
30380
+ const passiveCandidate = candidate && 'passive' in candidate
30381
+ ? candidate.passive
30382
+ : undefined;
30383
+ const targetCandidate = candidate && 'initialTargetNodeId' in candidate
30384
+ ? candidate.initialTargetNodeId
30385
+ : undefined;
30386
+ const channelName = typeof channelCandidate === 'string' && channelCandidate.trim().length > 0
30387
+ ? channelCandidate.trim()
30388
+ : this._channelName;
30389
+ const inboxCapacity = typeof inboxCandidate === 'number' &&
30390
+ Number.isFinite(inboxCandidate) &&
30391
+ inboxCandidate > 0
30392
+ ? Math.floor(inboxCandidate)
30393
+ : this._inboxCapacity;
30394
+ const initialWindow = typeof initialWindowCandidate === 'number' &&
30395
+ Number.isFinite(initialWindowCandidate) &&
30396
+ initialWindowCandidate > 0
30397
+ ? Math.floor(initialWindowCandidate)
30398
+ : undefined;
30399
+ const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
30400
+ return {
30193
30401
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
30194
- channelName: this._channelName,
30195
- inboxCapacity: this._inboxCapacity,
30196
- passive: true,
30402
+ channelName,
30403
+ inboxCapacity,
30404
+ passive: typeof passiveCandidate === 'boolean' ? passiveCandidate : true,
30405
+ initialWindow,
30406
+ localNodeId,
30407
+ initialTargetNodeId,
30197
30408
  };
30198
- const channelCandidate = candidate.channelName ?? candidate['channel_name'];
30199
- if (typeof channelCandidate === 'string' && channelCandidate.trim().length > 0) {
30200
- config.channelName = channelCandidate.trim();
30409
+ }
30410
+ _requireLocalNodeId() {
30411
+ if (!this._routingNode) {
30412
+ throw new Error('BroadcastChannelListener requires routing node context');
30201
30413
  }
30202
- const inboxCandidate = candidate.inboxCapacity ?? candidate['inbox_capacity'];
30203
- if (typeof inboxCandidate === 'number' &&
30204
- Number.isFinite(inboxCandidate) &&
30205
- inboxCandidate > 0) {
30206
- config.inboxCapacity = Math.floor(inboxCandidate);
30414
+ const normalized = this._normalizeNodeId(this._routingNode.sid) ??
30415
+ this._normalizeNodeId(this._routingNode.id);
30416
+ if (!normalized) {
30417
+ throw new Error('BroadcastChannelListener requires routing node with a stable identifier');
30207
30418
  }
30208
- return config;
30419
+ return normalized;
30420
+ }
30421
+ _normalizeNodeId(value) {
30422
+ if (typeof value !== 'string') {
30423
+ return null;
30424
+ }
30425
+ const trimmed = value.trim();
30426
+ return trimmed.length > 0 ? trimmed : null;
30209
30427
  }
30210
30428
  _monitorConnectorLifecycle(senderId, systemId, connector) {
30211
30429
  const maybeClosable = connector;