@naylence/runtime 0.3.5-test.965 → 0.3.5-test.967

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.
@@ -73,11 +73,6 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
73
73
  ensureBroadcastEnvironment();
74
74
  super(baseConfig);
75
75
  this.listenerRegistered = false;
76
- this.seenAckKeys = new Map();
77
- this.seenAckOrder = [];
78
- this.ackDedupTtlMs = 30000;
79
- this.ackDedupMaxEntries = 4096;
80
- this.textDecoder = new TextDecoder();
81
76
  this.visibilityChangeListenerRegistered = false;
82
77
  this.channelName =
83
78
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
@@ -169,9 +164,6 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
169
164
  connector_id: this.connectorId,
170
165
  payload_length: payload.byteLength,
171
166
  });
172
- if (this._shouldSkipDuplicateAck(senderNodeId, payload)) {
173
- return;
174
- }
175
167
  try {
176
168
  if (typeof this.inbox.tryEnqueue === 'function') {
177
169
  const accepted = this.inbox.tryEnqueue(payload);
@@ -275,9 +267,6 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
275
267
  }
276
268
  async pushToReceive(rawOrEnvelope) {
277
269
  const item = this._normalizeInboxItem(rawOrEnvelope);
278
- if (this._shouldSkipDuplicateAckFromInboxItem(item)) {
279
- return;
280
- }
281
270
  try {
282
271
  if (typeof this.inbox.tryEnqueue === 'function') {
283
272
  const accepted = this.inbox.tryEnqueue(item);
@@ -377,8 +366,6 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
377
366
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
378
367
  const shutdownError = new errors_js_1.FameTransportClose(closeReason, closeCode);
379
368
  this.inbox.drain(shutdownError);
380
- this.seenAckKeys.clear();
381
- this.seenAckOrder.length = 0;
382
369
  }
383
370
  _normalizeInboxItem(rawOrEnvelope) {
384
371
  if (rawOrEnvelope instanceof Uint8Array) {
@@ -455,125 +442,6 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
455
442
  ...extra,
456
443
  });
457
444
  }
458
- _shouldSkipDuplicateAck(senderId, payload) {
459
- const dedupKey = this._extractAckDedupKey(payload);
460
- if (!dedupKey) {
461
- return false;
462
- }
463
- const normalizedSenderId = typeof senderId === 'string' && senderId.length > 0
464
- ? senderId
465
- : undefined;
466
- if (normalizedSenderId && normalizedSenderId !== this.localNodeId) {
467
- logger.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
468
- channel: this.channelName,
469
- connector_id: this.connectorId,
470
- sender_id: normalizedSenderId,
471
- dedup_key: dedupKey,
472
- source: 'listener',
473
- });
474
- return false;
475
- }
476
- logger.debug('broadcast_channel_duplicate_ack_check', {
477
- channel: this.channelName,
478
- connector_id: this.connectorId,
479
- sender_id: normalizedSenderId ?? null,
480
- dedup_key: dedupKey,
481
- source: 'listener',
482
- cache_entries: this.seenAckKeys.size,
483
- });
484
- return this._checkDuplicateAck(dedupKey, normalizedSenderId);
485
- }
486
- _shouldSkipDuplicateAckFromInboxItem(item) {
487
- if (item instanceof Uint8Array) {
488
- return this._shouldSkipDuplicateAck(undefined, item);
489
- }
490
- const envelope = this._extractEnvelopeFromInboxItem(item);
491
- if (!envelope) {
492
- return false;
493
- }
494
- const frame = envelope.frame;
495
- if (!frame || frame.type !== 'DeliveryAck') {
496
- return false;
497
- }
498
- const refId = typeof frame.refId === 'string' && frame.refId.length > 0
499
- ? frame.refId
500
- : null;
501
- const dedupKey = refId ?? envelope.id ?? null;
502
- if (!dedupKey) {
503
- return false;
504
- }
505
- const senderId = this._extractSenderIdFromInboxItem(item);
506
- if (senderId && senderId !== this.localNodeId) {
507
- logger.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
508
- channel: this.channelName,
509
- connector_id: this.connectorId,
510
- sender_id: senderId,
511
- dedup_key: dedupKey,
512
- source: 'inbox_item',
513
- });
514
- return false;
515
- }
516
- logger.debug('broadcast_channel_duplicate_ack_check', {
517
- channel: this.channelName,
518
- connector_id: this.connectorId,
519
- sender_id: senderId ?? null,
520
- dedup_key: dedupKey,
521
- source: 'inbox_item',
522
- cache_entries: this.seenAckKeys.size,
523
- });
524
- return this._checkDuplicateAck(dedupKey, senderId);
525
- }
526
- _checkDuplicateAck(dedupKey, senderId) {
527
- const now = Date.now();
528
- const lastSeen = this.seenAckKeys.get(dedupKey);
529
- if (lastSeen && now - lastSeen < this.ackDedupTtlMs) {
530
- logger.debug('broadcast_channel_duplicate_ack_suppressed', {
531
- channel: this.channelName,
532
- connector_id: this.connectorId,
533
- sender_id: senderId ?? null,
534
- dedup_key: dedupKey,
535
- age_ms: now - lastSeen,
536
- ttl_ms: this.ackDedupTtlMs,
537
- cache_entries: this.seenAckKeys.size,
538
- });
539
- return true;
540
- }
541
- this.seenAckKeys.set(dedupKey, now);
542
- this.seenAckOrder.push(dedupKey);
543
- logger.debug('broadcast_channel_duplicate_ack_recorded', {
544
- channel: this.channelName,
545
- connector_id: this.connectorId,
546
- sender_id: senderId ?? null,
547
- dedup_key: dedupKey,
548
- cache_entries: this.seenAckKeys.size,
549
- });
550
- this._trimSeenAcks(now);
551
- return false;
552
- }
553
- _extractEnvelopeFromInboxItem(item) {
554
- if (!item || typeof item !== 'object') {
555
- return null;
556
- }
557
- if ('envelope' in item) {
558
- return item.envelope;
559
- }
560
- if ('frame' in item) {
561
- return item;
562
- }
563
- return null;
564
- }
565
- _extractSenderIdFromInboxItem(item) {
566
- if (!item || typeof item !== 'object') {
567
- return undefined;
568
- }
569
- if ('context' in item) {
570
- const context = item.context;
571
- if (context && typeof context.fromSystemId === 'string') {
572
- return context.fromSystemId;
573
- }
574
- }
575
- return undefined;
576
- }
577
445
  /**
578
446
  * Override start() to check initial visibility state
579
447
  */
