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