@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.
@@ -282,7 +282,7 @@ class InPageListener extends transport_listener_js_1.TransportListener {
282
282
  node: routingNode,
283
283
  });
284
284
  const selection = grant_selection_policy_js_1.defaultGrantSelectionPolicy.selectCallbackGrant(selectionContext);
285
- connectorConfig = this._grantToConnectorConfig(selection.grant);
285
+ connectorConfig = this._buildConnectorConfigForSystem(systemId, this._grantToConnectorConfig(selection.grant));
286
286
  }
287
287
  catch (error) {
288
288
  logger.debug('inpage_listener_grant_selection_failed', {
@@ -290,13 +290,13 @@ class InPageListener extends transport_listener_js_1.TransportListener {
290
290
  system_id: systemId,
291
291
  error: error instanceof Error ? error.message : String(error),
292
292
  });
293
- connectorConfig =
294
- this._extractInPageConnectorConfig(frame) ??
295
- {
296
- type: inpage_connector_js_1.INPAGE_CONNECTOR_TYPE,
297
- channelName: this._channelName,
298
- inboxCapacity: this._inboxCapacity,
299
- };
293
+ const fallbackConfig = this._extractInPageConnectorConfig(frame) ??
294
+ {
295
+ type: inpage_connector_js_1.INPAGE_CONNECTOR_TYPE,
296
+ channelName: this._channelName,
297
+ inboxCapacity: this._inboxCapacity,
298
+ };
299
+ connectorConfig = this._buildConnectorConfigForSystem(systemId, fallbackConfig);
300
300
  }
301
301
  try {
302
302
  const connector = await routingNode.createOriginConnector({
@@ -415,6 +415,65 @@ class InPageListener extends transport_listener_js_1.TransportListener {
415
415
  typeof frame === 'object' &&
416
416
  frame.type === 'NodeAttach');
417
417
  }
418
+ _buildConnectorConfigForSystem(systemId, baseConfig) {
419
+ const localNodeId = this._requireLocalNodeId();
420
+ const targetSystemId = this._normalizeNodeId(systemId);
421
+ if (!targetSystemId) {
422
+ throw new Error('InPageListener requires a valid system id for connector creation');
423
+ }
424
+ const candidate = baseConfig ?? null;
425
+ const channelCandidate = candidate && 'channelName' in candidate
426
+ ? candidate.channelName
427
+ : undefined;
428
+ const inboxCandidate = candidate && 'inboxCapacity' in candidate
429
+ ? candidate.inboxCapacity
430
+ : undefined;
431
+ const targetCandidate = candidate && 'initialTargetNodeId' in candidate
432
+ ? candidate.initialTargetNodeId
433
+ : undefined;
434
+ const channelName = typeof channelCandidate === 'string' && channelCandidate.trim().length > 0
435
+ ? channelCandidate.trim()
436
+ : this._channelName;
437
+ const inboxCapacity = typeof inboxCandidate === 'number' &&
438
+ Number.isFinite(inboxCandidate) &&
439
+ inboxCandidate > 0
440
+ ? Math.floor(inboxCandidate)
441
+ : this._inboxCapacity;
442
+ const normalizedTarget = this._normalizeTargetNodeId(targetCandidate);
443
+ return {
444
+ type: inpage_connector_js_1.INPAGE_CONNECTOR_TYPE,
445
+ channelName,
446
+ inboxCapacity,
447
+ localNodeId,
448
+ initialTargetNodeId: normalizedTarget ?? targetSystemId,
449
+ };
450
+ }
451
+ _requireLocalNodeId() {
452
+ if (!this._routingNode) {
453
+ throw new Error('InPageListener requires routing node context');
454
+ }
455
+ const normalized = this._normalizeNodeId(this._routingNode.id);
456
+ if (!normalized) {
457
+ throw new Error('InPageListener requires routing node with a stable identifier');
458
+ }
459
+ return normalized;
460
+ }
461
+ _normalizeNodeId(value) {
462
+ if (typeof value !== 'string') {
463
+ return null;
464
+ }
465
+ const trimmed = value.trim();
466
+ return trimmed.length > 0 ? trimmed : null;
467
+ }
468
+ _normalizeTargetNodeId(value) {
469
+ if (value === undefined || value === null) {
470
+ return undefined;
471
+ }
472
+ if (value === '*') {
473
+ return '*';
474
+ }
475
+ return this._normalizeNodeId(value) ?? undefined;
476
+ }
418
477
  }
419
478
  exports.InPageListener = InPageListener;
420
479
  function getInPageListenerInstance() {
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  // This file is auto-generated during build - do not edit manually
3
- // Generated from package.json version: 0.3.5-test.965
3
+ // Generated from package.json version: 0.3.5-test.967
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.VERSION = void 0;
6
6
  /**
7
7
  * The package version, injected at build time.
8
8
  * @internal
9
9
  */
10
- exports.VERSION = '0.3.5-test.965';
10
+ exports.VERSION = '0.3.5-test.967';
@@ -70,11 +70,6 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
70
70
  ensureBroadcastEnvironment();
71
71
  super(baseConfig);
72
72
  this.listenerRegistered = false;
73
- this.seenAckKeys = new Map();
74
- this.seenAckOrder = [];
75
- this.ackDedupTtlMs = 30000;
76
- this.ackDedupMaxEntries = 4096;
77
- this.textDecoder = new TextDecoder();
78
73
  this.visibilityChangeListenerRegistered = false;
79
74
  this.channelName =
80
75
  typeof config.channelName === 'string' && config.channelName.trim().length > 0
@@ -166,9 +161,6 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
166
161
  connector_id: this.connectorId,
167
162
  payload_length: payload.byteLength,
168
163
  });
169
- if (this._shouldSkipDuplicateAck(senderNodeId, payload)) {
170
- return;
171
- }
172
164
  try {
173
165
  if (typeof this.inbox.tryEnqueue === 'function') {
174
166
  const accepted = this.inbox.tryEnqueue(payload);
@@ -272,9 +264,6 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
272
264
  }
273
265
  async pushToReceive(rawOrEnvelope) {
274
266
  const item = this._normalizeInboxItem(rawOrEnvelope);
275
- if (this._shouldSkipDuplicateAckFromInboxItem(item)) {
276
- return;
277
- }
278
267
  try {
279
268
  if (typeof this.inbox.tryEnqueue === 'function') {
280
269
  const accepted = this.inbox.tryEnqueue(item);
@@ -374,8 +363,6 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
374
363
  const closeReason = typeof reason === 'string' && reason.length > 0 ? reason : 'closed';
375
364
  const shutdownError = new FameTransportClose(closeReason, closeCode);
376
365
  this.inbox.drain(shutdownError);
377
- this.seenAckKeys.clear();
378
- this.seenAckOrder.length = 0;
379
366
  }
380
367
  _normalizeInboxItem(rawOrEnvelope) {
381
368
  if (rawOrEnvelope instanceof Uint8Array) {
@@ -452,125 +439,6 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
452
439
  ...extra,
453
440
  });
454
441
  }
455
- _shouldSkipDuplicateAck(senderId, payload) {
456
- const dedupKey = this._extractAckDedupKey(payload);
457
- if (!dedupKey) {
458
- return false;
459
- }
460
- const normalizedSenderId = typeof senderId === 'string' && senderId.length > 0
461
- ? senderId
462
- : undefined;
463
- if (normalizedSenderId && normalizedSenderId !== this.localNodeId) {
464
- logger.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
465
- channel: this.channelName,
466
- connector_id: this.connectorId,
467
- sender_id: normalizedSenderId,
468
- dedup_key: dedupKey,
469
- source: 'listener',
470
- });
471
- return false;
472
- }
473
- logger.debug('broadcast_channel_duplicate_ack_check', {
474
- channel: this.channelName,
475
- connector_id: this.connectorId,
476
- sender_id: normalizedSenderId ?? null,
477
- dedup_key: dedupKey,
478
- source: 'listener',
479
- cache_entries: this.seenAckKeys.size,
480
- });
481
- return this._checkDuplicateAck(dedupKey, normalizedSenderId);
482
- }
483
- _shouldSkipDuplicateAckFromInboxItem(item) {
484
- if (item instanceof Uint8Array) {
485
- return this._shouldSkipDuplicateAck(undefined, item);
486
- }
487
- const envelope = this._extractEnvelopeFromInboxItem(item);
488
- if (!envelope) {
489
- return false;
490
- }
491
- const frame = envelope.frame;
492
- if (!frame || frame.type !== 'DeliveryAck') {
493
- return false;
494
- }
495
- const refId = typeof frame.refId === 'string' && frame.refId.length > 0
496
- ? frame.refId
497
- : null;
498
- const dedupKey = refId ?? envelope.id ?? null;
499
- if (!dedupKey) {
500
- return false;
501
- }
502
- const senderId = this._extractSenderIdFromInboxItem(item);
503
- if (senderId && senderId !== this.localNodeId) {
504
- logger.debug('broadcast_channel_duplicate_ack_bypass_non_self', {
505
- channel: this.channelName,
506
- connector_id: this.connectorId,
507
- sender_id: senderId,
508
- dedup_key: dedupKey,
509
- source: 'inbox_item',
510
- });
511
- return false;
512
- }
513
- logger.debug('broadcast_channel_duplicate_ack_check', {
514
- channel: this.channelName,
515
- connector_id: this.connectorId,
516
- sender_id: senderId ?? null,
517
- dedup_key: dedupKey,
518
- source: 'inbox_item',
519
- cache_entries: this.seenAckKeys.size,
520
- });
521
- return this._checkDuplicateAck(dedupKey, senderId);
522
- }
523
- _checkDuplicateAck(dedupKey, senderId) {
524
- const now = Date.now();
525
- const lastSeen = this.seenAckKeys.get(dedupKey);
526
- if (lastSeen && now - lastSeen < this.ackDedupTtlMs) {
527
- logger.debug('broadcast_channel_duplicate_ack_suppressed', {
528
- channel: this.channelName,
529
- connector_id: this.connectorId,
530
- sender_id: senderId ?? null,
531
- dedup_key: dedupKey,
532
- age_ms: now - lastSeen,
533
- ttl_ms: this.ackDedupTtlMs,
534
- cache_entries: this.seenAckKeys.size,
535
- });
536
- return true;
537
- }
538
- this.seenAckKeys.set(dedupKey, now);
539
- this.seenAckOrder.push(dedupKey);
540
- logger.debug('broadcast_channel_duplicate_ack_recorded', {
541
- channel: this.channelName,
542
- connector_id: this.connectorId,
543
- sender_id: senderId ?? null,
544
- dedup_key: dedupKey,
545
- cache_entries: this.seenAckKeys.size,
546
- });
547
- this._trimSeenAcks(now);
548
- return false;
549
- }
550
- _extractEnvelopeFromInboxItem(item) {
551
- if (!item || typeof item !== 'object') {
552
- return null;
553
- }
554
- if ('envelope' in item) {
555
- return item.envelope;
556
- }
557
- if ('frame' in item) {
558
- return item;
559
- }
560
- return null;
561
- }
562
- _extractSenderIdFromInboxItem(item) {
563
- if (!item || typeof item !== 'object') {
564
- return undefined;
565
- }
566
- if ('context' in item) {
567
- const context = item.context;
568
- if (context && typeof context.fromSystemId === 'string') {
569
- return context.fromSystemId;
570
- }
571
- }
572
- return undefined;
573
- }
574
442
  /**
575
443
  * Override start() to check initial visibility state
576
444
  */
@@ -624,45 +492,4 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
624
492
  target_mode: 'wildcard',
625
493
  });