@@ -627,46 +495,5 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
627
495
  target_mode: 'wildcard',
628
496
  });
629
497
  }
630
- _trimSeenAcks(now) {
631
- while (this.seenAckOrder.length > 0) {
632
- const candidate = this.seenAckOrder[0];
633
- const timestamp = this.seenAckKeys.get(candidate);
634
- if (timestamp === undefined) {
635
- this.seenAckOrder.shift();
636
- continue;
637
- }
638
- if (this.seenAckKeys.size > this.ackDedupMaxEntries ||
639
- now - timestamp > this.ackDedupTtlMs) {
640
- this.seenAckKeys.delete(candidate);
641
- this.seenAckOrder.shift();
642
- continue;
643
- }
644
- break;
645
- }
646
- }
647
- _extractAckDedupKey(payload) {
648
- try {
649
- const decoded = this.textDecoder.decode(payload);
650
- const parsed = JSON.parse(decoded);
651
- const envelopeId = typeof parsed?.id === 'string' ? parsed.id : null;
652
- const frameType = parsed?.frame?.type;
653
- if (typeof frameType !== 'string' || frameType !== 'DeliveryAck') {
654
- return null;
655
- }
656
- const refId = parsed.frame?.refId;
657
- if (typeof refId === 'string' && refId.length > 0) {
658
- return refId;
659
- }
660
- return envelopeId;
661
- }
662
- catch (error) {
663
- logger.debug('broadcast_channel_ack_dedup_parse_failed', {
664
- channel: this.channelName,
665
- connector_id: this.connectorId,
666
- error: error instanceof Error ? error.message : String(error),
667
- });
668
- return null;
669
- }
670
- }
671
498
  }
672
499
  exports.BroadcastChannelConnector = BroadcastChannelConnector;
@@ -68,8 +68,16 @@ class InPageConnectorFactory extends connector_factory_js_1.ConnectorFactory {
68
68
  }
69
69
  const normalized = this._normalizeConfig(config);
