@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.
- package/dist/browser/index.cjs +318 -201
- package/dist/browser/index.mjs +318 -201
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +0 -173
- package/dist/cjs/naylence/fame/connector/inpage-connector-factory.js +36 -0
- package/dist/cjs/naylence/fame/connector/inpage-connector.js +213 -18
- package/dist/cjs/naylence/fame/connector/inpage-listener.js +67 -8
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +0 -173
- package/dist/esm/naylence/fame/connector/inpage-connector-factory.js +36 -0
- package/dist/esm/naylence/fame/connector/inpage-connector.js +213 -18
- package/dist/esm/naylence/fame/connector/inpage-listener.js +67 -8
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +318 -201
- package/dist/node/index.mjs +318 -201
- package/dist/node/node.cjs +318 -201
- package/dist/node/node.mjs +318 -201
- package/dist/types/naylence/fame/connector/broadcast-channel-connector.browser.d.ts +0 -12
- package/dist/types/naylence/fame/connector/inpage-connector-factory.d.ts +6 -0
- package/dist/types/naylence/fame/connector/inpage-connector.d.ts +13 -0
- package/dist/types/naylence/fame/connector/inpage-listener.d.ts +4 -0
- package/dist/types/naylence/fame/grants/inpage-connection-grant.d.ts +2 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -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'
|
|
94
|
-
|
|
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
|
-
|
|
103
|
-
|
|
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
|
-
|
|
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 (
|
|
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:
|
|
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
|
-
|
|
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;
|