@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
|
@@ -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
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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() {
|
package/dist/cjs/version.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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;
|