70
70
  const options = (factoryArgs[0] ?? {});
71
+ const normalizedLocalNodeFromConfig = this._normalizeNodeId(normalized.localNodeId);
72
+ const localNodeId = this._normalizeNodeId(options.localNodeId) ?? normalizedLocalNodeFromConfig;
73
+ if (!localNodeId) {
74
+ throw new Error('InPageConnectorFactory requires a localNodeId from config or create() options');
75
+ }
71
76
  const channelName = normalized.channelName ?? DEFAULT_CHANNEL;
72
77
  const inboxCapacity = normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY;
78
+ const targetFromOptions = this._normalizeTargetNodeId(options.initialTargetNodeId);
79
+ const targetFromConfig = this._normalizeTargetNodeId(normalized.initialTargetNodeId);
80
+ const resolvedTarget = targetFromOptions ?? targetFromConfig ?? '*';
73
81
  const baseConfig = {
74
82
  drainTimeout: normalized.drainTimeout,
75
83
  flowControl: normalized.flowControl,
@@ -84,6 +92,8 @@ class InPageConnectorFactory extends connector_factory_js_1.ConnectorFactory {
84
92
  type: inpage_connector_js_1.INPAGE_CONNECTOR_TYPE,
85
93
  channelName,
86
94
  inboxCapacity,
95
+ localNodeId,
96
+ initialTargetNodeId: resolvedTarget,
87
97
  };
88
98
  const connector = new inpage_connector_js_1.InPageConnector(connectorConfig, baseConfig);
89
99
  if (options.authorization) {
@@ -119,6 +129,16 @@ class InPageConnectorFactory extends connector_factory_js_1.ConnectorFactory {
119
129
  capacity > 0) {
120
130
  normalized.inboxCapacity = Math.floor(capacity);
121
131
  }
132
+ const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
133
+ const normalizedLocalNodeId = this._normalizeNodeId(localNodeId);
134
+ if (normalizedLocalNodeId) {
135
+ normalized.localNodeId = normalizedLocalNodeId;
136
+ }
137
+ const initialTargetNodeId = candidate.initialTargetNodeId ?? candidate['initial_target_node_id'];
138
+ const normalizedTarget = this._normalizeTargetNodeId(initialTargetNodeId);
139
+ if (normalizedTarget) {
140
+ normalized.initialTargetNodeId = normalizedTarget;
141
+ }
122
142
  if (typeof candidate.flowControl === 'boolean') {
123
143
  normalized.flowControl = candidate.flowControl;
124
144
  }
@@ -157,6 +177,22 @@ class InPageConnectorFactory extends connector_factory_js_1.ConnectorFactory {
157
177
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY;
158
178
  return normalized;
159
179
  }
180
+ _normalizeNodeId(value) {
181
+ if (typeof value !== 'string') {
182
+ return null;
183
+ }
184
+ const trimmed = value.trim();
185
+ return trimmed.length > 0 ? trimmed : null;
186
+ }
187
+ _normalizeTargetNodeId(value) {
188
+ if (value === undefined || value === null) {
189
+ return undefined;
190
+ }
191
+ if (value === '*') {
192
+ return '*';
193
+ }
194
+ return this._normalizeNodeId(value) ?? undefined;
195
+ }
160
196
  }
161
197
  exports.InPageConnectorFactory = InPageConnectorFactory;
162
198
  exports.default = InPageConnectorFactory;
@@ -64,6 +64,26 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
64
64
  }
65
65
  return null;
66
66
  }
