@naylence/runtime 0.3.6-test.104 → 0.3.6-test.108
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 +20 -65
- package/dist/browser/index.mjs +20 -65
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector-factory.js +4 -0
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +1 -0
- package/dist/cjs/naylence/fame/connector/broadcast-channel-listener.js +9 -1
- package/dist/cjs/naylence/fame/delivery/default-delivery-tracker.js +4 -62
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +4 -0
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +1 -0
- package/dist/esm/naylence/fame/connector/broadcast-channel-listener.js +9 -1
- package/dist/esm/naylence/fame/delivery/default-delivery-tracker.js +4 -62
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +20 -65
- package/dist/node/index.mjs +20 -65
- package/dist/node/node.cjs +20 -65
- package/dist/node/node.mjs +20 -65
- package/dist/types/naylence/fame/connector/broadcast-channel-connector-factory.d.ts +1 -0
- package/dist/types/naylence/fame/delivery/default-delivery-tracker.d.ts +0 -6
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/browser/index.cjs
CHANGED
|
@@ -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.6-test.
|
|
101
|
+
// Generated from package.json version: 0.3.6-test.108
|
|
102
102
|
/**
|
|
103
103
|
* The package version, injected at build time.
|
|
104
104
|
* @internal
|
|
105
105
|
*/
|
|
106
|
-
const VERSION = '0.3.6-test.
|
|
106
|
+
const VERSION = '0.3.6-test.108';
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
109
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -7175,9 +7175,6 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7175
7175
|
this.ackDoneSince = new Map();
|
|
7176
7176
|
this.replyDoneSince = new Map();
|
|
7177
7177
|
this.pendingAckDispatches = new Set();
|
|
7178
|
-
this.recentlyHandled = new Map();
|
|
7179
|
-
this.recentlyHandledOrder = [];
|
|
7180
|
-
this.recentlyHandledTtlMs = 60000;
|
|
7181
7178
|
this.isPreparingToStop = false;
|
|
7182
7179
|
this.shutdownRequestedAtMs = null;
|
|
7183
7180
|
this.shutdownRetryGraceMs = 1000;
|
|
@@ -7399,22 +7396,6 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7399
7396
|
}
|
|
7400
7397
|
}
|
|
7401
7398
|
else {
|
|
7402
|
-
const wasRecentlyHandled = await this.lock.runExclusive(async () => this.wasRecentlyHandled(envelope.id));
|
|
7403
|
-
if (wasRecentlyHandled) {
|
|
7404
|
-
logger$12.debug('tracker_duplicate_envelope_recently_handled', {
|
|
7405
|
-
envp_id: envelope.id,
|
|
7406
|
-
});
|
|
7407
|
-
return new TrackedEnvelope({
|
|
7408
|
-
timeoutAtMs: 0,
|
|
7409
|
-
overallTimeoutAtMs: 0,
|
|
7410
|
-
expectedResponseType: envelope.rtype ?? core.FameResponseType.NONE,
|
|
7411
|
-
createdAtMs: Date.now(),
|
|
7412
|
-
status: EnvelopeStatus.HANDLED,
|
|
7413
|
-
mailboxType: MailboxType.INBOX,
|
|
7414
|
-
originalEnvelope: envelope,
|
|
7415
|
-
serviceName: inboxName,
|
|
7416
|
-
});
|
|
7417
|
-
}
|
|
7418
7399
|
tracked = new TrackedEnvelope({
|
|
7419
7400
|
timeoutAtMs: 0,
|
|
7420
7401
|
overallTimeoutAtMs: 0,
|
|
@@ -7436,12 +7417,8 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7436
7417
|
async onEnvelopeHandled(envelope) {
|
|
7437
7418
|
const inbox = this.ensureInbox();
|
|
7438
7419
|
envelope.status = EnvelopeStatus.HANDLED;
|
|
7420
|
+
// Delete the envelope from inbox to prevent growth
|
|
7439
7421
|
await inbox.delete(envelope.originalEnvelope.id);
|
|
7440
|
-
await this.lock.runExclusive(async () => {
|
|
7441
|
-
this.markRecentlyHandled(envelope.originalEnvelope.id);
|
|
7442
|
-
});
|
|
7443
|
-
// Preserve handled envelope to prevent duplicate redelivery during shutdown drains.
|
|
7444
|
-
// await inbox.set(envelope.originalEnvelope.id, envelope);
|
|
7445
7422
|
}
|
|
7446
7423
|
async onEnvelopeHandleFailed(inboxName, envelope, context, error, isFinalFailure = false) {
|
|
7447
7424
|
const inbox = this.ensureInbox();
|
|
@@ -7656,9 +7633,9 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7656
7633
|
});
|
|
7657
7634
|
await this.markDoneSince(this.replyFutures, trackedEnvelope.originalEnvelope.id, this.replyDoneSince);
|
|
7658
7635
|
await this.markDoneSince(this.ackFutures, trackedEnvelope.originalEnvelope.id, this.ackDoneSince);
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7636
|
+
// Note: ACK is already sent in onCorrelatedMessage (lines 655-657)
|
|
7637
|
+
// when the reply envelope is first delivered. No need to send it again here.
|
|
7638
|
+
// Removing this duplicate sendAck call fixes the duplicate DeliveryAck bug.
|
|
7662
7639
|
for (const handler of this.eventHandlers) {
|
|
7663
7640
|
await handler.onEnvelopeReplied?.(trackedEnvelope, envelope);
|
|
7664
7641
|
}
|
|
@@ -7808,8 +7785,6 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7808
7785
|
}
|
|
7809
7786
|
this.streamDone.clear();
|
|
7810
7787
|
this.correlationToEnvelope.clear();
|
|
7811
|
-
this.recentlyHandled.clear();
|
|
7812
|
-
this.recentlyHandledOrder.length = 0;
|
|
7813
7788
|
return values;
|
|
7814
7789
|
});
|
|
7815
7790
|
for (const timer of timers) {
|
|
@@ -8391,39 +8366,6 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
8391
8366
|
this.pendingAckDispatches.delete(ackDispatch);
|
|
8392
8367
|
}
|
|
8393
8368
|
}
|
|
8394
|
-
markRecentlyHandled(envelopeId) {
|
|
8395
|
-
const now = Date.now();
|
|
8396
|
-
this.recentlyHandled.set(envelopeId, now);
|
|
8397
|
-
this.recentlyHandledOrder.push(envelopeId);
|
|
8398
|
-
this.trimRecentlyHandled(now);
|
|
8399
|
-
}
|
|
8400
|
-
wasRecentlyHandled(envelopeId) {
|
|
8401
|
-
const now = Date.now();
|
|
8402
|
-
const timestamp = this.recentlyHandled.get(envelopeId);
|
|
8403
|
-
if (timestamp === undefined) {
|
|
8404
|
-
return false;
|
|
8405
|
-
}
|
|
8406
|
-
if (now - timestamp > this.recentlyHandledTtlMs) {
|
|
8407
|
-
this.recentlyHandled.delete(envelopeId);
|
|
8408
|
-
return false;
|
|
8409
|
-
}
|
|
8410
|
-
return true;
|
|
8411
|
-
}
|
|
8412
|
-
trimRecentlyHandled(now) {
|
|
8413
|
-
while (this.recentlyHandledOrder.length > 0) {
|
|
8414
|
-
const candidate = this.recentlyHandledOrder[0];
|
|
8415
|
-
const timestamp = this.recentlyHandled.get(candidate);
|
|
8416
|
-
if (timestamp === undefined) {
|
|
8417
|
-
this.recentlyHandledOrder.shift();
|
|
8418
|
-
continue;
|
|
8419
|
-
}
|
|
8420
|
-
if (now - timestamp <= this.recentlyHandledTtlMs) {
|
|
8421
|
-
break;
|
|
8422
|
-
}
|
|
8423
|
-
this.recentlyHandled.delete(candidate);
|
|
8424
|
-
this.recentlyHandledOrder.shift();
|
|
8425
|
-
}
|
|
8426
|
-
}
|
|
8427
8369
|
getShutdownRetryDeferDelay(nowMs) {
|
|
8428
8370
|
if (!this.isPreparingToStop || this.shutdownRequestedAtMs === null) {
|
|
8429
8371
|
return null;
|
|
@@ -9996,6 +9938,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9996
9938
|
local_node_id: this.localNodeId,
|
|
9997
9939
|
target_node_id: this.targetNodeId ?? null,
|
|
9998
9940
|
inbox_capacity: preferredCapacity,
|
|
9941
|
+
passive: config.passive ?? false,
|
|
9999
9942
|
timestamp: new Date().toISOString(),
|
|
10000
9943
|
});
|
|
10001
9944
|
this.onMsg = (event) => {
|
|
@@ -29229,6 +29172,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
29229
29172
|
inboxCapacity,
|
|
29230
29173
|
localNodeId,
|
|
29231
29174
|
initialTargetNodeId: resolvedTarget,
|
|
29175
|
+
passive: normalized.passive,
|
|
29232
29176
|
};
|
|
29233
29177
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
29234
29178
|
if (options.authorization) {
|
|
@@ -29267,6 +29211,9 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
29267
29211
|
if (normalizedLocalNodeId) {
|
|
29268
29212
|
normalized.localNodeId = normalizedLocalNodeId;
|
|
29269
29213
|
}
|
|
29214
|
+
if (typeof candidate.passive === 'boolean') {
|
|
29215
|
+
normalized.passive = candidate.passive;
|
|
29216
|
+
}
|
|
29270
29217
|
if (typeof candidate.flowControl === 'boolean') {
|
|
29271
29218
|
normalized.flowControl = candidate.flowControl;
|
|
29272
29219
|
}
|
|
@@ -30610,11 +30557,19 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
30610
30557
|
? Math.floor(initialWindowCandidate)
|
|
30611
30558
|
: undefined;
|
|
30612
30559
|
const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
|
|
30560
|
+
const passive = typeof passiveCandidate === 'boolean' ? passiveCandidate : true;
|
|
30561
|
+
logger$o.debug('broadcast_channel_listener_building_connector_config', {
|
|
30562
|
+
system_id: systemId,
|
|
30563
|
+
channel_name: channelName,
|
|
30564
|
+
passive,
|
|
30565
|
+
has_base_config: !!baseConfig,
|
|
30566
|
+
passive_candidate: passiveCandidate,
|
|
30567
|
+
});
|
|
30613
30568
|
return {
|
|
30614
30569
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
30615
30570
|
channelName,
|
|
30616
30571
|
inboxCapacity,
|
|
30617
|
-
passive
|
|
30572
|
+
passive,
|
|
30618
30573
|
initialWindow,
|
|
30619
30574
|
localNodeId,
|
|
30620
30575
|
initialTargetNodeId,
|
package/dist/browser/index.mjs
CHANGED
|
@@ -96,12 +96,12 @@ installProcessEnvShim();
|
|
|
96
96
|
// --- END ENV SHIM ---
|
|
97
97
|
|
|
98
98
|
// This file is auto-generated during build - do not edit manually
|
|
99
|
-
// Generated from package.json version: 0.3.6-test.
|
|
99
|
+
// Generated from package.json version: 0.3.6-test.108
|
|
100
100
|
/**
|
|
101
101
|
* The package version, injected at build time.
|
|
102
102
|
* @internal
|
|
103
103
|
*/
|
|
104
|
-
const VERSION = '0.3.6-test.
|
|
104
|
+
const VERSION = '0.3.6-test.108';
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -7173,9 +7173,6 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7173
7173
|
this.ackDoneSince = new Map();
|
|
7174
7174
|
this.replyDoneSince = new Map();
|
|
7175
7175
|
this.pendingAckDispatches = new Set();
|
|
7176
|
-
this.recentlyHandled = new Map();
|
|
7177
|
-
this.recentlyHandledOrder = [];
|
|
7178
|
-
this.recentlyHandledTtlMs = 60000;
|
|
7179
7176
|
this.isPreparingToStop = false;
|
|
7180
7177
|
this.shutdownRequestedAtMs = null;
|
|
7181
7178
|
this.shutdownRetryGraceMs = 1000;
|
|
@@ -7397,22 +7394,6 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7397
7394
|
}
|
|
7398
7395
|
}
|
|
7399
7396
|
else {
|
|
7400
|
-
const wasRecentlyHandled = await this.lock.runExclusive(async () => this.wasRecentlyHandled(envelope.id));
|
|
7401
|
-
if (wasRecentlyHandled) {
|
|
7402
|
-
logger$12.debug('tracker_duplicate_envelope_recently_handled', {
|
|
7403
|
-
envp_id: envelope.id,
|
|
7404
|
-
});
|
|
7405
|
-
return new TrackedEnvelope({
|
|
7406
|
-
timeoutAtMs: 0,
|
|
7407
|
-
overallTimeoutAtMs: 0,
|
|
7408
|
-
expectedResponseType: envelope.rtype ?? FameResponseType.NONE,
|
|
7409
|
-
createdAtMs: Date.now(),
|
|
7410
|
-
status: EnvelopeStatus.HANDLED,
|
|
7411
|
-
mailboxType: MailboxType.INBOX,
|
|
7412
|
-
originalEnvelope: envelope,
|
|
7413
|
-
serviceName: inboxName,
|
|
7414
|
-
});
|
|
7415
|
-
}
|
|
7416
7397
|
tracked = new TrackedEnvelope({
|
|
7417
7398
|
timeoutAtMs: 0,
|
|
7418
7399
|
overallTimeoutAtMs: 0,
|
|
@@ -7434,12 +7415,8 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7434
7415
|
async onEnvelopeHandled(envelope) {
|
|
7435
7416
|
const inbox = this.ensureInbox();
|
|
7436
7417
|
envelope.status = EnvelopeStatus.HANDLED;
|
|
7418
|
+
// Delete the envelope from inbox to prevent growth
|
|
7437
7419
|
await inbox.delete(envelope.originalEnvelope.id);
|
|
7438
|
-
await this.lock.runExclusive(async () => {
|
|
7439
|
-
this.markRecentlyHandled(envelope.originalEnvelope.id);
|
|
7440
|
-
});
|
|
7441
|
-
// Preserve handled envelope to prevent duplicate redelivery during shutdown drains.
|
|
7442
|
-
// await inbox.set(envelope.originalEnvelope.id, envelope);
|
|
7443
7420
|
}
|
|
7444
7421
|
async onEnvelopeHandleFailed(inboxName, envelope, context, error, isFinalFailure = false) {
|
|
7445
7422
|
const inbox = this.ensureInbox();
|
|
@@ -7654,9 +7631,9 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7654
7631
|
});
|
|
7655
7632
|
await this.markDoneSince(this.replyFutures, trackedEnvelope.originalEnvelope.id, this.replyDoneSince);
|
|
7656
7633
|
await this.markDoneSince(this.ackFutures, trackedEnvelope.originalEnvelope.id, this.ackDoneSince);
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7634
|
+
// Note: ACK is already sent in onCorrelatedMessage (lines 655-657)
|
|
7635
|
+
// when the reply envelope is first delivered. No need to send it again here.
|
|
7636
|
+
// Removing this duplicate sendAck call fixes the duplicate DeliveryAck bug.
|
|
7660
7637
|
for (const handler of this.eventHandlers) {
|
|
7661
7638
|
await handler.onEnvelopeReplied?.(trackedEnvelope, envelope);
|
|
7662
7639
|
}
|
|
@@ -7806,8 +7783,6 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
7806
7783
|
}
|
|
7807
7784
|
this.streamDone.clear();
|
|
7808
7785
|
this.correlationToEnvelope.clear();
|
|
7809
|
-
this.recentlyHandled.clear();
|
|
7810
|
-
this.recentlyHandledOrder.length = 0;
|
|
7811
7786
|
return values;
|
|
7812
7787
|
});
|
|
7813
7788
|
for (const timer of timers) {
|
|
@@ -8389,39 +8364,6 @@ class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
8389
8364
|
this.pendingAckDispatches.delete(ackDispatch);
|
|
8390
8365
|
}
|
|
8391
8366
|
}
|
|
8392
|
-
markRecentlyHandled(envelopeId) {
|
|
8393
|
-
const now = Date.now();
|
|
8394
|
-
this.recentlyHandled.set(envelopeId, now);
|
|
8395
|
-
this.recentlyHandledOrder.push(envelopeId);
|
|
8396
|
-
this.trimRecentlyHandled(now);
|
|
8397
|
-
}
|
|
8398
|
-
wasRecentlyHandled(envelopeId) {
|
|
8399
|
-
const now = Date.now();
|
|
8400
|
-
const timestamp = this.recentlyHandled.get(envelopeId);
|
|
8401
|
-
if (timestamp === undefined) {
|
|
8402
|
-
return false;
|
|
8403
|
-
}
|
|
8404
|
-
if (now - timestamp > this.recentlyHandledTtlMs) {
|
|
8405
|
-
this.recentlyHandled.delete(envelopeId);
|
|
8406
|
-
return false;
|
|
8407
|
-
}
|
|
8408
|
-
return true;
|
|
8409
|
-
}
|
|
8410
|
-
trimRecentlyHandled(now) {
|
|
8411
|
-
while (this.recentlyHandledOrder.length > 0) {
|
|
8412
|
-
const candidate = this.recentlyHandledOrder[0];
|
|
8413
|
-
const timestamp = this.recentlyHandled.get(candidate);
|
|
8414
|
-
if (timestamp === undefined) {
|
|
8415
|
-
this.recentlyHandledOrder.shift();
|
|
8416
|
-
continue;
|
|
8417
|
-
}
|
|
8418
|
-
if (now - timestamp <= this.recentlyHandledTtlMs) {
|
|
8419
|
-
break;
|
|
8420
|
-
}
|
|
8421
|
-
this.recentlyHandled.delete(candidate);
|
|
8422
|
-
this.recentlyHandledOrder.shift();
|
|
8423
|
-
}
|
|
8424
|
-
}
|
|
8425
8367
|
getShutdownRetryDeferDelay(nowMs) {
|
|
8426
8368
|
if (!this.isPreparingToStop || this.shutdownRequestedAtMs === null) {
|
|
8427
8369
|
return null;
|
|
@@ -9994,6 +9936,7 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9994
9936
|
local_node_id: this.localNodeId,
|
|
9995
9937
|
target_node_id: this.targetNodeId ?? null,
|
|
9996
9938
|
inbox_capacity: preferredCapacity,
|
|
9939
|
+
passive: config.passive ?? false,
|
|
9997
9940
|
timestamp: new Date().toISOString(),
|
|
9998
9941
|
});
|
|
9999
9942
|
this.onMsg = (event) => {
|
|
@@ -29227,6 +29170,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
29227
29170
|
inboxCapacity,
|
|
29228
29171
|
localNodeId,
|
|
29229
29172
|
initialTargetNodeId: resolvedTarget,
|
|
29173
|
+
passive: normalized.passive,
|
|
29230
29174
|
};
|
|
29231
29175
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
29232
29176
|
if (options.authorization) {
|
|
@@ -29265,6 +29209,9 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
29265
29209
|
if (normalizedLocalNodeId) {
|
|
29266
29210
|
normalized.localNodeId = normalizedLocalNodeId;
|
|
29267
29211
|
}
|
|
29212
|
+
if (typeof candidate.passive === 'boolean') {
|
|
29213
|
+
normalized.passive = candidate.passive;
|
|
29214
|
+
}
|
|
29268
29215
|
if (typeof candidate.flowControl === 'boolean') {
|
|
29269
29216
|
normalized.flowControl = candidate.flowControl;
|
|
29270
29217
|
}
|
|
@@ -30608,11 +30555,19 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
30608
30555
|
? Math.floor(initialWindowCandidate)
|
|
30609
30556
|
: undefined;
|
|
30610
30557
|
const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
|
|
30558
|
+
const passive = typeof passiveCandidate === 'boolean' ? passiveCandidate : true;
|
|
30559
|
+
logger$o.debug('broadcast_channel_listener_building_connector_config', {
|
|
30560
|
+
system_id: systemId,
|
|
30561
|
+
channel_name: channelName,
|
|
30562
|
+
passive,
|
|
30563
|
+
has_base_config: !!baseConfig,
|
|
30564
|
+
passive_candidate: passiveCandidate,
|
|
30565
|
+
});
|
|
30611
30566
|
return {
|
|
30612
30567
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
30613
30568
|
channelName,
|
|
30614
30569
|
inboxCapacity,
|
|
30615
|
-
passive
|
|
30570
|
+
passive,
|
|
30616
30571
|
initialWindow,
|
|
30617
30572
|
localNodeId,
|
|
30618
30573
|
initialTargetNodeId,
|
|
@@ -101,6 +101,7 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
101
101
|
inboxCapacity,
|
|
102
102
|
localNodeId,
|
|
103
103
|
initialTargetNodeId: resolvedTarget,
|
|
104
|
+
passive: normalized.passive,
|
|
104
105
|
};
|
|
105
106
|
const connector = new broadcast_channel_connector_js_1.BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
106
107
|
if (options.authorization) {
|
|
@@ -139,6 +140,9 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
139
140
|
if (normalizedLocalNodeId) {
|
|
140
141
|
normalized.localNodeId = normalizedLocalNodeId;
|
|
141
142
|
}
|
|
143
|
+
if (typeof candidate.passive === 'boolean') {
|
|
144
|
+
normalized.passive = candidate.passive;
|
|
145
|
+
}
|
|
142
146
|
if (typeof candidate.flowControl === 'boolean') {
|
|
143
147
|
normalized.flowControl = candidate.flowControl;
|
|
144
148
|
}
|
|
@@ -99,6 +99,7 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
99
99
|
local_node_id: this.localNodeId,
|
|
100
100
|
target_node_id: this.targetNodeId ?? null,
|
|
101
101
|
inbox_capacity: preferredCapacity,
|
|
102
|
+
passive: config.passive ?? false,
|
|
102
103
|
timestamp: new Date().toISOString(),
|
|
103
104
|
});
|
|
104
105
|
this.onMsg = (event) => {
|
|
@@ -455,11 +455,19 @@ class BroadcastChannelListener extends transport_listener_js_1.TransportListener
|
|
|
455
455
|
? Math.floor(initialWindowCandidate)
|
|
456
456
|
: undefined;
|
|
457
457
|
const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
|
|
458
|
+
const passive = typeof passiveCandidate === 'boolean' ? passiveCandidate : true;
|
|
459
|
+
logger.debug('broadcast_channel_listener_building_connector_config', {
|
|
460
|
+
system_id: systemId,
|
|
461
|
+
channel_name: channelName,
|
|
462
|
+
passive,
|
|
463
|
+
has_base_config: !!baseConfig,
|
|
464
|
+
passive_candidate: passiveCandidate,
|
|
465
|
+
});
|
|
458
466
|
return {
|
|
459
467
|
type: broadcast_channel_connector_js_1.BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
460
468
|
channelName,
|
|
461
469
|
inboxCapacity,
|
|
462
|
-
passive
|
|
470
|
+
passive,
|
|
463
471
|
initialWindow,
|
|
464
472
|
localNodeId,
|
|
465
473
|
initialTargetNodeId,
|
|
@@ -149,9 +149,6 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
149
149
|
this.ackDoneSince = new Map();
|
|
150
150
|
this.replyDoneSince = new Map();
|
|
151
151
|
this.pendingAckDispatches = new Set();
|
|
152
|
-
this.recentlyHandled = new Map();
|
|
153
|
-
this.recentlyHandledOrder = [];
|
|
154
|
-
this.recentlyHandledTtlMs = 60000;
|
|
155
152
|
this.isPreparingToStop = false;
|
|
156
153
|
this.shutdownRequestedAtMs = null;
|
|
157
154
|
this.shutdownRetryGraceMs = 1000;
|
|
@@ -387,22 +384,6 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
387
384
|
}
|
|
388
385
|
}
|
|
389
386
|
else {
|
|
390
|
-
const wasRecentlyHandled = await this.lock.runExclusive(async () => this.wasRecentlyHandled(envelope.id));
|
|
391
|
-
if (wasRecentlyHandled) {
|
|
392
|
-
logger.debug('tracker_duplicate_envelope_recently_handled', {
|
|
393
|
-
envp_id: envelope.id,
|
|
394
|
-
});
|
|
395
|
-
return new tracked_envelope_js_1.TrackedEnvelope({
|
|
396
|
-
timeoutAtMs: 0,
|
|
397
|
-
overallTimeoutAtMs: 0,
|
|
398
|
-
expectedResponseType: envelope.rtype ?? core_1.FameResponseType.NONE,
|
|
399
|
-
createdAtMs: Date.now(),
|
|
400
|
-
status: tracked_envelope_js_1.EnvelopeStatus.HANDLED,
|
|
401
|
-
mailboxType: tracked_envelope_js_1.MailboxType.INBOX,
|
|
402
|
-
originalEnvelope: envelope,
|
|
403
|
-
serviceName: inboxName,
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
387
|
tracked = new tracked_envelope_js_1.TrackedEnvelope({
|
|
407
388
|
timeoutAtMs: 0,
|
|
408
389
|
overallTimeoutAtMs: 0,
|
|
@@ -424,12 +405,8 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
424
405
|
async onEnvelopeHandled(envelope) {
|
|
425
406
|
const inbox = this.ensureInbox();
|
|
426
407
|
envelope.status = tracked_envelope_js_1.EnvelopeStatus.HANDLED;
|
|
408
|
+
// Delete the envelope from inbox to prevent growth
|
|
427
409
|
await inbox.delete(envelope.originalEnvelope.id);
|
|
428
|
-
await this.lock.runExclusive(async () => {
|
|
429
|
-
this.markRecentlyHandled(envelope.originalEnvelope.id);
|
|
430
|
-
});
|
|
431
|
-
// Preserve handled envelope to prevent duplicate redelivery during shutdown drains.
|
|
432
|
-
// await inbox.set(envelope.originalEnvelope.id, envelope);
|
|
433
410
|
}
|
|
434
411
|
async onEnvelopeHandleFailed(inboxName, envelope, context, error, isFinalFailure = false) {
|
|
435
412
|
void context;
|
|
@@ -648,9 +625,9 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
648
625
|
});
|
|
649
626
|
await this.markDoneSince(this.replyFutures, trackedEnvelope.originalEnvelope.id, this.replyDoneSince);
|
|
650
627
|
await this.markDoneSince(this.ackFutures, trackedEnvelope.originalEnvelope.id, this.ackDoneSince);
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
628
|
+
// Note: ACK is already sent in onCorrelatedMessage (lines 655-657)
|
|
629
|
+
// when the reply envelope is first delivered. No need to send it again here.
|
|
630
|
+
// Removing this duplicate sendAck call fixes the duplicate DeliveryAck bug.
|
|
654
631
|
for (const handler of this.eventHandlers) {
|
|
655
632
|
await handler.onEnvelopeReplied?.(trackedEnvelope, envelope);
|
|
656
633
|
}
|
|
@@ -800,8 +777,6 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
800
777
|
}
|
|
801
778
|
this.streamDone.clear();
|
|
802
779
|
this.correlationToEnvelope.clear();
|
|
803
|
-
this.recentlyHandled.clear();
|
|
804
|
-
this.recentlyHandledOrder.length = 0;
|
|
805
780
|
return values;
|
|
806
781
|
});
|
|
807
782
|
for (const timer of timers) {
|
|
@@ -1383,39 +1358,6 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
1383
1358
|
this.pendingAckDispatches.delete(ackDispatch);
|
|
1384
1359
|
}
|
|
1385
1360
|
}
|
|
1386
|
-
markRecentlyHandled(envelopeId) {
|
|
1387
|
-
const now = Date.now();
|
|
1388
|
-
this.recentlyHandled.set(envelopeId, now);
|
|
1389
|
-
this.recentlyHandledOrder.push(envelopeId);
|
|
1390
|
-
this.trimRecentlyHandled(now);
|
|
1391
|
-
}
|
|
1392
|
-
wasRecentlyHandled(envelopeId) {
|
|
1393
|
-
const now = Date.now();
|
|
1394
|
-
const timestamp = this.recentlyHandled.get(envelopeId);
|
|
1395
|
-
if (timestamp === undefined) {
|
|
1396
|
-
return false;
|
|
1397
|
-
}
|
|
1398
|
-
if (now - timestamp > this.recentlyHandledTtlMs) {
|
|
1399
|
-
this.recentlyHandled.delete(envelopeId);
|
|
1400
|
-
return false;
|
|
1401
|
-
}
|
|
1402
|
-
return true;
|
|
1403
|
-
}
|
|
1404
|
-
trimRecentlyHandled(now) {
|
|
1405
|
-
while (this.recentlyHandledOrder.length > 0) {
|
|
1406
|
-
const candidate = this.recentlyHandledOrder[0];
|
|
1407
|
-
const timestamp = this.recentlyHandled.get(candidate);
|
|
1408
|
-
if (timestamp === undefined) {
|
|
1409
|
-
this.recentlyHandledOrder.shift();
|
|
1410
|
-
continue;
|
|
1411
|
-
}
|
|
1412
|
-
if (now - timestamp <= this.recentlyHandledTtlMs) {
|
|
1413
|
-
break;
|
|
1414
|
-
}
|
|
1415
|
-
this.recentlyHandled.delete(candidate);
|
|
1416
|
-
this.recentlyHandledOrder.shift();
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
1361
|
getShutdownRetryDeferDelay(nowMs) {
|
|
1420
1362
|
if (!this.isPreparingToStop || this.shutdownRequestedAtMs === null) {
|
|
1421
1363
|
return null;
|
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.6-test.
|
|
3
|
+
// Generated from package.json version: 0.3.6-test.108
|
|
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.6-test.
|
|
10
|
+
exports.VERSION = '0.3.6-test.108';
|
|
@@ -98,6 +98,7 @@ export class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
98
98
|
inboxCapacity,
|
|
99
99
|
localNodeId,
|
|
100
100
|
initialTargetNodeId: resolvedTarget,
|
|
101
|
+
passive: normalized.passive,
|
|
101
102
|
};
|
|
102
103
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
103
104
|
if (options.authorization) {
|
|
@@ -136,6 +137,9 @@ export class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
136
137
|
if (normalizedLocalNodeId) {
|
|
137
138
|
normalized.localNodeId = normalizedLocalNodeId;
|
|
138
139
|
}
|
|
140
|
+
if (typeof candidate.passive === 'boolean') {
|
|
141
|
+
normalized.passive = candidate.passive;
|
|
142
|
+
}
|
|
139
143
|
if (typeof candidate.flowControl === 'boolean') {
|
|
140
144
|
normalized.flowControl = candidate.flowControl;
|
|
141
145
|
}
|
|
@@ -96,6 +96,7 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
|
|
|
96
96
|
local_node_id: this.localNodeId,
|
|
97
97
|
target_node_id: this.targetNodeId ?? null,
|
|
98
98
|
inbox_capacity: preferredCapacity,
|
|
99
|
+
passive: config.passive ?? false,
|
|
99
100
|
timestamp: new Date().toISOString(),
|
|
100
101
|
});
|
|
101
102
|
this.onMsg = (event) => {
|
|
@@ -451,11 +451,19 @@ export class BroadcastChannelListener extends TransportListener {
|
|
|
451
451
|
? Math.floor(initialWindowCandidate)
|
|
452
452
|
: undefined;
|
|
453
453
|
const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
|
|
454
|
+
const passive = typeof passiveCandidate === 'boolean' ? passiveCandidate : true;
|
|
455
|
+
logger.debug('broadcast_channel_listener_building_connector_config', {
|
|
456
|
+
system_id: systemId,
|
|
457
|
+
channel_name: channelName,
|
|
458
|
+
passive,
|
|
459
|
+
has_base_config: !!baseConfig,
|
|
460
|
+
passive_candidate: passiveCandidate,
|
|
461
|
+
});
|
|
454
462
|
return {
|
|
455
463
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
456
464
|
channelName,
|
|
457
465
|
inboxCapacity,
|
|
458
|
-
passive
|
|
466
|
+
passive,
|
|
459
467
|
initialWindow,
|
|
460
468
|
localNodeId,
|
|
461
469
|
initialTargetNodeId,
|
|
@@ -146,9 +146,6 @@ export class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
146
146
|
this.ackDoneSince = new Map();
|
|
147
147
|
this.replyDoneSince = new Map();
|
|
148
148
|
this.pendingAckDispatches = new Set();
|
|
149
|
-
this.recentlyHandled = new Map();
|
|
150
|
-
this.recentlyHandledOrder = [];
|
|
151
|
-
this.recentlyHandledTtlMs = 60000;
|
|
152
149
|
this.isPreparingToStop = false;
|
|
153
150
|
this.shutdownRequestedAtMs = null;
|
|
154
151
|
this.shutdownRetryGraceMs = 1000;
|
|
@@ -384,22 +381,6 @@ export class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
384
381
|
}
|
|
385
382
|
}
|
|
386
383
|
else {
|
|
387
|
-
const wasRecentlyHandled = await this.lock.runExclusive(async () => this.wasRecentlyHandled(envelope.id));
|
|
388
|
-
if (wasRecentlyHandled) {
|
|
389
|
-
logger.debug('tracker_duplicate_envelope_recently_handled', {
|
|
390
|
-
envp_id: envelope.id,
|
|
391
|
-
});
|
|
392
|
-
return new TrackedEnvelope({
|
|
393
|
-
timeoutAtMs: 0,
|
|
394
|
-
overallTimeoutAtMs: 0,
|
|
395
|
-
expectedResponseType: envelope.rtype ?? FameResponseType.NONE,
|
|
396
|
-
createdAtMs: Date.now(),
|
|
397
|
-
status: EnvelopeStatus.HANDLED,
|
|
398
|
-
mailboxType: MailboxType.INBOX,
|
|
399
|
-
originalEnvelope: envelope,
|
|
400
|
-
serviceName: inboxName,
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
384
|
tracked = new TrackedEnvelope({
|
|
404
385
|
timeoutAtMs: 0,
|
|
405
386
|
overallTimeoutAtMs: 0,
|
|
@@ -421,12 +402,8 @@ export class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
421
402
|
async onEnvelopeHandled(envelope) {
|
|
422
403
|
const inbox = this.ensureInbox();
|
|
423
404
|
envelope.status = EnvelopeStatus.HANDLED;
|
|
405
|
+
// Delete the envelope from inbox to prevent growth
|
|
424
406
|
await inbox.delete(envelope.originalEnvelope.id);
|
|
425
|
-
await this.lock.runExclusive(async () => {
|
|
426
|
-
this.markRecentlyHandled(envelope.originalEnvelope.id);
|
|
427
|
-
});
|
|
428
|
-
// Preserve handled envelope to prevent duplicate redelivery during shutdown drains.
|
|
429
|
-
// await inbox.set(envelope.originalEnvelope.id, envelope);
|
|
430
407
|
}
|
|
431
408
|
async onEnvelopeHandleFailed(inboxName, envelope, context, error, isFinalFailure = false) {
|
|
432
409
|
void context;
|
|
@@ -645,9 +622,9 @@ export class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
645
622
|
});
|
|
646
623
|
await this.markDoneSince(this.replyFutures, trackedEnvelope.originalEnvelope.id, this.replyDoneSince);
|
|
647
624
|
await this.markDoneSince(this.ackFutures, trackedEnvelope.originalEnvelope.id, this.ackDoneSince);
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
625
|
+
// Note: ACK is already sent in onCorrelatedMessage (lines 655-657)
|
|
626
|
+
// when the reply envelope is first delivered. No need to send it again here.
|
|
627
|
+
// Removing this duplicate sendAck call fixes the duplicate DeliveryAck bug.
|
|
651
628
|
for (const handler of this.eventHandlers) {
|
|
652
629
|
await handler.onEnvelopeReplied?.(trackedEnvelope, envelope);
|
|
653
630
|
}
|
|
@@ -797,8 +774,6 @@ export class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
797
774
|
}
|
|
798
775
|
this.streamDone.clear();
|
|
799
776
|
this.correlationToEnvelope.clear();
|
|
800
|
-
this.recentlyHandled.clear();
|
|
801
|
-
this.recentlyHandledOrder.length = 0;
|
|
802
777
|
return values;
|
|
803
778
|
});
|
|
804
779
|
for (const timer of timers) {
|
|
@@ -1380,39 +1355,6 @@ export class DefaultDeliveryTracker extends TaskSpawner {
|
|
|
1380
1355
|
this.pendingAckDispatches.delete(ackDispatch);
|
|
1381
1356
|
}
|
|
1382
1357
|
}
|
|
1383
|
-
markRecentlyHandled(envelopeId) {
|
|
1384
|
-
const now = Date.now();
|
|
1385
|
-
this.recentlyHandled.set(envelopeId, now);
|
|
1386
|
-
this.recentlyHandledOrder.push(envelopeId);
|
|
1387
|
-
this.trimRecentlyHandled(now);
|
|
1388
|
-
}
|
|
1389
|
-
wasRecentlyHandled(envelopeId) {
|
|
1390
|
-
const now = Date.now();
|
|
1391
|
-
const timestamp = this.recentlyHandled.get(envelopeId);
|
|
1392
|
-
if (timestamp === undefined) {
|
|
1393
|
-
return false;
|
|
1394
|
-
}
|
|
1395
|
-
if (now - timestamp > this.recentlyHandledTtlMs) {
|
|
1396
|
-
this.recentlyHandled.delete(envelopeId);
|
|
1397
|
-
return false;
|
|
1398
|
-
}
|
|
1399
|
-
return true;
|
|
1400
|
-
}
|
|
1401
|
-
trimRecentlyHandled(now) {
|
|
1402
|
-
while (this.recentlyHandledOrder.length > 0) {
|
|
1403
|
-
const candidate = this.recentlyHandledOrder[0];
|
|
1404
|
-
const timestamp = this.recentlyHandled.get(candidate);
|
|
1405
|
-
if (timestamp === undefined) {
|
|
1406
|
-
this.recentlyHandledOrder.shift();
|
|
1407
|
-
continue;
|
|
1408
|
-
}
|
|
1409
|
-
if (now - timestamp <= this.recentlyHandledTtlMs) {
|
|
1410
|
-
break;
|
|
1411
|
-
}
|
|
1412
|
-
this.recentlyHandled.delete(candidate);
|
|
1413
|
-
this.recentlyHandledOrder.shift();
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
1358
|
getShutdownRetryDeferDelay(nowMs) {
|
|
1417
1359
|
if (!this.isPreparingToStop || this.shutdownRequestedAtMs === null) {
|
|
1418
1360
|
return null;
|