626
494
  }
627
- _trimSeenAcks(now) {
628
- while (this.seenAckOrder.length > 0) {
629
- const candidate = this.seenAckOrder[0];
630
- const timestamp = this.seenAckKeys.get(candidate);
631
- if (timestamp === undefined) {
632
- this.seenAckOrder.shift();
633
- continue;
634
- }
635
- if (this.seenAckKeys.size > this.ackDedupMaxEntries ||
636
- now - timestamp > this.ackDedupTtlMs) {
637
- this.seenAckKeys.delete(candidate);
638
- this.seenAckOrder.shift();
639
- continue;
640
- }
641
- break;
642
- }
643
- }
644
- _extractAckDedupKey(payload) {
645
- try {
646
- const decoded = this.textDecoder.decode(payload);
647
- const parsed = JSON.parse(decoded);
648
- const envelopeId = typeof parsed?.id === 'string' ? parsed.id : null;
649
- const frameType = parsed?.frame?.type;
650
- if (typeof frameType !== 'string' || frameType !== 'DeliveryAck') {
651
- return null;
652
- }
653
- const refId = parsed.frame?.refId;
654
- if (typeof refId === 'string' && refId.length > 0) {
655
- return refId;
656
- }
657
- return envelopeId;
658
- }
659
- catch (error) {
660
- logger.debug('broadcast_channel_ack_dedup_parse_failed', {
661
- channel: this.channelName,
662
- connector_id: this.connectorId,
663
- error: error instanceof Error ? error.message : String(error),
664
- });
665
- return null;
666
- }
667
- }
668
495
  }