67
+ static normalizeNodeId(value) {
68
+ if (typeof value !== 'string') {
69
+ return null;
70
+ }
71
+ const trimmed = value.trim();
72
+ return trimmed.length > 0 ? trimmed : null;
73
+ }
74
+ static normalizeTargetNodeId(value) {
75
+ if (typeof value !== 'string') {
76
+ return undefined;
77
+ }
78
+ const trimmed = value.trim();
79
+ if (trimmed.length === 0) {
80
+ return undefined;
81
+ }
82
+ if (trimmed === '*') {
83
+ return '*';
84
+ }
85
+ return trimmed;
86
+ }
67
87
  constructor(config, baseConfig = {}) {
68
88
  ensureBrowserEnvironment();
69
89
  super(baseConfig);
@@ -79,41 +99,68 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
79
99
  ? Math.floor(config.inboxCapacity)
80
100
  : DEFAULT_INBOX_CAPACITY;
81
101
  this.inbox = new bounded_async_queue_js_1.BoundedAsyncQueue(preferredCapacity);
102
+ this.inboxCapacity = preferredCapacity;
82
103
  this.connectorId = InPageConnector.generateConnectorId();
104
+ const normalizedLocalNodeId = InPageConnector.normalizeNodeId(config.localNodeId);
105
+ if (!normalizedLocalNodeId) {
106
+ throw new Error('InPageConnector requires a non-empty localNodeId');
107
+ }
108
+ this.localNodeId = normalizedLocalNodeId;
109
+ this.targetNodeId = InPageConnector.normalizeTargetNodeId(config.initialTargetNodeId);
83
110
  logger.debug('inpage_connector_initialized', {
84
111
  channel: this.channelName,
85
112
  connector_id: this.connectorId,
113
+ local_node_id: this.localNodeId,
114
+ target_node_id: this.targetNodeId ?? null,
115
+ inbox_capacity: preferredCapacity,
86
116
  });
87
117
  this.onMsg = (event) => {
118
+ if (!this.listenerRegistered) {
119
+ logger.warning('inpage_message_after_unregister', {
120
+ channel: this.channelName,
121
+ connector_id: this.connectorId,
122
+ timestamp: new Date().toISOString(),
123
+ });
124
+ return;
125
+ }
88
126
  const messageEvent = event;
89
127
  const message = messageEvent.data;
90
128
  logger.debug('inpage_raw_event', {
91
129
  channel: this.channelName,
92
130
  connector_id: this.connectorId,
93
- message_type: message && typeof message === 'object' ? message.constructor?.name ?? typeof message : typeof message,
94
- has_sender_id: Boolean(message?.senderId),
95
- payload_type: message && typeof message === 'object'
96
- ? message?.payload instanceof Uint8Array
97
- ? 'Uint8Array'
98
- : message?.payload instanceof ArrayBuffer
99
- ? 'ArrayBuffer'
100
- : typeof message?.payload
131
+ message_type: message && typeof message === 'object'
132
+ ? message.constructor?.name ?? typeof message
101
133
  : typeof message,
102
- payload_constructor: message && typeof message === 'object'
103
- ? message?.payload?.constructor?.name
104
- : undefined,
105
- payload_keys: message && typeof message === 'object' && message?.payload && typeof message?.payload === 'object'
106
- ? Object.keys(message.payload).slice(0, 5)
107
- : undefined,
134
+ has_sender_id: Boolean(message?.senderId),
135
+ has_sender_node_id: Boolean(message?.senderNodeId),
108
136
  });
109
137
  if (!message || typeof message !== 'object') {
110
138
  return;
111
139
  }
112
140
  const busMessage = message;
113
- if (typeof busMessage.senderId !== 'string' || busMessage.senderId.length === 0) {
141
+ const senderId = typeof busMessage.senderId === 'string' && busMessage.senderId.length > 0
142
+ ? busMessage.senderId
143
+ : null;
144
+ const senderNodeId = InPageConnector.normalizeNodeId(busMessage.senderNodeId);
145
+ if (!senderId || !senderNodeId) {
146
+ logger.debug('inpage_message_rejected', {
147
+ channel: this.channelName,
148
+ connector_id: this.connectorId,
149
+ reason: 'missing_sender_metadata',
150
+ });
114
151
  return;
115
152
  }
116
- if (busMessage.senderId === this.connectorId) {
153
+ if (senderId === this.connectorId || senderNodeId === this.localNodeId) {
154
+ logger.debug('inpage_message_rejected', {
155
+ channel: this.channelName,
156
+ connector_id: this.connectorId,
157
+ reason: 'self_echo',
158
+ sender_node_id: senderNodeId,
159
+ });
160
+ return;
161
+ }
162
+ const incomingTargetNodeId = InPageConnector.normalizeTargetNodeId(busMessage.targetNodeId);
163
+ if (!this._shouldAcceptMessageFromBus(senderNodeId, incomingTargetNodeId)) {
117
164
  return;
118
165
  }
119
166
  const payload = InPageConnector.coercePayload(busMessage.payload);
@@ -127,7 +174,9 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
127
174
  }
128
175
  logger.debug('inpage_message_received', {
129
176
  channel: this.channelName,
130
- sender_id: busMessage.senderId,
177
+ sender_id: senderId,
178
+ sender_node_id: senderNodeId,
179
+ target_node_id: incomingTargetNodeId ?? null,
131
180
  connector_id: this.connectorId,
132
181
  payload_length: payload.byteLength,
133
182
  });
@@ -135,15 +184,27 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
135
184
  if (typeof this.inbox.tryEnqueue === 'function') {
136
185
  const accepted = this.inbox.tryEnqueue(payload);
137
186
  if (accepted) {
187
+ this.logInboxSnapshot('inpage_inbox_enqueued', {
188
+ source: 'listener',
189
+ enqueue_strategy: 'try',
190
+ payload_length: payload.byteLength,
191
+ });
138
192
  return;
139
193
  }
140
194
  }
141
195
  this.inbox.enqueue(payload);
196
+ this.logInboxSnapshot('inpage_inbox_enqueued', {
197
+ source: 'listener',
198
+ enqueue_strategy: 'enqueue',
199
+ payload_length: payload.byteLength,
200
+ });
142
201
  }
143
202
  catch (error) {
144
203
  if (error instanceof bounded_async_queue_js_1.QueueFullError) {
145
204
  logger.warning('inpage_receive_queue_full', {
146
205
  channel: this.channelName,
206
+ inbox_capacity: this.inboxCapacity,
207
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
147
208
  });
148
209
  }
149
210
  else {
@@ -250,15 +311,25 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
250
311
  if (typeof this.inbox.tryEnqueue === 'function') {
251
312
  const accepted = this.inbox.tryEnqueue(item);
252
313
  if (accepted) {
314
+ this.logInboxSnapshot('inpage_push_enqueued', {
315
+ enqueue_strategy: 'try',
316
+ item_type: this._describeInboxItem(item),
317
+ });
253
318
  return;
254
319
  }
255
320
  }
256
321
  this.inbox.enqueue(item);
322
+ this.logInboxSnapshot('inpage_push_enqueued', {
323
+ enqueue_strategy: 'enqueue',
324
+ item_type: this._describeInboxItem(item),
325
+ });
257
326
  }
258
327
  catch (error) {
259
328
  if (error instanceof bounded_async_queue_js_1.QueueFullError) {
260
329
  logger.warning('inpage_push_queue_full', {
261
330
  channel: this.channelName,
331
+ inbox_capacity: this.inboxCapacity,
332
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
262
333
  });
263
334
  throw error;
264
335
  }
@@ -271,25 +342,52 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
271
342
  }
272
343
  async _transportSendBytes(data) {
273
344
  ensureBrowserEnvironment();
345
+ const targetNodeId = this.targetNodeId ?? '*';
274
346
  logger.debug('inpage_message_sending', {
275
347
  channel: this.channelName,
276
348
  sender_id: this.connectorId,
349
+ sender_node_id: this.localNodeId,
350
+ target_node_id: targetNodeId,
277
351
  });
278
352
  const event = new MessageEvent(this.channelName, {
279
353
  data: {
280
354
  senderId: this.connectorId,
355
+ senderNodeId: this.localNodeId,
356
+ targetNodeId,
281
357
  payload: data,
282
358
  },
283
359
  });
284
360
  getSharedBus().dispatchEvent(event);
285
361
  }
286
362
  async _transportReceive() {
287
- return await this.inbox.dequeue();
363
+ const item = await this.inbox.dequeue();
364
+ this.logInboxSnapshot('inpage_inbox_dequeued', {
365
+ item_type: this._describeInboxItem(item),
366
+ });
367
+ return item;
288
368
  }
289
369
  async _transportClose(code, reason) {
370
+ logger.debug('inpage_transport_closing', {
371
+ channel: this.channelName,
372
+ connector_id: this.connectorId,
373
+ code,
374
+ reason,
375
+ listener_registered: this.listenerRegistered,
376
+ timestamp: new Date().toISOString(),
377
+ });
290
378
  if (this.listenerRegistered) {
379
+ logger.debug('inpage_removing_listener', {
380
+ channel: this.channelName,
381
+ connector_id: this.connectorId,
382
+ timestamp: new Date().toISOString(),
383
+ });
291
384
  getSharedBus().removeEventListener(this.channelName, this.onMsg);
292
385
  this.listenerRegistered = false;
386
+ logger.debug('inpage_listener_removed', {
387
+ channel: this.channelName,
388
+ connector_id: this.connectorId,
389
+ timestamp: new Date().toISOString(),
390
+ });
293
391
  }
294
392
  if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
295
393
  document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
@@ -307,5 +405,102 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
307
405
  }
308
406
  return rawOrEnvelope;
309
407
  }
408
+ _isWildcardTarget() {
409
+ return this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined';
410
+ }
411
+ _shouldAcceptMessageFromBus(senderNodeId, targetNodeId) {
412
+ if (this._isWildcardTarget()) {
413
+ if (targetNodeId &&
414
+ targetNodeId !== '*' &&
415
+ targetNodeId !== this.localNodeId) {
416
+ logger.debug('inpage_message_rejected', {
417
+ channel: this.channelName,
418
+ connector_id: this.connectorId,
419
+ reason: 'wildcard_target_mismatch',
420
+ sender_node_id: senderNodeId,
421
+ target_node_id: targetNodeId,
422
+ local_node_id: this.localNodeId,
423
+ });
424
+ return false;
425
+ }
426
+ return true;
427
+ }
428
+ const expectedSender = this.targetNodeId;
429
+ if (expectedSender && expectedSender !== '*' && senderNodeId !== expectedSender) {
430
+ logger.debug('inpage_message_rejected', {
431
+ channel: this.channelName,
432
+ connector_id: this.connectorId,
433
+ reason: 'unexpected_sender',
434
+ expected_sender_node_id: expectedSender,
435
+ sender_node_id: senderNodeId,
436
+ local_node_id: this.localNodeId,
437
+ });
438
+ return false;
439
+ }
440
+ if (targetNodeId &&
441
+ targetNodeId !== '*' &&
442
+ targetNodeId !== this.localNodeId) {
443
+ logger.debug('inpage_message_rejected', {
444
+ channel: this.channelName,
445
+ connector_id: this.connectorId,
446
+ reason: 'unexpected_target',
447
+ sender_node_id: senderNodeId,
448
+ target_node_id: targetNodeId,
449
+ local_node_id: this.localNodeId,
450
+ });
451
+ return false;
452
+ }
453
+ return true;
454
+ }
455
+ _describeInboxItem(item) {
456
+ if (item instanceof Uint8Array) {
457
+ return 'bytes';
458
+ }
459
+ if (item.envelope) {
460
+ return 'channel_message';
461
+ }
462
+ if (item.frame) {
463
+ return 'envelope';
464
+ }
465
+ return 'unknown';
466
+ }
467
+ logInboxSnapshot(event, extra = {}) {
468
+ logger.debug(event, {
469
+ channel: this.channelName,
470
+ connector_id: this.connectorId,
471
+ connector_state: this.state,
472
+ inbox_capacity: this.inboxCapacity,
473
+ inbox_remaining_capacity: this.inbox.remainingCapacity,
474
+ ...extra,
475
+ });
476
+ }
477
+ setTargetNodeId(nodeId) {
478
+ const normalized = InPageConnector.normalizeNodeId(nodeId);
479
+ if (!normalized) {
480
+ throw new Error('InPageConnector target node id must be a non-empty string');
481
+ }
482
+ if (normalized === '*') {
483
+ this.setWildcardTarget();
484
+ return;
485
+ }
486
+ this.targetNodeId = normalized;
487
+ logger.debug('inpage_target_updated', {
488
+ channel: this.channelName,
489
+ connector_id: this.connectorId,
490
+ local_node_id: this.localNodeId,
491
+ target_node_id: this.targetNodeId,
492
+ target_mode: 'direct',
493
+ });
494
+ }
495
+ setWildcardTarget() {
496
+ this.targetNodeId = '*';
497
+ logger.debug('inpage_target_updated', {
498
+ channel: this.channelName,
499
+ connector_id: this.connectorId,
500
+ local_node_id: this.localNodeId,
501
+ target_node_id: this.targetNodeId,
502
+ target_mode: 'wildcard',
503
+ });
504
+ }
310
505
  }
311
506
  exports.InPageConnector = InPageConnector;