@naylence/runtime 0.3.5-test.953 → 0.3.5-test.955
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 +133 -530
- package/dist/browser/index.mjs +133 -530
- package/dist/cjs/naylence/fame/channel/flow-controller.js +38 -1
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector-factory.js +2 -14
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +51 -109
- package/dist/cjs/naylence/fame/connector/broadcast-channel-listener.js +10 -76
- package/dist/cjs/naylence/fame/connector/inpage-connector-factory.js +0 -12
- package/dist/cjs/naylence/fame/connector/inpage-connector.js +1 -105
- package/dist/cjs/naylence/fame/connector/inpage-listener.js +2 -49
- package/dist/cjs/naylence/fame/grants/broadcast-channel-connection-grant.js +12 -23
- package/dist/cjs/naylence/fame/grants/inpage-connection-grant.js +0 -28
- package/dist/cjs/naylence/fame/node/admission/default-node-attach-client.js +0 -14
- package/dist/cjs/naylence/fame/node/upstream-session-manager.js +0 -6
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/channel/flow-controller.js +38 -1
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +2 -14
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +51 -109
- package/dist/esm/naylence/fame/connector/broadcast-channel-listener.js +10 -76
- package/dist/esm/naylence/fame/connector/inpage-connector-factory.js +0 -12
- package/dist/esm/naylence/fame/connector/inpage-connector.js +1 -105
- package/dist/esm/naylence/fame/connector/inpage-listener.js +2 -49
- package/dist/esm/naylence/fame/grants/broadcast-channel-connection-grant.js +12 -23
- package/dist/esm/naylence/fame/grants/inpage-connection-grant.js +0 -28
- package/dist/esm/naylence/fame/node/admission/default-node-attach-client.js +0 -14
- package/dist/esm/naylence/fame/node/upstream-session-manager.js +0 -6
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +133 -530
- package/dist/node/index.mjs +133 -530
- package/dist/node/node.cjs +133 -546
- package/dist/node/node.mjs +133 -546
- package/dist/types/naylence/fame/connector/broadcast-channel-connector-factory.d.ts +0 -2
- package/dist/types/naylence/fame/connector/broadcast-channel-connector.browser.d.ts +4 -9
- package/dist/types/naylence/fame/connector/inpage-connector-factory.d.ts +0 -2
- package/dist/types/naylence/fame/connector/inpage-connector.d.ts +0 -9
- package/dist/types/naylence/fame/connector/inpage-listener.d.ts +0 -1
- package/dist/types/naylence/fame/grants/broadcast-channel-connection-grant.d.ts +3 -6
- package/dist/types/naylence/fame/grants/inpage-connection-grant.d.ts +0 -8
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/cjs/naylence/fame/connector/transport-frame.js +0 -100
- package/dist/esm/naylence/fame/connector/transport-frame.js +0 -93
- package/dist/types/naylence/fame/connector/transport-frame.d.ts +0 -56
package/dist/node/index.cjs
CHANGED
|
@@ -14,12 +14,12 @@ var fastify = require('fastify');
|
|
|
14
14
|
var websocketPlugin = require('@fastify/websocket');
|
|
15
15
|
|
|
16
16
|
// This file is auto-generated during build - do not edit manually
|
|
17
|
-
// Generated from package.json version: 0.3.5-test.
|
|
17
|
+
// Generated from package.json version: 0.3.5-test.955
|
|
18
18
|
/**
|
|
19
19
|
* The package version, injected at build time.
|
|
20
20
|
* @internal
|
|
21
21
|
*/
|
|
22
|
-
const VERSION = '0.3.5-test.
|
|
22
|
+
const VERSION = '0.3.5-test.955';
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -837,7 +837,7 @@ class TaskCancelledError extends Error {
|
|
|
837
837
|
* Provides functionality similar to Python's asyncio TaskSpawner with proper
|
|
838
838
|
* error handling, cancellation, and graceful shutdown capabilities.
|
|
839
839
|
*/
|
|
840
|
-
const logger$
|
|
840
|
+
const logger$1c = getLogger('naylence.fame.util.task_spawner');
|
|
841
841
|
function firstDefined(source, keys) {
|
|
842
842
|
for (const key of keys) {
|
|
843
843
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
@@ -998,7 +998,7 @@ class TaskSpawner {
|
|
|
998
998
|
const taskId = `task-${++this._taskCounter}`;
|
|
999
999
|
const taskName = normalizedOptions.name || `unnamed-${taskId}`;
|
|
1000
1000
|
const timeout = normalizedOptions.timeout ?? this._config.defaultTimeout;
|
|
1001
|
-
logger$
|
|
1001
|
+
logger$1c.debug('starting_background_task', {
|
|
1002
1002
|
task_name: taskName,
|
|
1003
1003
|
task_id: taskId,
|
|
1004
1004
|
});
|
|
@@ -1015,7 +1015,7 @@ class TaskSpawner {
|
|
|
1015
1015
|
task.promise
|
|
1016
1016
|
.then(() => {
|
|
1017
1017
|
if (!this._suppressCompletionLogging) {
|
|
1018
|
-
logger$
|
|
1018
|
+
logger$1c.debug('task_completed_successfully', {
|
|
1019
1019
|
task_name: taskName,
|
|
1020
1020
|
task_id: taskId,
|
|
1021
1021
|
duration_ms: Date.now() - task.startTime,
|
|
@@ -1069,7 +1069,7 @@ class TaskSpawner {
|
|
|
1069
1069
|
error.name === 'AbortError' ||
|
|
1070
1070
|
error.message === 'Task cancelled' ||
|
|
1071
1071
|
error.message === 'Aborted') {
|
|
1072
|
-
logger$
|
|
1072
|
+
logger$1c.debug('task_cancelled', {
|
|
1073
1073
|
task_name: taskName,
|
|
1074
1074
|
note: 'Task cancelled as requested',
|
|
1075
1075
|
});
|
|
@@ -1077,7 +1077,7 @@ class TaskSpawner {
|
|
|
1077
1077
|
}
|
|
1078
1078
|
// Handle timeout
|
|
1079
1079
|
if (error instanceof TaskTimeoutError) {
|
|
1080
|
-
logger$
|
|
1080
|
+
logger$1c.warning('task_timed_out', {
|
|
1081
1081
|
task_name: taskName,
|
|
1082
1082
|
error: error.message,
|
|
1083
1083
|
});
|
|
@@ -1089,7 +1089,7 @@ class TaskSpawner {
|
|
|
1089
1089
|
// Handle known WebSocket shutdown race condition (similar to Python version)
|
|
1090
1090
|
if (error.message.includes("await wasn't used with future") ||
|
|
1091
1091
|
error.message.includes('WebSocket closed during receive')) {
|
|
1092
|
-
logger$
|
|
1092
|
+
logger$1c.debug('task_shutdown_race_condition_handled', {
|
|
1093
1093
|
task_name: taskName,
|
|
1094
1094
|
note: 'Normal WebSocket close timing during shutdown - not an error',
|
|
1095
1095
|
});
|
|
@@ -1099,7 +1099,7 @@ class TaskSpawner {
|
|
|
1099
1099
|
if (error.name === 'FameTransportClose' ||
|
|
1100
1100
|
error.message.includes('normal closure') ||
|
|
1101
1101
|
error.message.includes('Connection closed')) {
|
|
1102
|
-
logger$
|
|
1102
|
+
logger$1c.debug('task_shutdown_completed_normally', {
|
|
1103
1103
|
task_name: taskName,
|
|
1104
1104
|
note: 'Task closed normally during shutdown',
|
|
1105
1105
|
});
|
|
@@ -1112,14 +1112,14 @@ class TaskSpawner {
|
|
|
1112
1112
|
// Log retriable errors as warnings (they'll be retried by upstream logic)
|
|
1113
1113
|
// Log non-retriable errors as errors (fatal failures)
|
|
1114
1114
|
if (isRetriableError) {
|
|
1115
|
-
logger$
|
|
1115
|
+
logger$1c.warning('background_task_failed', {
|
|
1116
1116
|
task_name: taskName,
|
|
1117
1117
|
error: error.message,
|
|
1118
1118
|
retriable: true,
|
|
1119
1119
|
});
|
|
1120
1120
|
}
|
|
1121
1121
|
else {
|
|
1122
|
-
logger$
|
|
1122
|
+
logger$1c.error('background_task_failed', {
|
|
1123
1123
|
task_name: taskName,
|
|
1124
1124
|
error: error.message,
|
|
1125
1125
|
stack: error.stack,
|
|
@@ -1138,11 +1138,11 @@ class TaskSpawner {
|
|
|
1138
1138
|
async shutdownTasks(options = {}) {
|
|
1139
1139
|
const { gracePeriod, cancelHanging, joinTimeout } = normalizeShutdownOptions(options);
|
|
1140
1140
|
if (this._tasks.size === 0) {
|
|
1141
|
-
logger$
|
|
1141
|
+
logger$1c.debug('shutdown_tasks_no_tasks_to_shutdown');
|
|
1142
1142
|
return;
|
|
1143
1143
|
}
|
|
1144
1144
|
this._suppressCompletionLogging = true;
|
|
1145
|
-
logger$
|
|
1145
|
+
logger$1c.debug('shutting_down_tasks', {
|
|
1146
1146
|
task_count: this._tasks.size,
|
|
1147
1147
|
task_names: Array.from(this._tasks.values()).map((t) => t.name),
|
|
1148
1148
|
grace_period_ms: gracePeriod,
|
|
@@ -1157,7 +1157,7 @@ class TaskSpawner {
|
|
|
1157
1157
|
if (cancelHanging) {
|
|
1158
1158
|
const stillRunning = tasks.filter((task) => task.getState() === TaskState.RUNNING && !completed.has(task));
|
|
1159
1159
|
if (stillRunning.length > 0) {
|
|
1160
|
-
logger$
|
|
1160
|
+
logger$1c.debug('tasks_did_not_complete_within_grace_period', {
|
|
1161
1161
|
hanging_count: stillRunning.length,
|
|
1162
1162
|
});
|
|
1163
1163
|
// Wait for them to finish with individual timeouts
|
|
@@ -1167,7 +1167,7 @@ class TaskSpawner {
|
|
|
1167
1167
|
}
|
|
1168
1168
|
catch (error) {
|
|
1169
1169
|
if (error instanceof TaskTimeoutError) {
|
|
1170
|
-
logger$
|
|
1170
|
+
logger$1c.warning('task_did_not_shutdown', {
|
|
1171
1171
|
task_name: task.name || task.id,
|
|
1172
1172
|
join_timeout_ms: joinTimeout,
|
|
1173
1173
|
});
|
|
@@ -1178,7 +1178,7 @@ class TaskSpawner {
|
|
|
1178
1178
|
}
|
|
1179
1179
|
else if (!(error instanceof TaskCancelledError)) {
|
|
1180
1180
|
/* istanbul ignore next - unreachable defensive branch */
|
|
1181
|
-
logger$
|
|
1181
|
+
logger$1c.error('task_raised_during_cancellation', {
|
|
1182
1182
|
task_name: task.name || task.id,
|
|
1183
1183
|
error: error instanceof Error ? error.message : String(error),
|
|
1184
1184
|
});
|
|
@@ -2271,6 +2271,7 @@ function validateKeyCorrelationTtlSec(ttlSec) {
|
|
|
2271
2271
|
* condition/promise and ensure at most one notifier coroutine exists for a
|
|
2272
2272
|
* flow at any time.
|
|
2273
2273
|
*/
|
|
2274
|
+
const logger$1b = getLogger('naylence.fame.flow.flow_controller');
|
|
2274
2275
|
/**
|
|
2275
2276
|
* Simple condition variable implementation for TypeScript/Node.js
|
|
2276
2277
|
* Similar to Python's asyncio.Condition
|
|
@@ -2396,8 +2397,17 @@ class FlowController {
|
|
|
2396
2397
|
// clamp into [0, initialWindow]
|
|
2397
2398
|
const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
|
|
2398
2399
|
this.credits.set(flowId, newBalance);
|
|
2400
|
+
const crossedZero = prev <= 0 && newBalance > 0;
|
|
2401
|
+
logger$1b.debug('flow_controller_add_credits', {
|
|
2402
|
+
flow_id: flowId,
|
|
2403
|
+
delta,
|
|
2404
|
+
prev_balance: prev,
|
|
2405
|
+
new_balance: newBalance,
|
|
2406
|
+
initial_window: this.initialWindow,
|
|
2407
|
+
crossed_zero: crossedZero,
|
|
2408
|
+
});
|
|
2399
2409
|
// wake waiters only if we crossed the zero boundary
|
|
2400
|
-
if (
|
|
2410
|
+
if (crossedZero) {
|
|
2401
2411
|
this.wakeWaiters(flowId);
|
|
2402
2412
|
}
|
|
2403
2413
|
return newBalance;
|
|
@@ -2408,11 +2418,27 @@ class FlowController {
|
|
|
2408
2418
|
async acquire(flowId) {
|
|
2409
2419
|
this.ensureFlow(flowId);
|
|
2410
2420
|
const condition = this.conditions.get(flowId);
|
|
2421
|
+
logger$1b.debug('flow_controller_acquire_attempt', {
|
|
2422
|
+
flow_id: flowId,
|
|
2423
|
+
current_balance: this.credits.get(flowId),
|
|
2424
|
+
});
|
|
2411
2425
|
while (this.credits.get(flowId) <= 0) {
|
|
2426
|
+
logger$1b.debug('flow_controller_waiting_for_credit', {
|
|
2427
|
+
flow_id: flowId,
|
|
2428
|
+
});
|
|
2412
2429
|
await condition.wait();
|
|
2430
|
+
logger$1b.debug('flow_controller_woke_with_credit', {
|
|
2431
|
+
flow_id: flowId,
|
|
2432
|
+
balance_after_wake: this.credits.get(flowId),
|
|
2433
|
+
});
|
|
2413
2434
|
}
|
|
2414
2435
|
const current = this.credits.get(flowId);
|
|
2415
2436
|
this.credits.set(flowId, current - 1);
|
|
2437
|
+
logger$1b.debug('flow_controller_credit_consumed', {
|
|
2438
|
+
flow_id: flowId,
|
|
2439
|
+
prev_balance: current,
|
|
2440
|
+
remaining_balance: current - 1,
|
|
2441
|
+
});
|
|
2416
2442
|
}
|
|
2417
2443
|
/**
|
|
2418
2444
|
* Consume *credits* immediately (non-blocking).
|
|
@@ -2432,6 +2458,12 @@ class FlowController {
|
|
|
2432
2458
|
const current = this.credits.get(flowId);
|
|
2433
2459
|
const remaining = Math.max(current - credits, 0);
|
|
2434
2460
|
this.credits.set(flowId, remaining);
|
|
2461
|
+
logger$1b.debug('flow_controller_consume', {
|
|
2462
|
+
flow_id: flowId,
|
|
2463
|
+
requested: credits,
|
|
2464
|
+
prev_balance: current,
|
|
2465
|
+
remaining_balance: remaining,
|
|
2466
|
+
});
|
|
2435
2467
|
return remaining;
|
|
2436
2468
|
}
|
|
2437
2469
|
/**
|
|
@@ -2452,6 +2484,10 @@ class FlowController {
|
|
|
2452
2484
|
this.windowIds.delete(flowId);
|
|
2453
2485
|
this.credits.set(flowId, this.initialWindow);
|
|
2454
2486
|
this.wakeWaiters(flowId);
|
|
2487
|
+
logger$1b.debug('flow_controller_flow_reset', {
|
|
2488
|
+
flow_id: flowId,
|
|
2489
|
+
reset_balance: this.initialWindow,
|
|
2490
|
+
});
|
|
2455
2491
|
}
|
|
2456
2492
|
/**
|
|
2457
2493
|
* Return `[windowId, flags]` for the next outbound envelope.
|
|
@@ -9734,84 +9770,6 @@ class BoundedAsyncQueue {
|
|
|
9734
9770
|
}
|
|
9735
9771
|
}
|
|
9736
9772
|
|
|
9737
|
-
/**
|
|
9738
|
-
* Transport frame layer for multiplexing logical links on physical channels.
|
|
9739
|
-
*
|
|
9740
|
-
* This lightweight framing layer wraps raw FAME payloads to enable multiple
|
|
9741
|
-
* logical connections over a single physical channel (BroadcastChannel or InPage bus).
|
|
9742
|
-
*
|
|
9743
|
-
* The transport frame does NOT modify FAME envelopes - it only wraps the raw
|
|
9744
|
-
* Uint8Array payload at the connector level.
|
|
9745
|
-
*/
|
|
9746
|
-
/**
|
|
9747
|
-
* Transport frame version for future compatibility
|
|
9748
|
-
*/
|
|
9749
|
-
const TRANSPORT_FRAME_VERSION = 1;
|
|
9750
|
-
/**
|
|
9751
|
-
* Wrap a raw payload in a transport frame
|
|
9752
|
-
*
|
|
9753
|
-
* @param payload - Raw FAME envelope bytes
|
|
9754
|
-
* @param srcNodeId - Local node ID (this connector)
|
|
9755
|
-
* @param dstNodeId - Remote node ID (target connector)
|
|
9756
|
-
* @returns Transport frame ready for transmission
|
|
9757
|
-
*/
|
|
9758
|
-
function wrapTransportFrame(payload, srcNodeId, dstNodeId) {
|
|
9759
|
-
return {
|
|
9760
|
-
v: TRANSPORT_FRAME_VERSION,
|
|
9761
|
-
src: srcNodeId,
|
|
9762
|
-
dst: dstNodeId,
|
|
9763
|
-
payload,
|
|
9764
|
-
};
|
|
9765
|
-
}
|
|
9766
|
-
/**
|
|
9767
|
-
* Serialize a transport frame for transmission over the bus
|
|
9768
|
-
*
|
|
9769
|
-
* @param frame - Transport frame to serialize
|
|
9770
|
-
* @returns Serialized frame data ready for postMessage/dispatchEvent
|
|
9771
|
-
*/
|
|
9772
|
-
function serializeTransportFrame(frame) {
|
|
9773
|
-
// Convert Uint8Array to regular array for JSON serialization
|
|
9774
|
-
const serializable = {
|
|
9775
|
-
v: frame.v,
|
|
9776
|
-
src: frame.src,
|
|
9777
|
-
dst: frame.dst,
|
|
9778
|
-
payload: Array.from(frame.payload),
|
|
9779
|
-
};
|
|
9780
|
-
return serializable;
|
|
9781
|
-
}
|
|
9782
|
-
/**
|
|
9783
|
-
* Unwrap a transport frame (pure deserializer - no filtering)
|
|
9784
|
-
*
|
|
9785
|
-
* @param raw - Raw data from the bus
|
|
9786
|
-
* @returns Unwrapped frame with payload as Uint8Array, or null if invalid structure
|
|
9787
|
-
*/
|
|
9788
|
-
function unwrapTransportFrame(raw) {
|
|
9789
|
-
// Validate basic structure
|
|
9790
|
-
if (!raw || typeof raw !== 'object') {
|
|
9791
|
-
return null;
|
|
9792
|
-
}
|
|
9793
|
-
const frame = raw;
|
|
9794
|
-
// Check version
|
|
9795
|
-
if (frame.v !== TRANSPORT_FRAME_VERSION) {
|
|
9796
|
-
return null;
|
|
9797
|
-
}
|
|
9798
|
-
// Check src and dst
|
|
9799
|
-
if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
|
|
9800
|
-
return null;
|
|
9801
|
-
}
|
|
9802
|
-
// Extract payload
|
|
9803
|
-
if (!frame.payload || !Array.isArray(frame.payload)) {
|
|
9804
|
-
return null;
|
|
9805
|
-
}
|
|
9806
|
-
// Convert array back to Uint8Array and return full frame
|
|
9807
|
-
return {
|
|
9808
|
-
v: frame.v,
|
|
9809
|
-
src: frame.src,
|
|
9810
|
-
dst: frame.dst,
|
|
9811
|
-
payload: Uint8Array.from(frame.payload),
|
|
9812
|
-
};
|
|
9813
|
-
}
|
|
9814
|
-
|
|
9815
9773
|
const logger$_ = getLogger('naylence.fame.connector.broadcast_channel_connector');
|
|
9816
9774
|
const BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
|
|
9817
9775
|
const DEFAULT_CHANNEL$7 = 'naylence-fabric';
|
|
@@ -9875,22 +9833,12 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9875
9833
|
? Math.floor(config.inboxCapacity)
|
|
9876
9834
|
: DEFAULT_INBOX_CAPACITY$7;
|
|
9877
9835
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
9836
|
+
this.inboxCapacity = preferredCapacity;
|
|
9878
9837
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
9879
9838
|
this.channel = new BroadcastChannel(this.channelName);
|
|
9880
|
-
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
9881
|
-
this.localNodeId =
|
|
9882
|
-
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
9883
|
-
? config.localNodeId.trim()
|
|
9884
|
-
: this.connectorId;
|
|
9885
|
-
this.remoteNodeId =
|
|
9886
|
-
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
9887
|
-
? config.remoteNodeId.trim()
|
|
9888
|
-
: '*'; // Accept from any remote if not specified
|
|
9889
9839
|
logger$_.debug('broadcast_channel_connector_created', {
|
|
9890
9840
|
channel: this.channelName,
|
|
9891
9841
|
connector_id: this.connectorId,
|
|
9892
|
-
local_node_id: this.localNodeId,
|
|
9893
|
-
remote_node_id: this.remoteNodeId,
|
|
9894
9842
|
inbox_capacity: preferredCapacity,
|
|
9895
9843
|
timestamp: new Date().toISOString(),
|
|
9896
9844
|
});
|
|
@@ -9923,67 +9871,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9923
9871
|
if (busMessage.senderId === this.connectorId) {
|
|
9924
9872
|
return;
|
|
9925
9873
|
}
|
|
9926
|
-
// Try to unwrap as transport frame
|
|
9927
|
-
const frame = unwrapTransportFrame(busMessage.payload);
|
|
9928
|
-
if (frame) {
|
|
9929
|
-
// Apply connector's filtering policy: strict dst check, src accepts wildcard
|
|
9930
|
-
const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
|
|
9931
|
-
const dstMatches = frame.dst === this.localNodeId;
|
|
9932
|
-
if (dstMatches && srcMatches) {
|
|
9933
|
-
// Successfully received and filtered transport frame
|
|
9934
|
-
logger$_.debug('broadcast_channel_transport_frame_received', {
|
|
9935
|
-
channel: this.channelName,
|
|
9936
|
-
sender_id: busMessage.senderId,
|
|
9937
|
-
connector_id: this.connectorId,
|
|
9938
|
-
local_node_id: this.localNodeId,
|
|
9939
|
-
remote_node_id: this.remoteNodeId,
|
|
9940
|
-
frame_src: frame.src,
|
|
9941
|
-
frame_dst: frame.dst,
|
|
9942
|
-
payload_length: frame.payload.byteLength,
|
|
9943
|
-
});
|
|
9944
|
-
const unwrapped = frame.payload;
|
|
9945
|
-
if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
|
|
9946
|
-
return;
|
|
9947
|
-
}
|
|
9948
|
-
try {
|
|
9949
|
-
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
9950
|
-
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
9951
|
-
if (accepted) {
|
|
9952
|
-
return;
|
|
9953
|
-
}
|
|
9954
|
-
}
|
|
9955
|
-
this.inbox.enqueue(unwrapped);
|
|
9956
|
-
}
|
|
9957
|
-
catch (error) {
|
|
9958
|
-
if (error instanceof QueueFullError) {
|
|
9959
|
-
logger$_.warning('broadcast_channel_receive_queue_full', {
|
|
9960
|
-
channel: this.channelName,
|
|
9961
|
-
});
|
|
9962
|
-
}
|
|
9963
|
-
else {
|
|
9964
|
-
logger$_.error('broadcast_channel_receive_error', {
|
|
9965
|
-
channel: this.channelName,
|
|
9966
|
-
error: error instanceof Error ? error.message : String(error),
|
|
9967
|
-
});
|
|
9968
|
-
}
|
|
9969
|
-
}
|
|
9970
|
-
return;
|
|
9971
|
-
}
|
|
9972
|
-
else {
|
|
9973
|
-
// Frame filtered out by addressing rules
|
|
9974
|
-
logger$_.debug('broadcast_channel_transport_frame_filtered', {
|
|
9975
|
-
channel: this.channelName,
|
|
9976
|
-
connector_id: this.connectorId,
|
|
9977
|
-
local_node_id: this.localNodeId,
|
|
9978
|
-
remote_node_id: this.remoteNodeId,
|
|
9979
|
-
frame_src: frame.src,
|
|
9980
|
-
frame_dst: frame.dst,
|
|
9981
|
-
reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
|
|
9982
|
-
});
|
|
9983
|
-
return;
|
|
9984
|
-
}
|
|
9985
|
-
}
|
|
9986
|
-
// Fall back to legacy format (no transport frame)
|
|
9987
9874
|
const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
|
|
9988
9875
|
if (!payload) {
|
|
9989
9876
|
logger$_.debug('broadcast_channel_payload_rejected', {
|
|
@@ -10006,15 +9893,27 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10006
9893
|
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
10007
9894
|
const accepted = this.inbox.tryEnqueue(payload);
|
|
10008
9895
|
if (accepted) {
|
|
9896
|
+
this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
|
|
9897
|
+
source: 'listener',
|
|
9898
|
+
enqueue_strategy: 'try',
|
|
9899
|
+
payload_length: payload.byteLength,
|
|
9900
|
+
});
|
|
10009
9901
|
return;
|
|
10010
9902
|
}
|
|
10011
9903
|
}
|
|
10012
9904
|
this.inbox.enqueue(payload);
|
|
9905
|
+
this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
|
|
9906
|
+
source: 'listener',
|
|
9907
|
+
enqueue_strategy: 'enqueue',
|
|
9908
|
+
payload_length: payload.byteLength,
|
|
9909
|
+
});
|
|
10013
9910
|
}
|
|
10014
9911
|
catch (error) {
|
|
10015
9912
|
if (error instanceof QueueFullError) {
|
|
10016
9913
|
logger$_.warning('broadcast_channel_receive_queue_full', {
|
|
10017
9914
|
channel: this.channelName,
|
|
9915
|
+
inbox_capacity: this.inboxCapacity,
|
|
9916
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
10018
9917
|
});
|
|
10019
9918
|
}
|
|
10020
9919
|
else {
|
|
@@ -10098,15 +9997,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10098
9997
|
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
10099
9998
|
const accepted = this.inbox.tryEnqueue(item);
|
|
10100
9999
|
if (accepted) {
|
|
10000
|
+
this.logInboxSnapshot('broadcast_channel_push_enqueued', {
|
|
10001
|
+
enqueue_strategy: 'try',
|
|
10002
|
+
item_type: this._describeInboxItem(item),
|
|
10003
|
+
});
|
|
10101
10004
|
return;
|
|
10102
10005
|
}
|
|
10103
10006
|
}
|
|
10104
10007
|
this.inbox.enqueue(item);
|
|
10008
|
+
this.logInboxSnapshot('broadcast_channel_push_enqueued', {
|
|
10009
|
+
enqueue_strategy: 'enqueue',
|
|
10010
|
+
item_type: this._describeInboxItem(item),
|
|
10011
|
+
});
|
|
10105
10012
|
}
|
|
10106
10013
|
catch (error) {
|
|
10107
10014
|
if (error instanceof QueueFullError) {
|
|
10108
10015
|
logger$_.warning('broadcast_channel_push_queue_full', {
|
|
10109
10016
|
channel: this.channelName,
|
|
10017
|
+
inbox_capacity: this.inboxCapacity,
|
|
10018
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
10110
10019
|
});
|
|
10111
10020
|
throw error;
|
|
10112
10021
|
}
|
|
@@ -10122,30 +10031,18 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10122
10031
|
logger$_.debug('broadcast_channel_message_sending', {
|
|
10123
10032
|
channel: this.channelName,
|
|
10124
10033
|
sender_id: this.connectorId,
|
|
10125
|
-
|
|
10126
|
-
remote_node_id: this.remoteNodeId,
|
|
10127
|
-
});
|
|
10128
|
-
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
10129
|
-
// (not using default values). This ensures backwards compatibility.
|
|
10130
|
-
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
10131
|
-
this.remoteNodeId !== '*';
|
|
10132
|
-
let payload;
|
|
10133
|
-
if (useTransportFrame) {
|
|
10134
|
-
// Wrap payload in transport frame
|
|
10135
|
-
const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
|
|
10136
|
-
payload = serializeTransportFrame(frame);
|
|
10137
|
-
}
|
|
10138
|
-
else {
|
|
10139
|
-
// Legacy format: send raw payload
|
|
10140
|
-
payload = data;
|
|
10141
|
-
}
|
|
10034
|
+
});
|
|
10142
10035
|
this.channel.postMessage({
|
|
10143
10036
|
senderId: this.connectorId,
|
|
10144
|
-
payload,
|
|
10037
|
+
payload: data,
|
|
10145
10038
|
});
|
|
10146
10039
|
}
|
|
10147
10040
|
async _transportReceive() {
|
|
10148
|
-
|
|
10041
|
+
const item = await this.inbox.dequeue();
|
|
10042
|
+
this.logInboxSnapshot('broadcast_channel_inbox_dequeued', {
|
|
10043
|
+
item_type: this._describeInboxItem(item),
|
|
10044
|
+
});
|
|
10045
|
+
return item;
|
|
10149
10046
|
}
|
|
10150
10047
|
async _transportClose(code, reason) {
|
|
10151
10048
|
logger$_.debug('broadcast_channel_transport_closing', {
|
|
@@ -10199,6 +10096,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10199
10096
|
}
|
|
10200
10097
|
return rawOrEnvelope;
|
|
10201
10098
|
}
|
|
10099
|
+
_describeInboxItem(item) {
|
|
10100
|
+
if (item instanceof Uint8Array) {
|
|
10101
|
+
return 'bytes';
|
|
10102
|
+
}
|
|
10103
|
+
if (item.envelope) {
|
|
10104
|
+
return 'channel_message';
|
|
10105
|
+
}
|
|
10106
|
+
if (item.frame) {
|
|
10107
|
+
return 'envelope';
|
|
10108
|
+
}
|
|
10109
|
+
return 'unknown';
|
|
10110
|
+
}
|
|
10111
|
+
logInboxSnapshot(event, extra = {}) {
|
|
10112
|
+
logger$_.debug(event, {
|
|
10113
|
+
channel: this.channelName,
|
|
10114
|
+
connector_id: this.connectorId,
|
|
10115
|
+
connector_state: this.state,
|
|
10116
|
+
inbox_capacity: this.inboxCapacity,
|
|
10117
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
10118
|
+
...extra,
|
|
10119
|
+
});
|
|
10120
|
+
}
|
|
10202
10121
|
_shouldSkipDuplicateAck(senderId, payload) {
|
|
10203
10122
|
const dedupKey = this._extractAckDedupKey(payload);
|
|
10204
10123
|
if (!dedupKey) {
|
|
@@ -10297,24 +10216,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10297
10216
|
});
|
|
10298
10217
|
}
|
|
10299
10218
|
}
|
|
10300
|
-
/**
|
|
10301
|
-
* Update the remote node ID after learning it from NodeAttachAck
|
|
10302
|
-
* This allows upstream connectors to switch from wildcard to specific addressing
|
|
10303
|
-
*/
|
|
10304
|
-
updateRemoteNodeId(newRemoteNodeId) {
|
|
10305
|
-
if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
|
|
10306
|
-
throw new Error('Invalid remote node ID');
|
|
10307
|
-
}
|
|
10308
|
-
const oldValue = this.remoteNodeId;
|
|
10309
|
-
this.remoteNodeId = newRemoteNodeId.trim();
|
|
10310
|
-
logger$_.debug('broadcast_channel_connector_remote_node_id_updated', {
|
|
10311
|
-
channel: this.channelName,
|
|
10312
|
-
connector_id: this.connectorId,
|
|
10313
|
-
local_node_id: this.localNodeId,
|
|
10314
|
-
old_remote_node_id: oldValue,
|
|
10315
|
-
new_remote_node_id: this.remoteNodeId,
|
|
10316
|
-
});
|
|
10317
|
-
}
|
|
10318
10219
|
_trimSeenAcks(now) {
|
|
10319
10220
|
while (this.seenAckOrder.length > 0) {
|
|
10320
10221
|
const candidate = this.seenAckOrder[0];
|
|
@@ -10452,12 +10353,9 @@ function isBroadcastChannelConnectionGrant(candidate) {
|
|
|
10452
10353
|
record.inboxCapacity <= 0)) {
|
|
10453
10354
|
return false;
|
|
10454
10355
|
}
|
|
10455
|
-
if (record.
|
|
10456
|
-
(
|
|
10457
|
-
|
|
10458
|
-
}
|
|
10459
|
-
if (record.remoteNodeId !== undefined &&
|
|
10460
|
-
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
10356
|
+
if (record.initialWindow !== undefined &&
|
|
10357
|
+
(!Number.isFinite(record.initialWindow) ||
|
|
10358
|
+
record.initialWindow <= 0)) {
|
|
10461
10359
|
return false;
|
|
10462
10360
|
}
|
|
10463
10361
|
return true;
|
|
@@ -10493,19 +10391,14 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
|
10493
10391
|
}
|
|
10494
10392
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
10495
10393
|
}
|
|
10496
|
-
const
|
|
10497
|
-
if (
|
|
10498
|
-
if (typeof
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
10502
|
-
}
|
|
10503
|
-
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
10504
|
-
if (remoteNodeIdValue !== undefined) {
|
|
10505
|
-
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
10506
|
-
throw new TypeError('BroadcastChannelConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
10394
|
+
const windowValue = candidate.initialWindow ?? candidate['initial_window'];
|
|
10395
|
+
if (windowValue !== undefined) {
|
|
10396
|
+
if (typeof windowValue !== 'number' ||
|
|
10397
|
+
!Number.isFinite(windowValue) ||
|
|
10398
|
+
windowValue <= 0) {
|
|
10399
|
+
throw new TypeError('BroadcastChannelConnectionGrant "initialWindow" must be a positive number when provided');
|
|
10507
10400
|
}
|
|
10508
|
-
result.
|
|
10401
|
+
result.initialWindow = Math.floor(windowValue);
|
|
10509
10402
|
}
|
|
10510
10403
|
return result;
|
|
10511
10404
|
}
|
|
@@ -10520,11 +10413,8 @@ function broadcastChannelGrantToConnectorConfig(grant) {
|
|
|
10520
10413
|
if (normalized.inboxCapacity !== undefined) {
|
|
10521
10414
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
10522
10415
|
}
|
|
10523
|
-
if (normalized.
|
|
10524
|
-
config.
|
|
10525
|
-
}
|
|
10526
|
-
if (normalized.remoteNodeId) {
|
|
10527
|
-
config.remoteNodeId = normalized.remoteNodeId;
|
|
10416
|
+
if (normalized.initialWindow !== undefined) {
|
|
10417
|
+
config.initialWindow = normalized.initialWindow;
|
|
10528
10418
|
}
|
|
10529
10419
|
return config;
|
|
10530
10420
|
}
|
|
@@ -10816,12 +10706,6 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
10816
10706
|
cryptoProvider.prepareForAttach(welcome.frame.systemId, welcome.frame.assignedPath, welcome.frame.acceptedLogicals ?? []);
|
|
10817
10707
|
}
|
|
10818
10708
|
await this.onWelcome(welcome.frame);
|
|
10819
|
-
// Inject node ID into grant for transport frame multiplexing
|
|
10820
|
-
// This ensures localNodeId matches the node's systemId for proper frame filtering
|
|
10821
|
-
grant.localNodeId = welcome.frame.systemId;
|
|
10822
|
-
if (welcome.frame.targetSystemId) {
|
|
10823
|
-
grant.remoteNodeId = welcome.frame.targetSystemId;
|
|
10824
|
-
}
|
|
10825
10709
|
const connector = await ConnectorFactory.createConnector(grant, {
|
|
10826
10710
|
systemId: welcome.frame.systemId,
|
|
10827
10711
|
});
|
|
@@ -12778,20 +12662,6 @@ class DefaultNodeAttachClient {
|
|
|
12778
12662
|
if (!targetSystemId) {
|
|
12779
12663
|
throw new Error('Target system ID must be set in NodeAttachAckFrame on success');
|
|
12780
12664
|
}
|
|
12781
|
-
// Update connector's remote node ID if it supports it (e.g., BroadcastChannelConnector, InPageConnector)
|
|
12782
|
-
// This allows upstream connectors to switch from wildcard '*' to specific node addressing
|
|
12783
|
-
const updatableConnector = connector;
|
|
12784
|
-
if (typeof updatableConnector.updateRemoteNodeId === 'function') {
|
|
12785
|
-
try {
|
|
12786
|
-
updatableConnector.updateRemoteNodeId(targetSystemId);
|
|
12787
|
-
}
|
|
12788
|
-
catch (error) {
|
|
12789
|
-
logger$W.debug('connector_remote_node_id_update_failed', {
|
|
12790
|
-
target_system_id: targetSystemId,
|
|
12791
|
-
error: error instanceof Error ? error.message : String(error),
|
|
12792
|
-
});
|
|
12793
|
-
}
|
|
12794
|
-
}
|
|
12795
12665
|
try {
|
|
12796
12666
|
if (this.replicaStickinessManager) {
|
|
12797
12667
|
this.replicaStickinessManager.accept(ackFrame.stickiness ?? null);
|
|
@@ -20492,20 +20362,9 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20492
20362
|
: DEFAULT_INBOX_CAPACITY$6;
|
|
20493
20363
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
20494
20364
|
this.connectorId = InPageConnector.generateConnectorId();
|
|
20495
|
-
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
20496
|
-
this.localNodeId =
|
|
20497
|
-
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
20498
|
-
? config.localNodeId.trim()
|
|
20499
|
-
: this.connectorId;
|
|
20500
|
-
this.remoteNodeId =
|
|
20501
|
-
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
20502
|
-
? config.remoteNodeId.trim()
|
|
20503
|
-
: '*'; // Accept from any remote if not specified
|
|
20504
20365
|
logger$G.debug('inpage_connector_initialized', {
|
|
20505
20366
|
channel: this.channelName,
|
|
20506
20367
|
connector_id: this.connectorId,
|
|
20507
|
-
local_node_id: this.localNodeId,
|
|
20508
|
-
remote_node_id: this.remoteNodeId,
|
|
20509
20368
|
});
|
|
20510
20369
|
this.onMsg = (event) => {
|
|
20511
20370
|
const messageEvent = event;
|
|
@@ -20539,64 +20398,6 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20539
20398
|
if (busMessage.senderId === this.connectorId) {
|
|
20540
20399
|
return;
|
|
20541
20400
|
}
|
|
20542
|
-
// Try to unwrap as transport frame
|
|
20543
|
-
const frame = unwrapTransportFrame(busMessage.payload);
|
|
20544
|
-
if (frame) {
|
|
20545
|
-
// Apply connector's filtering policy: strict dst check, src accepts wildcard
|
|
20546
|
-
const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
|
|
20547
|
-
const dstMatches = frame.dst === this.localNodeId;
|
|
20548
|
-
if (dstMatches && srcMatches) {
|
|
20549
|
-
// Successfully received and filtered transport frame
|
|
20550
|
-
logger$G.debug('inpage_transport_frame_received', {
|
|
20551
|
-
channel: this.channelName,
|
|
20552
|
-
sender_id: busMessage.senderId,
|
|
20553
|
-
connector_id: this.connectorId,
|
|
20554
|
-
local_node_id: this.localNodeId,
|
|
20555
|
-
remote_node_id: this.remoteNodeId,
|
|
20556
|
-
frame_src: frame.src,
|
|
20557
|
-
frame_dst: frame.dst,
|
|
20558
|
-
payload_length: frame.payload.byteLength,
|
|
20559
|
-
});
|
|
20560
|
-
const unwrapped = frame.payload;
|
|
20561
|
-
try {
|
|
20562
|
-
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
20563
|
-
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
20564
|
-
if (accepted) {
|
|
20565
|
-
return;
|
|
20566
|
-
}
|
|
20567
|
-
}
|
|
20568
|
-
this.inbox.enqueue(unwrapped);
|
|
20569
|
-
}
|
|
20570
|
-
catch (error) {
|
|
20571
|
-
if (error instanceof QueueFullError) {
|
|
20572
|
-
logger$G.warning('inpage_receive_queue_full', {
|
|
20573
|
-
channel: this.channelName,
|
|
20574
|
-
});
|
|
20575
|
-
}
|
|
20576
|
-
else {
|
|
20577
|
-
logger$G.error('inpage_receive_error', {
|
|
20578
|
-
channel: this.channelName,
|
|
20579
|
-
error: error instanceof Error ? error.message : String(error),
|
|
20580
|
-
});
|
|
20581
|
-
}
|
|
20582
|
-
}
|
|
20583
|
-
return;
|
|
20584
|
-
}
|
|
20585
|
-
else {
|
|
20586
|
-
// Frame filtered out by addressing rules
|
|
20587
|
-
logger$G.debug('inpage_transport_frame_filtered', {
|
|
20588
|
-
channel: this.channelName,
|
|
20589
|
-
connector_id: this.connectorId,
|
|
20590
|
-
local_node_id: this.localNodeId,
|
|
20591
|
-
remote_node_id: this.remoteNodeId,
|
|
20592
|
-
frame_src: frame.src,
|
|
20593
|
-
frame_dst: frame.dst,
|
|
20594
|
-
reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
|
|
20595
|
-
});
|
|
20596
|
-
return;
|
|
20597
|
-
}
|
|
20598
|
-
}
|
|
20599
|
-
// Fall back to legacy format (no transport frame)
|
|
20600
20401
|
const payload = InPageConnector.coercePayload(busMessage.payload);
|
|
20601
20402
|
if (!payload) {
|
|
20602
20403
|
logger$G.debug('inpage_payload_rejected', {
|
|
@@ -20755,27 +20556,11 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20755
20556
|
logger$G.debug('inpage_message_sending', {
|
|
20756
20557
|
channel: this.channelName,
|
|
20757
20558
|
sender_id: this.connectorId,
|
|
20758
|
-
|
|
20759
|
-
remote_node_id: this.remoteNodeId,
|
|
20760
|
-
});
|
|
20761
|
-
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
20762
|
-
// (not using default values). This ensures backwards compatibility.
|
|
20763
|
-
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
20764
|
-
this.remoteNodeId !== '*';
|
|
20765
|
-
let payload;
|
|
20766
|
-
if (useTransportFrame) {
|
|
20767
|
-
// Wrap payload in transport frame
|
|
20768
|
-
const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
|
|
20769
|
-
payload = serializeTransportFrame(frame);
|
|
20770
|
-
}
|
|
20771
|
-
else {
|
|
20772
|
-
// Legacy format: send raw payload
|
|
20773
|
-
payload = data;
|
|
20774
|
-
}
|
|
20559
|
+
});
|
|
20775
20560
|
const event = new MessageEvent(this.channelName, {
|
|
20776
20561
|
data: {
|
|
20777
20562
|
senderId: this.connectorId,
|
|
20778
|
-
payload,
|
|
20563
|
+
payload: data,
|
|
20779
20564
|
},
|
|
20780
20565
|
});
|
|
20781
20566
|
getSharedBus$1().dispatchEvent(event);
|
|
@@ -20804,24 +20589,6 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20804
20589
|
}
|
|
20805
20590
|
return rawOrEnvelope;
|
|
20806
20591
|
}
|
|
20807
|
-
/**
|
|
20808
|
-
* Update the remote node ID after learning it from NodeAttachAck
|
|
20809
|
-
* This allows upstream connectors to switch from wildcard to specific addressing
|
|
20810
|
-
*/
|
|
20811
|
-
updateRemoteNodeId(newRemoteNodeId) {
|
|
20812
|
-
if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
|
|
20813
|
-
throw new Error('Invalid remote node ID');
|
|
20814
|
-
}
|
|
20815
|
-
const oldValue = this.remoteNodeId;
|
|
20816
|
-
this.remoteNodeId = newRemoteNodeId.trim();
|
|
20817
|
-
logger$G.debug('inpage_connector_remote_node_id_updated', {
|
|
20818
|
-
channel: this.channelName,
|
|
20819
|
-
connector_id: this.connectorId,
|
|
20820
|
-
local_node_id: this.localNodeId,
|
|
20821
|
-
old_remote_node_id: oldValue,
|
|
20822
|
-
new_remote_node_id: this.remoteNodeId,
|
|
20823
|
-
});
|
|
20824
|
-
}
|
|
20825
20592
|
}
|
|
20826
20593
|
|
|
20827
20594
|
const RPC_REGISTRY = Symbol('naylence.rpc.registry');
|
|
@@ -28158,14 +27925,6 @@ function isInPageConnectionGrant(candidate) {
|
|
|
28158
27925
|
record.inboxCapacity <= 0)) {
|
|
28159
27926
|
return false;
|
|
28160
27927
|
}
|
|
28161
|
-
if (record.localNodeId !== undefined &&
|
|
28162
|
-
(typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
|
|
28163
|
-
return false;
|
|
28164
|
-
}
|
|
28165
|
-
if (record.remoteNodeId !== undefined &&
|
|
28166
|
-
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
28167
|
-
return false;
|
|
28168
|
-
}
|
|
28169
27928
|
return true;
|
|
28170
27929
|
}
|
|
28171
27930
|
function normalizeInPageConnectionGrant(candidate) {
|
|
@@ -28199,20 +27958,6 @@ function normalizeInPageConnectionGrant(candidate) {
|
|
|
28199
27958
|
}
|
|
28200
27959
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
28201
27960
|
}
|
|
28202
|
-
const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
|
|
28203
|
-
if (localNodeIdValue !== undefined) {
|
|
28204
|
-
if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
|
|
28205
|
-
throw new TypeError('InPageConnectionGrant "localNodeId" must be a non-empty string when provided');
|
|
28206
|
-
}
|
|
28207
|
-
result.localNodeId = localNodeIdValue.trim();
|
|
28208
|
-
}
|
|
28209
|
-
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
28210
|
-
if (remoteNodeIdValue !== undefined) {
|
|
28211
|
-
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
28212
|
-
throw new TypeError('InPageConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
28213
|
-
}
|
|
28214
|
-
result.remoteNodeId = remoteNodeIdValue.trim();
|
|
28215
|
-
}
|
|
28216
27961
|
return result;
|
|
28217
27962
|
}
|
|
28218
27963
|
function inPageGrantToConnectorConfig(grant) {
|
|
@@ -28226,12 +27971,6 @@ function inPageGrantToConnectorConfig(grant) {
|
|
|
28226
27971
|
if (normalized.inboxCapacity !== undefined) {
|
|
28227
27972
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
28228
27973
|
}
|
|
28229
|
-
if (normalized.localNodeId) {
|
|
28230
|
-
config.localNodeId = normalized.localNodeId;
|
|
28231
|
-
}
|
|
28232
|
-
if (normalized.remoteNodeId) {
|
|
28233
|
-
config.remoteNodeId = normalized.remoteNodeId;
|
|
28234
|
-
}
|
|
28235
27974
|
return config;
|
|
28236
27975
|
}
|
|
28237
27976
|
|
|
@@ -28809,8 +28548,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28809
28548
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
28810
28549
|
channelName: connectorConfig.channelName,
|
|
28811
28550
|
inboxCapacity: connectorConfig.inboxCapacity,
|
|
28812
|
-
|
|
28813
|
-
remoteNodeId: connectorConfig.remoteNodeId,
|
|
28551
|
+
initialWindow: connectorConfig.initialWindow,
|
|
28814
28552
|
};
|
|
28815
28553
|
}
|
|
28816
28554
|
const config = {
|
|
@@ -28835,6 +28573,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28835
28573
|
purpose: 'connection',
|
|
28836
28574
|
channelName: normalizedConfig.channelName,
|
|
28837
28575
|
inboxCapacity: normalizedConfig.inboxCapacity,
|
|
28576
|
+
initialWindow: normalizedConfig.initialWindow,
|
|
28838
28577
|
});
|
|
28839
28578
|
return grant;
|
|
28840
28579
|
}
|
|
@@ -28860,8 +28599,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28860
28599
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
28861
28600
|
channelName,
|
|
28862
28601
|
inboxCapacity,
|
|
28863
|
-
localNodeId: normalized.localNodeId,
|
|
28864
|
-
remoteNodeId: normalized.remoteNodeId,
|
|
28865
28602
|
};
|
|
28866
28603
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
28867
28604
|
if (options.authorization) {
|
|
@@ -28923,16 +28660,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
28923
28660
|
if (candidate.authorizationContext !== undefined) {
|
|
28924
28661
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
28925
28662
|
}
|
|
28926
|
-
// Handle localNodeId
|
|
28927
|
-
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
28928
|
-
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
28929
|
-
normalized.localNodeId = localNodeId.trim();
|
|
28930
|
-
}
|
|
28931
|
-
// Handle remoteNodeId
|
|
28932
|
-
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
28933
|
-
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
28934
|
-
normalized.remoteNodeId = remoteNodeId.trim();
|
|
28935
|
-
}
|
|
28936
28663
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$5;
|
|
28937
28664
|
normalized.inboxCapacity =
|
|
28938
28665
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
|
|
@@ -29496,8 +29223,6 @@ class InPageConnectorFactory extends ConnectorFactory {
|
|
|
29496
29223
|
type: INPAGE_CONNECTOR_TYPE,
|
|
29497
29224
|
channelName,
|
|
29498
29225
|
inboxCapacity,
|
|
29499
|
-
localNodeId: normalized.localNodeId,
|
|
29500
|
-
remoteNodeId: normalized.remoteNodeId,
|
|
29501
29226
|
};
|
|
29502
29227
|
const connector = new InPageConnector(connectorConfig, baseConfig);
|
|
29503
29228
|
if (options.authorization) {
|
|
@@ -29566,16 +29291,6 @@ class InPageConnectorFactory extends ConnectorFactory {
|
|
|
29566
29291
|
if (candidate.authorizationContext !== undefined) {
|
|
29567
29292
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
29568
29293
|
}
|
|
29569
|
-
// Handle localNodeId
|
|
29570
|
-
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
29571
|
-
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
29572
|
-
normalized.localNodeId = localNodeId.trim();
|
|
29573
|
-
}
|
|
29574
|
-
// Handle remoteNodeId
|
|
29575
|
-
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
29576
|
-
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
29577
|
-
normalized.remoteNodeId = remoteNodeId.trim();
|
|
29578
|
-
}
|
|
29579
29294
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$3;
|
|
29580
29295
|
normalized.inboxCapacity =
|
|
29581
29296
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$3;
|
|
@@ -36341,18 +36056,13 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36341
36056
|
});
|
|
36342
36057
|
}
|
|
36343
36058
|
asCallbackGrant() {
|
|
36344
|
-
|
|
36059
|
+
return this.withLegacySnakeCaseKeys({
|
|
36345
36060
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
36346
36061
|
connectorType: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
36347
36062
|
connectionGrantType: BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE,
|
|
36348
36063
|
channelName: this._channelName,
|
|
36349
36064
|
inboxCapacity: this._inboxCapacity,
|
|
36350
|
-
};
|
|
36351
|
-
// Include localNodeId for transport frame multiplexing if node is available
|
|
36352
|
-
if (this._routingNode) {
|
|
36353
|
-
grant.localNodeId = this._routingNode.id;
|
|
36354
|
-
}
|
|
36355
|
-
return this.withLegacySnakeCaseKeys(grant);
|
|
36065
|
+
});
|
|
36356
36066
|
}
|
|
36357
36067
|
_registerChannelListener() {
|
|
36358
36068
|
if (this._channelHandler) {
|
|
@@ -36412,54 +36122,23 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36412
36122
|
if (typeof senderId !== 'string' || senderId.length === 0) {
|
|
36413
36123
|
return null;
|
|
36414
36124
|
}
|
|
36415
|
-
|
|
36416
|
-
|
|
36417
|
-
|
|
36418
|
-
|
|
36419
|
-
|
|
36420
|
-
|
|
36421
|
-
// Apply listener's filtering policy: accept frames addressed to us OR with wildcard destination
|
|
36422
|
-
// Wildcard is needed because downstream nodes don't know the sentinel's ID during initial attach
|
|
36423
|
-
const isAddressedToUs = frame.dst === this._routingNode.id || frame.dst === '*';
|
|
36424
|
-
if (isAddressedToUs) {
|
|
36425
|
-
envelopePayload = frame.payload;
|
|
36426
|
-
logger$a.debug('broadcast_channel_listener_unwrapped_transport_frame', {
|
|
36427
|
-
sender_id: senderId,
|
|
36428
|
-
src: frame.src,
|
|
36429
|
-
dst: frame.dst,
|
|
36430
|
-
});
|
|
36431
|
-
}
|
|
36432
|
-
else {
|
|
36433
|
-
// Frame addressed to a different node, ignore it
|
|
36434
|
-
logger$a.debug('broadcast_channel_listener_ignored_frame_wrong_destination', {
|
|
36435
|
-
sender_id: senderId,
|
|
36436
|
-
dst: frame.dst,
|
|
36437
|
-
expected: this._routingNode.id,
|
|
36438
|
-
});
|
|
36439
|
-
return null;
|
|
36440
|
-
}
|
|
36441
|
-
}
|
|
36442
|
-
}
|
|
36443
|
-
// If not a transport frame, try to coerce as legacy format
|
|
36444
|
-
if (!envelopePayload) {
|
|
36445
|
-
envelopePayload = coercePayload$1(record.payload);
|
|
36446
|
-
if (!envelopePayload) {
|
|
36447
|
-
logger$a.debug('broadcast_channel_listener_ignored_event_without_payload', {
|
|
36448
|
-
sender_id: senderId,
|
|
36449
|
-
});
|
|
36450
|
-
return null;
|
|
36451
|
-
}
|
|
36125
|
+
const payload = coercePayload$1(record.payload);
|
|
36126
|
+
if (!payload) {
|
|
36127
|
+
logger$a.debug('broadcast_channel_listener_ignored_event_without_payload', {
|
|
36128
|
+
sender_id: senderId,
|
|
36129
|
+
});
|
|
36130
|
+
return null;
|
|
36452
36131
|
}
|
|
36453
36132
|
let envelope;
|
|
36454
36133
|
try {
|
|
36455
|
-
const decoded = new TextDecoder().decode(
|
|
36134
|
+
const decoded = new TextDecoder().decode(payload);
|
|
36456
36135
|
const parsed = JSON.parse(decoded);
|
|
36457
36136
|
envelope = core.deserializeEnvelope(parsed);
|
|
36458
36137
|
}
|
|
36459
36138
|
catch (error) {
|
|
36460
36139
|
const decoded = (() => {
|
|
36461
36140
|
try {
|
|
36462
|
-
return new TextDecoder().decode(
|
|
36141
|
+
return new TextDecoder().decode(payload);
|
|
36463
36142
|
}
|
|
36464
36143
|
catch {
|
|
36465
36144
|
return null;
|
|
@@ -36579,20 +36258,6 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36579
36258
|
inboxCapacity: this._inboxCapacity,
|
|
36580
36259
|
};
|
|
36581
36260
|
}
|
|
36582
|
-
// Automatically configure transport frame multiplexing:
|
|
36583
|
-
// Use node IDs (not connector IDs) for node-to-node targeting
|
|
36584
|
-
const broadcastConfig = connectorConfig;
|
|
36585
|
-
// Always force localNodeId to be this listener's node ID
|
|
36586
|
-
// This ensures the sentinel sets localNodeId=sentinel, not the child's ID
|
|
36587
|
-
broadcastConfig.localNodeId = routingNode.id;
|
|
36588
|
-
// Always force remoteNodeId to be the attaching child's system ID
|
|
36589
|
-
broadcastConfig.remoteNodeId = systemId;
|
|
36590
|
-
logger$a.debug('broadcast_channel_listener_configured_node_ids', {
|
|
36591
|
-
sender_id: params.senderId,
|
|
36592
|
-
system_id: systemId,
|
|
36593
|
-
local_node_id: broadcastConfig.localNodeId,
|
|
36594
|
-
remote_node_id: broadcastConfig.remoteNodeId,
|
|
36595
|
-
});
|
|
36596
36261
|
try {
|
|
36597
36262
|
const connector = await routingNode.createOriginConnector({
|
|
36598
36263
|
originType,
|
|
@@ -36662,21 +36327,6 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
36662
36327
|
inboxCandidate > 0) {
|
|
36663
36328
|
config.inboxCapacity = Math.floor(inboxCandidate);
|
|
36664
36329
|
}
|
|
36665
|
-
// Extract transport frame multiplexing node IDs
|
|
36666
|
-
const localNodeIdCandidate = candidate.localNodeId ?? candidate['local_node_id'];
|
|
36667
|
-
if (typeof localNodeIdCandidate === 'string' && localNodeIdCandidate.trim().length > 0) {
|
|
36668
|
-
config.localNodeId = localNodeIdCandidate.trim();
|
|
36669
|
-
logger$a.debug('broadcast_channel_listener_extracted_local_node_id', {
|
|
36670
|
-
local_node_id: config.localNodeId,
|
|
36671
|
-
});
|
|
36672
|
-
}
|
|
36673
|
-
const remoteNodeIdCandidate = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
36674
|
-
if (typeof remoteNodeIdCandidate === 'string' && remoteNodeIdCandidate.trim().length > 0) {
|
|
36675
|
-
config.remoteNodeId = remoteNodeIdCandidate.trim();
|
|
36676
|
-
logger$a.debug('broadcast_channel_listener_extracted_remote_node_id', {
|
|
36677
|
-
remote_node_id: config.remoteNodeId,
|
|
36678
|
-
});
|
|
36679
|
-
}
|
|
36680
36330
|
return config;
|
|
36681
36331
|
}
|
|
36682
36332
|
_monitorConnectorLifecycle(senderId, systemId, connector) {
|
|
@@ -37399,7 +37049,6 @@ class InPageListener extends TransportListener {
|
|
|
37399
37049
|
this._busHandler = null;
|
|
37400
37050
|
this._senderRegistry = new Map();
|
|
37401
37051
|
this._systemToSender = new Map();
|
|
37402
|
-
this._flowIdToSender = new Map();
|
|
37403
37052
|
this._pendingAttachments = new Map();
|
|
37404
37053
|
ensureBrowserEnvironment();
|
|
37405
37054
|
const channelCandidate = options?.channelName;
|
|
@@ -37466,7 +37115,6 @@ class InPageListener extends TransportListener {
|
|
|
37466
37115
|
this._unregisterBusListener();
|
|
37467
37116
|
this._senderRegistry.clear();
|
|
37468
37117
|
this._systemToSender.clear();
|
|
37469
|
-
this._flowIdToSender.clear();
|
|
37470
37118
|
this._pendingAttachments.clear();
|
|
37471
37119
|
logger$7.debug('inpage_listener_stopped', {
|
|
37472
37120
|
channel: this._channelName,
|
|
@@ -37520,25 +37168,10 @@ class InPageListener extends TransportListener {
|
|
|
37520
37168
|
await this._handleAttachFrame(senderId, envelope);
|
|
37521
37169
|
return;
|
|
37522
37170
|
}
|
|
37523
|
-
|
|
37524
|
-
let entry = this._senderRegistry.get(senderId);
|
|
37525
|
-
// If not found and we have a flowId, try to route based on flow
|
|
37526
|
-
if (!entry && envelope.flowId) {
|
|
37527
|
-
const originalSenderId = this._flowIdToSender.get(envelope.flowId);
|
|
37528
|
-
if (originalSenderId) {
|
|
37529
|
-
entry = this._senderRegistry.get(originalSenderId);
|
|
37530
|
-
logger$7.debug('inpage_listener_routed_by_flow_id', {
|
|
37531
|
-
sender_id: senderId,
|
|
37532
|
-
original_sender_id: originalSenderId,
|
|
37533
|
-
flow_id: envelope.flowId,
|
|
37534
|
-
frame_type: envelope.frame?.type ?? 'unknown',
|
|
37535
|
-
});
|
|
37536
|
-
}
|
|
37537
|
-
}
|
|
37171
|
+
const entry = this._senderRegistry.get(senderId);
|
|
37538
37172
|
if (!entry) {
|
|
37539
37173
|
logger$7.debug('inpage_listener_no_connector_for_sender', {
|
|
37540
37174
|
sender_id: senderId,
|
|
37541
|
-
flow_id: envelope.flowId,
|
|
37542
37175
|
frame_type: envelope.frame?.type ?? 'unknown',
|
|
37543
37176
|
});
|
|
37544
37177
|
return;
|
|
@@ -37615,15 +37248,6 @@ class InPageListener extends TransportListener {
|
|
|
37615
37248
|
}
|
|
37616
37249
|
this._senderRegistry.set(senderId, entry);
|
|
37617
37250
|
this._systemToSender.set(entry.systemId, senderId);
|
|
37618
|
-
// Track the flowId if present so we can route responses back
|
|
37619
|
-
if (envelope.flowId) {
|
|
37620
|
-
this._flowIdToSender.set(envelope.flowId, senderId);
|
|
37621
|
-
logger$7.debug('inpage_listener_registered_flow_id', {
|
|
37622
|
-
sender_id: senderId,
|
|
37623
|
-
system_id: entry.systemId,
|
|
37624
|
-
flow_id: envelope.flowId,
|
|
37625
|
-
});
|
|
37626
|
-
}
|
|
37627
37251
|
await this._deliverEnvelope(entry, envelope);
|
|
37628
37252
|
}
|
|
37629
37253
|
async _createConnectorForAttach(params) {
|
|
@@ -37671,7 +37295,7 @@ class InPageListener extends TransportListener {
|
|
|
37671
37295
|
origin_type: originType,
|
|
37672
37296
|
connector_type: connector.constructor?.name ?? 'unknown',
|
|
37673
37297
|
});
|
|
37674
|
-
return { connector, systemId, originType
|
|
37298
|
+
return { connector, systemId, originType };
|
|
37675
37299
|
}
|
|
37676
37300
|
catch (error) {
|
|
37677
37301
|
logger$7.error('inpage_listener_connector_creation_failed', {
|
|
@@ -37725,12 +37349,6 @@ class InPageListener extends TransportListener {
|
|
|
37725
37349
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
37726
37350
|
this._systemToSender.delete(systemId);
|
|
37727
37351
|
}
|
|
37728
|
-
// Clean up flowId mappings for this sender
|
|
37729
|
-
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
37730
|
-
if (sid === senderId) {
|
|
37731
|
-
this._flowIdToSender.delete(flowId);
|
|
37732
|
-
}
|
|
37733
|
-
}
|
|
37734
37352
|
})
|
|
37735
37353
|
.catch((error) => {
|
|
37736
37354
|
logger$7.debug('inpage_listener_wait_until_closed_failed', {
|
|
@@ -37742,24 +37360,9 @@ class InPageListener extends TransportListener {
|
|
|
37742
37360
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
37743
37361
|
this._systemToSender.delete(systemId);
|
|
37744
37362
|
}
|
|
37745
|
-
// Clean up flowId mappings for this sender
|
|
37746
|
-
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
37747
|
-
if (sid === senderId) {
|
|
37748
|
-
this._flowIdToSender.delete(flowId);
|
|
37749
|
-
}
|
|
37750
|
-
}
|
|
37751
37363
|
});
|
|
37752
37364
|
}
|
|
37753
37365
|
async _deliverEnvelope(entry, envelope) {
|
|
37754
|
-
// Track flowId for routing responses back
|
|
37755
|
-
if (envelope.flowId && !this._flowIdToSender.has(envelope.flowId)) {
|
|
37756
|
-
this._flowIdToSender.set(envelope.flowId, entry.senderId);
|
|
37757
|
-
logger$7.debug('inpage_listener_registered_flow_id_on_delivery', {
|
|
37758
|
-
sender_id: entry.senderId,
|
|
37759
|
-
system_id: entry.systemId,
|
|
37760
|
-
flow_id: envelope.flowId,
|
|
37761
|
-
});
|
|
37762
|
-
}
|
|
37763
37366
|
const message = this._buildChannelMessage({
|
|
37764
37367
|
envelope,
|
|
37765
37368
|
connector: entry.connector,
|