@@ -65,8 +65,16 @@ export class InPageConnectorFactory extends ConnectorFactory {
65
65
  }
66
66
  const normalized = this._normalizeConfig(config);
67
67
  const options = (factoryArgs[0] ?? {});
68
+ const normalizedLocalNodeFromConfig = this._normalizeNodeId(normalized.localNodeId);
69
+ const localNodeId = this._normalizeNodeId(options.localNodeId) ?? normalizedLocalNodeFromConfig;
70
+ if (!localNodeId) {
71
+ throw new Error('InPageConnectorFactory requires a localNodeId from config or create() options');
72
+ }
68
73
  const channelName = normalized.channelName ?? DEFAULT_CHANNEL;
69
74
  const inboxCapacity = normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY;
75
+ const targetFromOptions = this._normalizeTargetNodeId(options.initialTargetNodeId);
76
+ const targetFromConfig = this._normalizeTargetNodeId(normalized.initialTargetNodeId);
77
+ const resolvedTarget = targetFromOptions ?? targetFromConfig ?? '*';
70
78
  const baseConfig = {
71
79
  drainTimeout: normalized.drainTimeout,
72
80
  flowControl: normalized.flowControl,
@@ -81,6 +89,8 @@ export class InPageConnectorFactory extends ConnectorFactory {
81
89
  type: INPAGE_CONNECTOR_TYPE,
82
90
  channelName,
83
91
  inboxCapacity,
92
+ localNodeId,
93
+ initialTargetNodeId: resolvedTarget,
84
94
  };
85
95
  const connector = new InPageConnector(connectorConfig, baseConfig);
86
96
  if (options.authorization) {
@@ -116,6 +126,16 @@ export class InPageConnectorFactory extends ConnectorFactory {
116
126
  capacity > 0) {
117
127
  normalized.inboxCapacity = Math.floor(capacity);
118
128
  }
129
+ const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
130
+ const normalizedLocalNodeId = this._normalizeNodeId(localNodeId);
131
+ if (normalizedLocalNodeId) {
132
+ normalized.localNodeId = normalizedLocalNodeId;
133
+ }
134
+ const initialTargetNodeId = candidate.initialTargetNodeId ?? candidate['initial_target_node_id'];
135
+ const normalizedTarget = this._normalizeTargetNodeId(initialTargetNodeId);
136
+ if (normalizedTarget) {
137
+ normalized.initialTargetNodeId = normalizedTarget;
138
+ }
119
139
  if (typeof candidate.flowControl === 'boolean') {
120
140
  normalized.flowControl = candidate.flowControl;
121
141
  }
@@ -154,5 +174,21 @@ export class InPageConnectorFactory extends ConnectorFactory {
154
174
  normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY;
155
175
  return normalized;
156
176
  }
177
+ _normalizeNodeId(value) {
178
+ if (typeof value !== 'string') {
179
+ return null;
180
+ }
181
+ const trimmed = value.trim();
182
+ return trimmed.length > 0 ? trimmed : null;
183
+ }
184
+ _normalizeTargetNodeId(value) {
185
+ if (value === undefined || value === null) {
186
+ return undefined;
187
+ }
188
+ if (value === '*') {
189
+ return '*';
190
+ }
191
+ return this._normalizeNodeId(value) ?? undefined;
192
+ }
157
193
  }
158
194
  export default InPageConnectorFactory;