@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/browser/index.mjs
CHANGED
|
@@ -96,12 +96,12 @@ installProcessEnvShim();
|
|
|
96
96
|
// --- END ENV SHIM ---
|
|
97
97
|
|
|
98
98
|
// This file is auto-generated during build - do not edit manually
|
|
99
|
-
// Generated from package.json version: 0.3.5-test.
|
|
99
|
+
// Generated from package.json version: 0.3.5-test.955
|
|
100
100
|
/**
|
|
101
101
|
* The package version, injected at build time.
|
|
102
102
|
* @internal
|
|
103
103
|
*/
|
|
104
|
-
const VERSION = '0.3.5-test.
|
|
104
|
+
const VERSION = '0.3.5-test.955';
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Fame protocol specific error classes with WebSocket close codes and proper inheritance.
|
|
@@ -919,7 +919,7 @@ class TaskCancelledError extends Error {
|
|
|
919
919
|
* Provides functionality similar to Python's asyncio TaskSpawner with proper
|
|
920
920
|
* error handling, cancellation, and graceful shutdown capabilities.
|
|
921
921
|
*/
|
|
922
|
-
const logger$
|
|
922
|
+
const logger$1c = getLogger('naylence.fame.util.task_spawner');
|
|
923
923
|
function firstDefined(source, keys) {
|
|
924
924
|
for (const key of keys) {
|
|
925
925
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
@@ -1080,7 +1080,7 @@ class TaskSpawner {
|
|
|
1080
1080
|
const taskId = `task-${++this._taskCounter}`;
|
|
1081
1081
|
const taskName = normalizedOptions.name || `unnamed-${taskId}`;
|
|
1082
1082
|
const timeout = normalizedOptions.timeout ?? this._config.defaultTimeout;
|
|
1083
|
-
logger$
|
|
1083
|
+
logger$1c.debug('starting_background_task', {
|
|
1084
1084
|
task_name: taskName,
|
|
1085
1085
|
task_id: taskId,
|
|
1086
1086
|
});
|
|
@@ -1097,7 +1097,7 @@ class TaskSpawner {
|
|
|
1097
1097
|
task.promise
|
|
1098
1098
|
.then(() => {
|
|
1099
1099
|
if (!this._suppressCompletionLogging) {
|
|
1100
|
-
logger$
|
|
1100
|
+
logger$1c.debug('task_completed_successfully', {
|
|
1101
1101
|
task_name: taskName,
|
|
1102
1102
|
task_id: taskId,
|
|
1103
1103
|
duration_ms: Date.now() - task.startTime,
|
|
@@ -1151,7 +1151,7 @@ class TaskSpawner {
|
|
|
1151
1151
|
error.name === 'AbortError' ||
|
|
1152
1152
|
error.message === 'Task cancelled' ||
|
|
1153
1153
|
error.message === 'Aborted') {
|
|
1154
|
-
logger$
|
|
1154
|
+
logger$1c.debug('task_cancelled', {
|
|
1155
1155
|
task_name: taskName,
|
|
1156
1156
|
note: 'Task cancelled as requested',
|
|
1157
1157
|
});
|
|
@@ -1159,7 +1159,7 @@ class TaskSpawner {
|
|
|
1159
1159
|
}
|
|
1160
1160
|
// Handle timeout
|
|
1161
1161
|
if (error instanceof TaskTimeoutError) {
|
|
1162
|
-
logger$
|
|
1162
|
+
logger$1c.warning('task_timed_out', {
|
|
1163
1163
|
task_name: taskName,
|
|
1164
1164
|
error: error.message,
|
|
1165
1165
|
});
|
|
@@ -1171,7 +1171,7 @@ class TaskSpawner {
|
|
|
1171
1171
|
// Handle known WebSocket shutdown race condition (similar to Python version)
|
|
1172
1172
|
if (error.message.includes("await wasn't used with future") ||
|
|
1173
1173
|
error.message.includes('WebSocket closed during receive')) {
|
|
1174
|
-
logger$
|
|
1174
|
+
logger$1c.debug('task_shutdown_race_condition_handled', {
|
|
1175
1175
|
task_name: taskName,
|
|
1176
1176
|
note: 'Normal WebSocket close timing during shutdown - not an error',
|
|
1177
1177
|
});
|
|
@@ -1181,7 +1181,7 @@ class TaskSpawner {
|
|
|
1181
1181
|
if (error.name === 'FameTransportClose' ||
|
|
1182
1182
|
error.message.includes('normal closure') ||
|
|
1183
1183
|
error.message.includes('Connection closed')) {
|
|
1184
|
-
logger$
|
|
1184
|
+
logger$1c.debug('task_shutdown_completed_normally', {
|
|
1185
1185
|
task_name: taskName,
|
|
1186
1186
|
note: 'Task closed normally during shutdown',
|
|
1187
1187
|
});
|
|
@@ -1194,14 +1194,14 @@ class TaskSpawner {
|
|
|
1194
1194
|
// Log retriable errors as warnings (they'll be retried by upstream logic)
|
|
1195
1195
|
// Log non-retriable errors as errors (fatal failures)
|
|
1196
1196
|
if (isRetriableError) {
|
|
1197
|
-
logger$
|
|
1197
|
+
logger$1c.warning('background_task_failed', {
|
|
1198
1198
|
task_name: taskName,
|
|
1199
1199
|
error: error.message,
|
|
1200
1200
|
retriable: true,
|
|
1201
1201
|
});
|
|
1202
1202
|
}
|
|
1203
1203
|
else {
|
|
1204
|
-
logger$
|
|
1204
|
+
logger$1c.error('background_task_failed', {
|
|
1205
1205
|
task_name: taskName,
|
|
1206
1206
|
error: error.message,
|
|
1207
1207
|
stack: error.stack,
|
|
@@ -1220,11 +1220,11 @@ class TaskSpawner {
|
|
|
1220
1220
|
async shutdownTasks(options = {}) {
|
|
1221
1221
|
const { gracePeriod, cancelHanging, joinTimeout } = normalizeShutdownOptions(options);
|
|
1222
1222
|
if (this._tasks.size === 0) {
|
|
1223
|
-
logger$
|
|
1223
|
+
logger$1c.debug('shutdown_tasks_no_tasks_to_shutdown');
|
|
1224
1224
|
return;
|
|
1225
1225
|
}
|
|
1226
1226
|
this._suppressCompletionLogging = true;
|
|
1227
|
-
logger$
|
|
1227
|
+
logger$1c.debug('shutting_down_tasks', {
|
|
1228
1228
|
task_count: this._tasks.size,
|
|
1229
1229
|
task_names: Array.from(this._tasks.values()).map((t) => t.name),
|
|
1230
1230
|
grace_period_ms: gracePeriod,
|
|
@@ -1239,7 +1239,7 @@ class TaskSpawner {
|
|
|
1239
1239
|
if (cancelHanging) {
|
|
1240
1240
|
const stillRunning = tasks.filter((task) => task.getState() === TaskState.RUNNING && !completed.has(task));
|
|
1241
1241
|
if (stillRunning.length > 0) {
|
|
1242
|
-
logger$
|
|
1242
|
+
logger$1c.debug('tasks_did_not_complete_within_grace_period', {
|
|
1243
1243
|
hanging_count: stillRunning.length,
|
|
1244
1244
|
});
|
|
1245
1245
|
// Wait for them to finish with individual timeouts
|
|
@@ -1249,7 +1249,7 @@ class TaskSpawner {
|
|
|
1249
1249
|
}
|
|
1250
1250
|
catch (error) {
|
|
1251
1251
|
if (error instanceof TaskTimeoutError) {
|
|
1252
|
-
logger$
|
|
1252
|
+
logger$1c.warning('task_did_not_shutdown', {
|
|
1253
1253
|
task_name: task.name || task.id,
|
|
1254
1254
|
join_timeout_ms: joinTimeout,
|
|
1255
1255
|
});
|
|
@@ -1260,7 +1260,7 @@ class TaskSpawner {
|
|
|
1260
1260
|
}
|
|
1261
1261
|
else if (!(error instanceof TaskCancelledError)) {
|
|
1262
1262
|
/* istanbul ignore next - unreachable defensive branch */
|
|
1263
|
-
logger$
|
|
1263
|
+
logger$1c.error('task_raised_during_cancellation', {
|
|
1264
1264
|
task_name: task.name || task.id,
|
|
1265
1265
|
error: error instanceof Error ? error.message : String(error),
|
|
1266
1266
|
});
|
|
@@ -2353,6 +2353,7 @@ function validateKeyCorrelationTtlSec(ttlSec) {
|
|
|
2353
2353
|
* condition/promise and ensure at most one notifier coroutine exists for a
|
|
2354
2354
|
* flow at any time.
|
|
2355
2355
|
*/
|
|
2356
|
+
const logger$1b = getLogger('naylence.fame.flow.flow_controller');
|
|
2356
2357
|
/**
|
|
2357
2358
|
* Simple condition variable implementation for TypeScript/Node.js
|
|
2358
2359
|
* Similar to Python's asyncio.Condition
|
|
@@ -2478,8 +2479,17 @@ class FlowController {
|
|
|
2478
2479
|
// clamp into [0, initialWindow]
|
|
2479
2480
|
const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
|
|
2480
2481
|
this.credits.set(flowId, newBalance);
|
|
2482
|
+
const crossedZero = prev <= 0 && newBalance > 0;
|
|
2483
|
+
logger$1b.debug('flow_controller_add_credits', {
|
|
2484
|
+
flow_id: flowId,
|
|
2485
|
+
delta,
|
|
2486
|
+
prev_balance: prev,
|
|
2487
|
+
new_balance: newBalance,
|
|
2488
|
+
initial_window: this.initialWindow,
|
|
2489
|
+
crossed_zero: crossedZero,
|
|
2490
|
+
});
|
|
2481
2491
|
// wake waiters only if we crossed the zero boundary
|
|
2482
|
-
if (
|
|
2492
|
+
if (crossedZero) {
|
|
2483
2493
|
this.wakeWaiters(flowId);
|
|
2484
2494
|
}
|
|
2485
2495
|
return newBalance;
|
|
@@ -2490,11 +2500,27 @@ class FlowController {
|
|
|
2490
2500
|
async acquire(flowId) {
|
|
2491
2501
|
this.ensureFlow(flowId);
|
|
2492
2502
|
const condition = this.conditions.get(flowId);
|
|
2503
|
+
logger$1b.debug('flow_controller_acquire_attempt', {
|
|
2504
|
+
flow_id: flowId,
|
|
2505
|
+
current_balance: this.credits.get(flowId),
|
|
2506
|
+
});
|
|
2493
2507
|
while (this.credits.get(flowId) <= 0) {
|
|
2508
|
+
logger$1b.debug('flow_controller_waiting_for_credit', {
|
|
2509
|
+
flow_id: flowId,
|
|
2510
|
+
});
|
|
2494
2511
|
await condition.wait();
|
|
2512
|
+
logger$1b.debug('flow_controller_woke_with_credit', {
|
|
2513
|
+
flow_id: flowId,
|
|
2514
|
+
balance_after_wake: this.credits.get(flowId),
|
|
2515
|
+
});
|
|
2495
2516
|
}
|
|
2496
2517
|
const current = this.credits.get(flowId);
|
|
2497
2518
|
this.credits.set(flowId, current - 1);
|
|
2519
|
+
logger$1b.debug('flow_controller_credit_consumed', {
|
|
2520
|
+
flow_id: flowId,
|
|
2521
|
+
prev_balance: current,
|
|
2522
|
+
remaining_balance: current - 1,
|
|
2523
|
+
});
|
|
2498
2524
|
}
|
|
2499
2525
|
/**
|
|
2500
2526
|
* Consume *credits* immediately (non-blocking).
|
|
@@ -2514,6 +2540,12 @@ class FlowController {
|
|
|
2514
2540
|
const current = this.credits.get(flowId);
|
|
2515
2541
|
const remaining = Math.max(current - credits, 0);
|
|
2516
2542
|
this.credits.set(flowId, remaining);
|
|
2543
|
+
logger$1b.debug('flow_controller_consume', {
|
|
2544
|
+
flow_id: flowId,
|
|
2545
|
+
requested: credits,
|
|
2546
|
+
prev_balance: current,
|
|
2547
|
+
remaining_balance: remaining,
|
|
2548
|
+
});
|
|
2517
2549
|
return remaining;
|
|
2518
2550
|
}
|
|
2519
2551
|
/**
|
|
@@ -2534,6 +2566,10 @@ class FlowController {
|
|
|
2534
2566
|
this.windowIds.delete(flowId);
|
|
2535
2567
|
this.credits.set(flowId, this.initialWindow);
|
|
2536
2568
|
this.wakeWaiters(flowId);
|
|
2569
|
+
logger$1b.debug('flow_controller_flow_reset', {
|
|
2570
|
+
flow_id: flowId,
|
|
2571
|
+
reset_balance: this.initialWindow,
|
|
2572
|
+
});
|
|
2537
2573
|
}
|
|
2538
2574
|
/**
|
|
2539
2575
|
* Return `[windowId, flags]` for the next outbound envelope.
|
|
@@ -9816,84 +9852,6 @@ class BoundedAsyncQueue {
|
|
|
9816
9852
|
}
|
|
9817
9853
|
}
|
|
9818
9854
|
|
|
9819
|
-
/**
|
|
9820
|
-
* Transport frame layer for multiplexing logical links on physical channels.
|
|
9821
|
-
*
|
|
9822
|
-
* This lightweight framing layer wraps raw FAME payloads to enable multiple
|
|
9823
|
-
* logical connections over a single physical channel (BroadcastChannel or InPage bus).
|
|
9824
|
-
*
|
|
9825
|
-
* The transport frame does NOT modify FAME envelopes - it only wraps the raw
|
|
9826
|
-
* Uint8Array payload at the connector level.
|
|
9827
|
-
*/
|
|
9828
|
-
/**
|
|
9829
|
-
* Transport frame version for future compatibility
|
|
9830
|
-
*/
|
|
9831
|
-
const TRANSPORT_FRAME_VERSION = 1;
|
|
9832
|
-
/**
|
|
9833
|
-
* Wrap a raw payload in a transport frame
|
|
9834
|
-
*
|
|
9835
|
-
* @param payload - Raw FAME envelope bytes
|
|
9836
|
-
* @param srcNodeId - Local node ID (this connector)
|
|
9837
|
-
* @param dstNodeId - Remote node ID (target connector)
|
|
9838
|
-
* @returns Transport frame ready for transmission
|
|
9839
|
-
*/
|
|
9840
|
-
function wrapTransportFrame(payload, srcNodeId, dstNodeId) {
|
|
9841
|
-
return {
|
|
9842
|
-
v: TRANSPORT_FRAME_VERSION,
|
|
9843
|
-
src: srcNodeId,
|
|
9844
|
-
dst: dstNodeId,
|
|
9845
|
-
payload,
|
|
9846
|
-
};
|
|
9847
|
-
}
|
|
9848
|
-
/**
|
|
9849
|
-
* Serialize a transport frame for transmission over the bus
|
|
9850
|
-
*
|
|
9851
|
-
* @param frame - Transport frame to serialize
|
|
9852
|
-
* @returns Serialized frame data ready for postMessage/dispatchEvent
|
|
9853
|
-
*/
|
|
9854
|
-
function serializeTransportFrame(frame) {
|
|
9855
|
-
// Convert Uint8Array to regular array for JSON serialization
|
|
9856
|
-
const serializable = {
|
|
9857
|
-
v: frame.v,
|
|
9858
|
-
src: frame.src,
|
|
9859
|
-
dst: frame.dst,
|
|
9860
|
-
payload: Array.from(frame.payload),
|
|
9861
|
-
};
|
|
9862
|
-
return serializable;
|
|
9863
|
-
}
|
|
9864
|
-
/**
|
|
9865
|
-
* Unwrap a transport frame (pure deserializer - no filtering)
|
|
9866
|
-
*
|
|
9867
|
-
* @param raw - Raw data from the bus
|
|
9868
|
-
* @returns Unwrapped frame with payload as Uint8Array, or null if invalid structure
|
|
9869
|
-
*/
|
|
9870
|
-
function unwrapTransportFrame(raw) {
|
|
9871
|
-
// Validate basic structure
|
|
9872
|
-
if (!raw || typeof raw !== 'object') {
|
|
9873
|
-
return null;
|
|
9874
|
-
}
|
|
9875
|
-
const frame = raw;
|
|
9876
|
-
// Check version
|
|
9877
|
-
if (frame.v !== TRANSPORT_FRAME_VERSION) {
|
|
9878
|
-
return null;
|
|
9879
|
-
}
|
|
9880
|
-
// Check src and dst
|
|
9881
|
-
if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
|
|
9882
|
-
return null;
|
|
9883
|
-
}
|
|
9884
|
-
// Extract payload
|
|
9885
|
-
if (!frame.payload || !Array.isArray(frame.payload)) {
|
|
9886
|
-
return null;
|
|
9887
|
-
}
|
|
9888
|
-
// Convert array back to Uint8Array and return full frame
|
|
9889
|
-
return {
|
|
9890
|
-
v: frame.v,
|
|
9891
|
-
src: frame.src,
|
|
9892
|
-
dst: frame.dst,
|
|
9893
|
-
payload: Uint8Array.from(frame.payload),
|
|
9894
|
-
};
|
|
9895
|
-
}
|
|
9896
|
-
|
|
9897
9855
|
const logger$_ = getLogger('naylence.fame.connector.broadcast_channel_connector');
|
|
9898
9856
|
const BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
|
|
9899
9857
|
const DEFAULT_CHANNEL$7 = 'naylence-fabric';
|
|
@@ -9957,22 +9915,12 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
9957
9915
|
? Math.floor(config.inboxCapacity)
|
|
9958
9916
|
: DEFAULT_INBOX_CAPACITY$7;
|
|
9959
9917
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
9918
|
+
this.inboxCapacity = preferredCapacity;
|
|
9960
9919
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
9961
9920
|
this.channel = new BroadcastChannel(this.channelName);
|
|
9962
|
-
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
9963
|
-
this.localNodeId =
|
|
9964
|
-
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
9965
|
-
? config.localNodeId.trim()
|
|
9966
|
-
: this.connectorId;
|
|
9967
|
-
this.remoteNodeId =
|
|
9968
|
-
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
9969
|
-
? config.remoteNodeId.trim()
|
|
9970
|
-
: '*'; // Accept from any remote if not specified
|
|
9971
9921
|
logger$_.debug('broadcast_channel_connector_created', {
|
|
9972
9922
|
channel: this.channelName,
|
|
9973
9923
|
connector_id: this.connectorId,
|
|
9974
|
-
local_node_id: this.localNodeId,
|
|
9975
|
-
remote_node_id: this.remoteNodeId,
|
|
9976
9924
|
inbox_capacity: preferredCapacity,
|
|
9977
9925
|
timestamp: new Date().toISOString(),
|
|
9978
9926
|
});
|
|
@@ -10005,67 +9953,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10005
9953
|
if (busMessage.senderId === this.connectorId) {
|
|
10006
9954
|
return;
|
|
10007
9955
|
}
|
|
10008
|
-
// Try to unwrap as transport frame
|
|
10009
|
-
const frame = unwrapTransportFrame(busMessage.payload);
|
|
10010
|
-
if (frame) {
|
|
10011
|
-
// Apply connector's filtering policy: strict dst check, src accepts wildcard
|
|
10012
|
-
const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
|
|
10013
|
-
const dstMatches = frame.dst === this.localNodeId;
|
|
10014
|
-
if (dstMatches && srcMatches) {
|
|
10015
|
-
// Successfully received and filtered transport frame
|
|
10016
|
-
logger$_.debug('broadcast_channel_transport_frame_received', {
|
|
10017
|
-
channel: this.channelName,
|
|
10018
|
-
sender_id: busMessage.senderId,
|
|
10019
|
-
connector_id: this.connectorId,
|
|
10020
|
-
local_node_id: this.localNodeId,
|
|
10021
|
-
remote_node_id: this.remoteNodeId,
|
|
10022
|
-
frame_src: frame.src,
|
|
10023
|
-
frame_dst: frame.dst,
|
|
10024
|
-
payload_length: frame.payload.byteLength,
|
|
10025
|
-
});
|
|
10026
|
-
const unwrapped = frame.payload;
|
|
10027
|
-
if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
|
|
10028
|
-
return;
|
|
10029
|
-
}
|
|
10030
|
-
try {
|
|
10031
|
-
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
10032
|
-
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
10033
|
-
if (accepted) {
|
|
10034
|
-
return;
|
|
10035
|
-
}
|
|
10036
|
-
}
|
|
10037
|
-
this.inbox.enqueue(unwrapped);
|
|
10038
|
-
}
|
|
10039
|
-
catch (error) {
|
|
10040
|
-
if (error instanceof QueueFullError) {
|
|
10041
|
-
logger$_.warning('broadcast_channel_receive_queue_full', {
|
|
10042
|
-
channel: this.channelName,
|
|
10043
|
-
});
|
|
10044
|
-
}
|
|
10045
|
-
else {
|
|
10046
|
-
logger$_.error('broadcast_channel_receive_error', {
|
|
10047
|
-
channel: this.channelName,
|
|
10048
|
-
error: error instanceof Error ? error.message : String(error),
|
|
10049
|
-
});
|
|
10050
|
-
}
|
|
10051
|
-
}
|
|
10052
|
-
return;
|
|
10053
|
-
}
|
|
10054
|
-
else {
|
|
10055
|
-
// Frame filtered out by addressing rules
|
|
10056
|
-
logger$_.debug('broadcast_channel_transport_frame_filtered', {
|
|
10057
|
-
channel: this.channelName,
|
|
10058
|
-
connector_id: this.connectorId,
|
|
10059
|
-
local_node_id: this.localNodeId,
|
|
10060
|
-
remote_node_id: this.remoteNodeId,
|
|
10061
|
-
frame_src: frame.src,
|
|
10062
|
-
frame_dst: frame.dst,
|
|
10063
|
-
reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
|
|
10064
|
-
});
|
|
10065
|
-
return;
|
|
10066
|
-
}
|
|
10067
|
-
}
|
|
10068
|
-
// Fall back to legacy format (no transport frame)
|
|
10069
9956
|
const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
|
|
10070
9957
|
if (!payload) {
|
|
10071
9958
|
logger$_.debug('broadcast_channel_payload_rejected', {
|
|
@@ -10088,15 +9975,27 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10088
9975
|
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
10089
9976
|
const accepted = this.inbox.tryEnqueue(payload);
|
|
10090
9977
|
if (accepted) {
|
|
9978
|
+
this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
|
|
9979
|
+
source: 'listener',
|
|
9980
|
+
enqueue_strategy: 'try',
|
|
9981
|
+
payload_length: payload.byteLength,
|
|
9982
|
+
});
|
|
10091
9983
|
return;
|
|
10092
9984
|
}
|
|
10093
9985
|
}
|
|
10094
9986
|
this.inbox.enqueue(payload);
|
|
9987
|
+
this.logInboxSnapshot('broadcast_channel_inbox_enqueued', {
|
|
9988
|
+
source: 'listener',
|
|
9989
|
+
enqueue_strategy: 'enqueue',
|
|
9990
|
+
payload_length: payload.byteLength,
|
|
9991
|
+
});
|
|
10095
9992
|
}
|
|
10096
9993
|
catch (error) {
|
|
10097
9994
|
if (error instanceof QueueFullError) {
|
|
10098
9995
|
logger$_.warning('broadcast_channel_receive_queue_full', {
|
|
10099
9996
|
channel: this.channelName,
|
|
9997
|
+
inbox_capacity: this.inboxCapacity,
|
|
9998
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
10100
9999
|
});
|
|
10101
10000
|
}
|
|
10102
10001
|
else {
|
|
@@ -10180,15 +10079,25 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10180
10079
|
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
10181
10080
|
const accepted = this.inbox.tryEnqueue(item);
|
|
10182
10081
|
if (accepted) {
|
|
10082
|
+
this.logInboxSnapshot('broadcast_channel_push_enqueued', {
|
|
10083
|
+
enqueue_strategy: 'try',
|
|
10084
|
+
item_type: this._describeInboxItem(item),
|
|
10085
|
+
});
|
|
10183
10086
|
return;
|
|
10184
10087
|
}
|
|
10185
10088
|
}
|
|
10186
10089
|
this.inbox.enqueue(item);
|
|
10090
|
+
this.logInboxSnapshot('broadcast_channel_push_enqueued', {
|
|
10091
|
+
enqueue_strategy: 'enqueue',
|
|
10092
|
+
item_type: this._describeInboxItem(item),
|
|
10093
|
+
});
|
|
10187
10094
|
}
|
|
10188
10095
|
catch (error) {
|
|
10189
10096
|
if (error instanceof QueueFullError) {
|
|
10190
10097
|
logger$_.warning('broadcast_channel_push_queue_full', {
|
|
10191
10098
|
channel: this.channelName,
|
|
10099
|
+
inbox_capacity: this.inboxCapacity,
|
|
10100
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
10192
10101
|
});
|
|
10193
10102
|
throw error;
|
|
10194
10103
|
}
|
|
@@ -10204,30 +10113,18 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10204
10113
|
logger$_.debug('broadcast_channel_message_sending', {
|
|
10205
10114
|
channel: this.channelName,
|
|
10206
10115
|
sender_id: this.connectorId,
|
|
10207
|
-
|
|
10208
|
-
remote_node_id: this.remoteNodeId,
|
|
10209
|
-
});
|
|
10210
|
-
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
10211
|
-
// (not using default values). This ensures backwards compatibility.
|
|
10212
|
-
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
10213
|
-
this.remoteNodeId !== '*';
|
|
10214
|
-
let payload;
|
|
10215
|
-
if (useTransportFrame) {
|
|
10216
|
-
// Wrap payload in transport frame
|
|
10217
|
-
const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
|
|
10218
|
-
payload = serializeTransportFrame(frame);
|
|
10219
|
-
}
|
|
10220
|
-
else {
|
|
10221
|
-
// Legacy format: send raw payload
|
|
10222
|
-
payload = data;
|
|
10223
|
-
}
|
|
10116
|
+
});
|
|
10224
10117
|
this.channel.postMessage({
|
|
10225
10118
|
senderId: this.connectorId,
|
|
10226
|
-
payload,
|
|
10119
|
+
payload: data,
|
|
10227
10120
|
});
|
|
10228
10121
|
}
|
|
10229
10122
|
async _transportReceive() {
|
|
10230
|
-
|
|
10123
|
+
const item = await this.inbox.dequeue();
|
|
10124
|
+
this.logInboxSnapshot('broadcast_channel_inbox_dequeued', {
|
|
10125
|
+
item_type: this._describeInboxItem(item),
|
|
10126
|
+
});
|
|
10127
|
+
return item;
|
|
10231
10128
|
}
|
|
10232
10129
|
async _transportClose(code, reason) {
|
|
10233
10130
|
logger$_.debug('broadcast_channel_transport_closing', {
|
|
@@ -10281,6 +10178,28 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10281
10178
|
}
|
|
10282
10179
|
return rawOrEnvelope;
|
|
10283
10180
|
}
|
|
10181
|
+
_describeInboxItem(item) {
|
|
10182
|
+
if (item instanceof Uint8Array) {
|
|
10183
|
+
return 'bytes';
|
|
10184
|
+
}
|
|
10185
|
+
if (item.envelope) {
|
|
10186
|
+
return 'channel_message';
|
|
10187
|
+
}
|
|
10188
|
+
if (item.frame) {
|
|
10189
|
+
return 'envelope';
|
|
10190
|
+
}
|
|
10191
|
+
return 'unknown';
|
|
10192
|
+
}
|
|
10193
|
+
logInboxSnapshot(event, extra = {}) {
|
|
10194
|
+
logger$_.debug(event, {
|
|
10195
|
+
channel: this.channelName,
|
|
10196
|
+
connector_id: this.connectorId,
|
|
10197
|
+
connector_state: this.state,
|
|
10198
|
+
inbox_capacity: this.inboxCapacity,
|
|
10199
|
+
inbox_remaining_capacity: this.inbox.remainingCapacity,
|
|
10200
|
+
...extra,
|
|
10201
|
+
});
|
|
10202
|
+
}
|
|
10284
10203
|
_shouldSkipDuplicateAck(senderId, payload) {
|
|
10285
10204
|
const dedupKey = this._extractAckDedupKey(payload);
|
|
10286
10205
|
if (!dedupKey) {
|
|
@@ -10379,24 +10298,6 @@ let BroadcastChannelConnector$2 = class BroadcastChannelConnector extends BaseAs
|
|
|
10379
10298
|
});
|
|
10380
10299
|
}
|
|
10381
10300
|
}
|
|
10382
|
-
/**
|
|
10383
|
-
* Update the remote node ID after learning it from NodeAttachAck
|
|
10384
|
-
* This allows upstream connectors to switch from wildcard to specific addressing
|
|
10385
|
-
*/
|
|
10386
|
-
updateRemoteNodeId(newRemoteNodeId) {
|
|
10387
|
-
if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
|
|
10388
|
-
throw new Error('Invalid remote node ID');
|
|
10389
|
-
}
|
|
10390
|
-
const oldValue = this.remoteNodeId;
|
|
10391
|
-
this.remoteNodeId = newRemoteNodeId.trim();
|
|
10392
|
-
logger$_.debug('broadcast_channel_connector_remote_node_id_updated', {
|
|
10393
|
-
channel: this.channelName,
|
|
10394
|
-
connector_id: this.connectorId,
|
|
10395
|
-
local_node_id: this.localNodeId,
|
|
10396
|
-
old_remote_node_id: oldValue,
|
|
10397
|
-
new_remote_node_id: this.remoteNodeId,
|
|
10398
|
-
});
|
|
10399
|
-
}
|
|
10400
10301
|
_trimSeenAcks(now) {
|
|
10401
10302
|
while (this.seenAckOrder.length > 0) {
|
|
10402
10303
|
const candidate = this.seenAckOrder[0];
|
|
@@ -10534,12 +10435,9 @@ function isBroadcastChannelConnectionGrant(candidate) {
|
|
|
10534
10435
|
record.inboxCapacity <= 0)) {
|
|
10535
10436
|
return false;
|
|
10536
10437
|
}
|
|
10537
|
-
if (record.
|
|
10538
|
-
(
|
|
10539
|
-
|
|
10540
|
-
}
|
|
10541
|
-
if (record.remoteNodeId !== undefined &&
|
|
10542
|
-
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
10438
|
+
if (record.initialWindow !== undefined &&
|
|
10439
|
+
(!Number.isFinite(record.initialWindow) ||
|
|
10440
|
+
record.initialWindow <= 0)) {
|
|
10543
10441
|
return false;
|
|
10544
10442
|
}
|
|
10545
10443
|
return true;
|
|
@@ -10575,19 +10473,14 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
|
10575
10473
|
}
|
|
10576
10474
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
10577
10475
|
}
|
|
10578
|
-
const
|
|
10579
|
-
if (
|
|
10580
|
-
if (typeof
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
}
|
|
10585
|
-
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
10586
|
-
if (remoteNodeIdValue !== undefined) {
|
|
10587
|
-
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
10588
|
-
throw new TypeError('BroadcastChannelConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
10476
|
+
const windowValue = candidate.initialWindow ?? candidate['initial_window'];
|
|
10477
|
+
if (windowValue !== undefined) {
|
|
10478
|
+
if (typeof windowValue !== 'number' ||
|
|
10479
|
+
!Number.isFinite(windowValue) ||
|
|
10480
|
+
windowValue <= 0) {
|
|
10481
|
+
throw new TypeError('BroadcastChannelConnectionGrant "initialWindow" must be a positive number when provided');
|
|
10589
10482
|
}
|
|
10590
|
-
result.
|
|
10483
|
+
result.initialWindow = Math.floor(windowValue);
|
|
10591
10484
|
}
|
|
10592
10485
|
return result;
|
|
10593
10486
|
}
|
|
@@ -10602,11 +10495,8 @@ function broadcastChannelGrantToConnectorConfig(grant) {
|
|
|
10602
10495
|
if (normalized.inboxCapacity !== undefined) {
|
|
10603
10496
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
10604
10497
|
}
|
|
10605
|
-
if (normalized.
|
|
10606
|
-
config.
|
|
10607
|
-
}
|
|
10608
|
-
if (normalized.remoteNodeId) {
|
|
10609
|
-
config.remoteNodeId = normalized.remoteNodeId;
|
|
10498
|
+
if (normalized.initialWindow !== undefined) {
|
|
10499
|
+
config.initialWindow = normalized.initialWindow;
|
|
10610
10500
|
}
|
|
10611
10501
|
return config;
|
|
10612
10502
|
}
|
|
@@ -10898,12 +10788,6 @@ class UpstreamSessionManager extends TaskSpawner {
|
|
|
10898
10788
|
cryptoProvider.prepareForAttach(welcome.frame.systemId, welcome.frame.assignedPath, welcome.frame.acceptedLogicals ?? []);
|
|
10899
10789
|
}
|
|
10900
10790
|
await this.onWelcome(welcome.frame);
|
|
10901
|
-
// Inject node ID into grant for transport frame multiplexing
|
|
10902
|
-
// This ensures localNodeId matches the node's systemId for proper frame filtering
|
|
10903
|
-
grant.localNodeId = welcome.frame.systemId;
|
|
10904
|
-
if (welcome.frame.targetSystemId) {
|
|
10905
|
-
grant.remoteNodeId = welcome.frame.targetSystemId;
|
|
10906
|
-
}
|
|
10907
10791
|
const connector = await ConnectorFactory.createConnector(grant, {
|
|
10908
10792
|
systemId: welcome.frame.systemId,
|
|
10909
10793
|
});
|
|
@@ -12860,20 +12744,6 @@ class DefaultNodeAttachClient {
|
|
|
12860
12744
|
if (!targetSystemId) {
|
|
12861
12745
|
throw new Error('Target system ID must be set in NodeAttachAckFrame on success');
|
|
12862
12746
|
}
|
|
12863
|
-
// Update connector's remote node ID if it supports it (e.g., BroadcastChannelConnector, InPageConnector)
|
|
12864
|
-
// This allows upstream connectors to switch from wildcard '*' to specific node addressing
|
|
12865
|
-
const updatableConnector = connector;
|
|
12866
|
-
if (typeof updatableConnector.updateRemoteNodeId === 'function') {
|
|
12867
|
-
try {
|
|
12868
|
-
updatableConnector.updateRemoteNodeId(targetSystemId);
|
|
12869
|
-
}
|
|
12870
|
-
catch (error) {
|
|
12871
|
-
logger$W.debug('connector_remote_node_id_update_failed', {
|
|
12872
|
-
target_system_id: targetSystemId,
|
|
12873
|
-
error: error instanceof Error ? error.message : String(error),
|
|
12874
|
-
});
|
|
12875
|
-
}
|
|
12876
|
-
}
|
|
12877
12747
|
try {
|
|
12878
12748
|
if (this.replicaStickinessManager) {
|
|
12879
12749
|
this.replicaStickinessManager.accept(ackFrame.stickiness ?? null);
|
|
@@ -20574,20 +20444,9 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20574
20444
|
: DEFAULT_INBOX_CAPACITY$6;
|
|
20575
20445
|
this.inbox = new BoundedAsyncQueue(preferredCapacity);
|
|
20576
20446
|
this.connectorId = InPageConnector.generateConnectorId();
|
|
20577
|
-
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
20578
|
-
this.localNodeId =
|
|
20579
|
-
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
20580
|
-
? config.localNodeId.trim()
|
|
20581
|
-
: this.connectorId;
|
|
20582
|
-
this.remoteNodeId =
|
|
20583
|
-
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
20584
|
-
? config.remoteNodeId.trim()
|
|
20585
|
-
: '*'; // Accept from any remote if not specified
|
|
20586
20447
|
logger$G.debug('inpage_connector_initialized', {
|
|
20587
20448
|
channel: this.channelName,
|
|
20588
20449
|
connector_id: this.connectorId,
|
|
20589
|
-
local_node_id: this.localNodeId,
|
|
20590
|
-
remote_node_id: this.remoteNodeId,
|
|
20591
20450
|
});
|
|
20592
20451
|
this.onMsg = (event) => {
|
|
20593
20452
|
const messageEvent = event;
|
|
@@ -20621,64 +20480,6 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20621
20480
|
if (busMessage.senderId === this.connectorId) {
|
|
20622
20481
|
return;
|
|
20623
20482
|
}
|
|
20624
|
-
// Try to unwrap as transport frame
|
|
20625
|
-
const frame = unwrapTransportFrame(busMessage.payload);
|
|
20626
|
-
if (frame) {
|
|
20627
|
-
// Apply connector's filtering policy: strict dst check, src accepts wildcard
|
|
20628
|
-
const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
|
|
20629
|
-
const dstMatches = frame.dst === this.localNodeId;
|
|
20630
|
-
if (dstMatches && srcMatches) {
|
|
20631
|
-
// Successfully received and filtered transport frame
|
|
20632
|
-
logger$G.debug('inpage_transport_frame_received', {
|
|
20633
|
-
channel: this.channelName,
|
|
20634
|
-
sender_id: busMessage.senderId,
|
|
20635
|
-
connector_id: this.connectorId,
|
|
20636
|
-
local_node_id: this.localNodeId,
|
|
20637
|
-
remote_node_id: this.remoteNodeId,
|
|
20638
|
-
frame_src: frame.src,
|
|
20639
|
-
frame_dst: frame.dst,
|
|
20640
|
-
payload_length: frame.payload.byteLength,
|
|
20641
|
-
});
|
|
20642
|
-
const unwrapped = frame.payload;
|
|
20643
|
-
try {
|
|
20644
|
-
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
20645
|
-
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
20646
|
-
if (accepted) {
|
|
20647
|
-
return;
|
|
20648
|
-
}
|
|
20649
|
-
}
|
|
20650
|
-
this.inbox.enqueue(unwrapped);
|
|
20651
|
-
}
|
|
20652
|
-
catch (error) {
|
|
20653
|
-
if (error instanceof QueueFullError) {
|
|
20654
|
-
logger$G.warning('inpage_receive_queue_full', {
|
|
20655
|
-
channel: this.channelName,
|
|
20656
|
-
});
|
|
20657
|
-
}
|
|
20658
|
-
else {
|
|
20659
|
-
logger$G.error('inpage_receive_error', {
|
|
20660
|
-
channel: this.channelName,
|
|
20661
|
-
error: error instanceof Error ? error.message : String(error),
|
|
20662
|
-
});
|
|
20663
|
-
}
|
|
20664
|
-
}
|
|
20665
|
-
return;
|
|
20666
|
-
}
|
|
20667
|
-
else {
|
|
20668
|
-
// Frame filtered out by addressing rules
|
|
20669
|
-
logger$G.debug('inpage_transport_frame_filtered', {
|
|
20670
|
-
channel: this.channelName,
|
|
20671
|
-
connector_id: this.connectorId,
|
|
20672
|
-
local_node_id: this.localNodeId,
|
|
20673
|
-
remote_node_id: this.remoteNodeId,
|
|
20674
|
-
frame_src: frame.src,
|
|
20675
|
-
frame_dst: frame.dst,
|
|
20676
|
-
reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
|
|
20677
|
-
});
|
|
20678
|
-
return;
|
|
20679
|
-
}
|
|
20680
|
-
}
|
|
20681
|
-
// Fall back to legacy format (no transport frame)
|
|
20682
20483
|
const payload = InPageConnector.coercePayload(busMessage.payload);
|
|
20683
20484
|
if (!payload) {
|
|
20684
20485
|
logger$G.debug('inpage_payload_rejected', {
|
|
@@ -20837,27 +20638,11 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20837
20638
|
logger$G.debug('inpage_message_sending', {
|
|
20838
20639
|
channel: this.channelName,
|
|
20839
20640
|
sender_id: this.connectorId,
|
|
20840
|
-
|
|
20841
|
-
remote_node_id: this.remoteNodeId,
|
|
20842
|
-
});
|
|
20843
|
-
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
20844
|
-
// (not using default values). This ensures backwards compatibility.
|
|
20845
|
-
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
20846
|
-
this.remoteNodeId !== '*';
|
|
20847
|
-
let payload;
|
|
20848
|
-
if (useTransportFrame) {
|
|
20849
|
-
// Wrap payload in transport frame
|
|
20850
|
-
const frame = wrapTransportFrame(data, this.localNodeId, this.remoteNodeId);
|
|
20851
|
-
payload = serializeTransportFrame(frame);
|
|
20852
|
-
}
|
|
20853
|
-
else {
|
|
20854
|
-
// Legacy format: send raw payload
|
|
20855
|
-
payload = data;
|
|
20856
|
-
}
|
|
20641
|
+
});
|
|
20857
20642
|
const event = new MessageEvent(this.channelName, {
|
|
20858
20643
|
data: {
|
|
20859
20644
|
senderId: this.connectorId,
|
|
20860
|
-
payload,
|
|
20645
|
+
payload: data,
|
|
20861
20646
|
},
|
|
20862
20647
|
});
|
|
20863
20648
|
getSharedBus$1().dispatchEvent(event);
|
|
@@ -20886,24 +20671,6 @@ class InPageConnector extends BaseAsyncConnector {
|
|
|
20886
20671
|
}
|
|
20887
20672
|
return rawOrEnvelope;
|
|
20888
20673
|
}
|
|
20889
|
-
/**
|
|
20890
|
-
* Update the remote node ID after learning it from NodeAttachAck
|
|
20891
|
-
* This allows upstream connectors to switch from wildcard to specific addressing
|
|
20892
|
-
*/
|
|
20893
|
-
updateRemoteNodeId(newRemoteNodeId) {
|
|
20894
|
-
if (typeof newRemoteNodeId !== 'string' || newRemoteNodeId.trim().length === 0) {
|
|
20895
|
-
throw new Error('Invalid remote node ID');
|
|
20896
|
-
}
|
|
20897
|
-
const oldValue = this.remoteNodeId;
|
|
20898
|
-
this.remoteNodeId = newRemoteNodeId.trim();
|
|
20899
|
-
logger$G.debug('inpage_connector_remote_node_id_updated', {
|
|
20900
|
-
channel: this.channelName,
|
|
20901
|
-
connector_id: this.connectorId,
|
|
20902
|
-
local_node_id: this.localNodeId,
|
|
20903
|
-
old_remote_node_id: oldValue,
|
|
20904
|
-
new_remote_node_id: this.remoteNodeId,
|
|
20905
|
-
});
|
|
20906
|
-
}
|
|
20907
20674
|
}
|
|
20908
20675
|
|
|
20909
20676
|
const RPC_REGISTRY = Symbol('naylence.rpc.registry');
|
|
@@ -28240,14 +28007,6 @@ function isInPageConnectionGrant(candidate) {
|
|
|
28240
28007
|
record.inboxCapacity <= 0)) {
|
|
28241
28008
|
return false;
|
|
28242
28009
|
}
|
|
28243
|
-
if (record.localNodeId !== undefined &&
|
|
28244
|
-
(typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
|
|
28245
|
-
return false;
|
|
28246
|
-
}
|
|
28247
|
-
if (record.remoteNodeId !== undefined &&
|
|
28248
|
-
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
28249
|
-
return false;
|
|
28250
|
-
}
|
|
28251
28010
|
return true;
|
|
28252
28011
|
}
|
|
28253
28012
|
function normalizeInPageConnectionGrant(candidate) {
|
|
@@ -28281,20 +28040,6 @@ function normalizeInPageConnectionGrant(candidate) {
|
|
|
28281
28040
|
}
|
|
28282
28041
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
28283
28042
|
}
|
|
28284
|
-
const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
|
|
28285
|
-
if (localNodeIdValue !== undefined) {
|
|
28286
|
-
if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
|
|
28287
|
-
throw new TypeError('InPageConnectionGrant "localNodeId" must be a non-empty string when provided');
|
|
28288
|
-
}
|
|
28289
|
-
result.localNodeId = localNodeIdValue.trim();
|
|
28290
|
-
}
|
|
28291
|
-
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
28292
|
-
if (remoteNodeIdValue !== undefined) {
|
|
28293
|
-
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
28294
|
-
throw new TypeError('InPageConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
28295
|
-
}
|
|
28296
|
-
result.remoteNodeId = remoteNodeIdValue.trim();
|
|
28297
|
-
}
|
|
28298
28043
|
return result;
|
|
28299
28044
|
}
|
|
28300
28045
|
function inPageGrantToConnectorConfig(grant) {
|
|
@@ -28308,12 +28053,6 @@ function inPageGrantToConnectorConfig(grant) {
|
|
|
28308
28053
|
if (normalized.inboxCapacity !== undefined) {
|
|
28309
28054
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
28310
28055
|
}
|
|
28311
|
-
if (normalized.localNodeId) {
|
|
28312
|
-
config.localNodeId = normalized.localNodeId;
|
|
28313
|
-
}
|
|
28314
|
-
if (normalized.remoteNodeId) {
|
|
28315
|
-
config.remoteNodeId = normalized.remoteNodeId;
|
|
28316
|
-
}
|
|
28317
28056
|
return config;
|
|
28318
28057
|
}
|
|
28319
28058
|
|
|
@@ -28935,8 +28674,6 @@ class InPageConnectorFactory extends ConnectorFactory {
|
|
|
28935
28674
|
type: INPAGE_CONNECTOR_TYPE,
|
|
28936
28675
|
channelName,
|
|
28937
28676
|
inboxCapacity,
|
|
28938
|
-
localNodeId: normalized.localNodeId,
|
|
28939
|
-
remoteNodeId: normalized.remoteNodeId,
|
|
28940
28677
|
};
|
|
28941
28678
|
const connector = new InPageConnector(connectorConfig, baseConfig);
|
|
28942
28679
|
if (options.authorization) {
|
|
@@ -29005,16 +28742,6 @@ class InPageConnectorFactory extends ConnectorFactory {
|
|
|
29005
28742
|
if (candidate.authorizationContext !== undefined) {
|
|
29006
28743
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
29007
28744
|
}
|
|
29008
|
-
// Handle localNodeId
|
|
29009
|
-
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
29010
|
-
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
29011
|
-
normalized.localNodeId = localNodeId.trim();
|
|
29012
|
-
}
|
|
29013
|
-
// Handle remoteNodeId
|
|
29014
|
-
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
29015
|
-
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
29016
|
-
normalized.remoteNodeId = remoteNodeId.trim();
|
|
29017
|
-
}
|
|
29018
28745
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$5;
|
|
29019
28746
|
normalized.inboxCapacity =
|
|
29020
28747
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$5;
|
|
@@ -29065,8 +28792,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
29065
28792
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
29066
28793
|
channelName: connectorConfig.channelName,
|
|
29067
28794
|
inboxCapacity: connectorConfig.inboxCapacity,
|
|
29068
|
-
|
|
29069
|
-
remoteNodeId: connectorConfig.remoteNodeId,
|
|
28795
|
+
initialWindow: connectorConfig.initialWindow,
|
|
29070
28796
|
};
|
|
29071
28797
|
}
|
|
29072
28798
|
const config = {
|
|
@@ -29091,6 +28817,7 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
29091
28817
|
purpose: 'connection',
|
|
29092
28818
|
channelName: normalizedConfig.channelName,
|
|
29093
28819
|
inboxCapacity: normalizedConfig.inboxCapacity,
|
|
28820
|
+
initialWindow: normalizedConfig.initialWindow,
|
|
29094
28821
|
});
|
|
29095
28822
|
return grant;
|
|
29096
28823
|
}
|
|
@@ -29116,8 +28843,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
29116
28843
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
29117
28844
|
channelName,
|
|
29118
28845
|
inboxCapacity,
|
|
29119
|
-
localNodeId: normalized.localNodeId,
|
|
29120
|
-
remoteNodeId: normalized.remoteNodeId,
|
|
29121
28846
|
};
|
|
29122
28847
|
const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
29123
28848
|
if (options.authorization) {
|
|
@@ -29179,16 +28904,6 @@ class BroadcastChannelConnectorFactory extends ConnectorFactory {
|
|
|
29179
28904
|
if (candidate.authorizationContext !== undefined) {
|
|
29180
28905
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
29181
28906
|
}
|
|
29182
|
-
// Handle localNodeId
|
|
29183
|
-
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
29184
|
-
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
29185
|
-
normalized.localNodeId = localNodeId.trim();
|
|
29186
|
-
}
|
|
29187
|
-
// Handle remoteNodeId
|
|
29188
|
-
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
29189
|
-
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
29190
|
-
normalized.remoteNodeId = remoteNodeId.trim();
|
|
29191
|
-
}
|
|
29192
28907
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL$4;
|
|
29193
28908
|
normalized.inboxCapacity =
|
|
29194
28909
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY$4;
|
|
@@ -29557,7 +29272,6 @@ class InPageListener extends TransportListener {
|
|
|
29557
29272
|
this._busHandler = null;
|
|
29558
29273
|
this._senderRegistry = new Map();
|
|
29559
29274
|
this._systemToSender = new Map();
|
|
29560
|
-
this._flowIdToSender = new Map();
|
|
29561
29275
|
this._pendingAttachments = new Map();
|
|
29562
29276
|
ensureBrowserEnvironment$1();
|
|
29563
29277
|
const channelCandidate = options?.channelName;
|
|
@@ -29624,7 +29338,6 @@ class InPageListener extends TransportListener {
|
|
|
29624
29338
|
this._unregisterBusListener();
|
|
29625
29339
|
this._senderRegistry.clear();
|
|
29626
29340
|
this._systemToSender.clear();
|
|
29627
|
-
this._flowIdToSender.clear();
|
|
29628
29341
|
this._pendingAttachments.clear();
|
|
29629
29342
|
logger$p.debug('inpage_listener_stopped', {
|
|
29630
29343
|
channel: this._channelName,
|
|
@@ -29678,25 +29391,10 @@ class InPageListener extends TransportListener {
|
|
|
29678
29391
|
await this._handleAttachFrame(senderId, envelope);
|
|
29679
29392
|
return;
|
|
29680
29393
|
}
|
|
29681
|
-
|
|
29682
|
-
let entry = this._senderRegistry.get(senderId);
|
|
29683
|
-
// If not found and we have a flowId, try to route based on flow
|
|
29684
|
-
if (!entry && envelope.flowId) {
|
|
29685
|
-
const originalSenderId = this._flowIdToSender.get(envelope.flowId);
|
|
29686
|
-
if (originalSenderId) {
|
|
29687
|
-
entry = this._senderRegistry.get(originalSenderId);
|
|
29688
|
-
logger$p.debug('inpage_listener_routed_by_flow_id', {
|
|
29689
|
-
sender_id: senderId,
|
|
29690
|
-
original_sender_id: originalSenderId,
|
|
29691
|
-
flow_id: envelope.flowId,
|
|
29692
|
-
frame_type: envelope.frame?.type ?? 'unknown',
|
|
29693
|
-
});
|
|
29694
|
-
}
|
|
29695
|
-
}
|
|
29394
|
+
const entry = this._senderRegistry.get(senderId);
|
|
29696
29395
|
if (!entry) {
|
|
29697
29396
|
logger$p.debug('inpage_listener_no_connector_for_sender', {
|
|
29698
29397
|
sender_id: senderId,
|
|
29699
|
-
flow_id: envelope.flowId,
|
|
29700
29398
|
frame_type: envelope.frame?.type ?? 'unknown',
|
|
29701
29399
|
});
|
|
29702
29400
|
return;
|
|
@@ -29773,15 +29471,6 @@ class InPageListener extends TransportListener {
|
|
|
29773
29471
|
}
|
|
29774
29472
|
this._senderRegistry.set(senderId, entry);
|
|
29775
29473
|
this._systemToSender.set(entry.systemId, senderId);
|
|
29776
|
-
// Track the flowId if present so we can route responses back
|
|
29777
|
-
if (envelope.flowId) {
|
|
29778
|
-
this._flowIdToSender.set(envelope.flowId, senderId);
|
|
29779
|
-
logger$p.debug('inpage_listener_registered_flow_id', {
|
|
29780
|
-
sender_id: senderId,
|
|
29781
|
-
system_id: entry.systemId,
|
|
29782
|
-
flow_id: envelope.flowId,
|
|
29783
|
-
});
|
|
29784
|
-
}
|
|
29785
29474
|
await this._deliverEnvelope(entry, envelope);
|
|
29786
29475
|
}
|
|
29787
29476
|
async _createConnectorForAttach(params) {
|
|
@@ -29829,7 +29518,7 @@ class InPageListener extends TransportListener {
|
|
|
29829
29518
|
origin_type: originType,
|
|
29830
29519
|
connector_type: connector.constructor?.name ?? 'unknown',
|
|
29831
29520
|
});
|
|
29832
|
-
return { connector, systemId, originType
|
|
29521
|
+
return { connector, systemId, originType };
|
|
29833
29522
|
}
|
|
29834
29523
|
catch (error) {
|
|
29835
29524
|
logger$p.error('inpage_listener_connector_creation_failed', {
|
|
@@ -29883,12 +29572,6 @@ class InPageListener extends TransportListener {
|
|
|
29883
29572
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
29884
29573
|
this._systemToSender.delete(systemId);
|
|
29885
29574
|
}
|
|
29886
|
-
// Clean up flowId mappings for this sender
|
|
29887
|
-
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
29888
|
-
if (sid === senderId) {
|
|
29889
|
-
this._flowIdToSender.delete(flowId);
|
|
29890
|
-
}
|
|
29891
|
-
}
|
|
29892
29575
|
})
|
|
29893
29576
|
.catch((error) => {
|
|
29894
29577
|
logger$p.debug('inpage_listener_wait_until_closed_failed', {
|
|
@@ -29900,24 +29583,9 @@ class InPageListener extends TransportListener {
|
|
|
29900
29583
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
29901
29584
|
this._systemToSender.delete(systemId);
|
|
29902
29585
|
}
|
|
29903
|
-
// Clean up flowId mappings for this sender
|
|
29904
|
-
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
29905
|
-
if (sid === senderId) {
|
|
29906
|
-
this._flowIdToSender.delete(flowId);
|
|
29907
|
-
}
|
|
29908
|
-
}
|
|
29909
29586
|
});
|
|
29910
29587
|
}
|
|
29911
29588
|
async _deliverEnvelope(entry, envelope) {
|
|
29912
|
-
// Track flowId for routing responses back
|
|
29913
|
-
if (envelope.flowId && !this._flowIdToSender.has(envelope.flowId)) {
|
|
29914
|
-
this._flowIdToSender.set(envelope.flowId, entry.senderId);
|
|
29915
|
-
logger$p.debug('inpage_listener_registered_flow_id_on_delivery', {
|
|
29916
|
-
sender_id: entry.senderId,
|
|
29917
|
-
system_id: entry.systemId,
|
|
29918
|
-
flow_id: envelope.flowId,
|
|
29919
|
-
});
|
|
29920
|
-
}
|
|
29921
29589
|
const message = this._buildChannelMessage({
|
|
29922
29590
|
envelope,
|
|
29923
29591
|
connector: entry.connector,
|
|
@@ -30158,18 +29826,13 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
30158
29826
|
});
|
|
30159
29827
|
}
|
|
30160
29828
|
asCallbackGrant() {
|
|
30161
|
-
|
|
29829
|
+
return this.withLegacySnakeCaseKeys({
|
|
30162
29830
|
type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
30163
29831
|
connectorType: BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
30164
29832
|
connectionGrantType: BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE,
|
|
30165
29833
|
channelName: this._channelName,
|
|
30166
29834
|
inboxCapacity: this._inboxCapacity,
|
|
30167
|
-
};
|
|
30168
|
-
// Include localNodeId for transport frame multiplexing if node is available
|
|
30169
|
-
if (this._routingNode) {
|
|
30170
|
-
grant.localNodeId = this._routingNode.id;
|
|
30171
|
-
}
|
|
30172
|
-
return this.withLegacySnakeCaseKeys(grant);
|
|
29835
|
+
});
|
|
30173
29836
|
}
|
|
30174
29837
|
_registerChannelListener() {
|
|
30175
29838
|
if (this._channelHandler) {
|
|
@@ -30229,54 +29892,23 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
30229
29892
|
if (typeof senderId !== 'string' || senderId.length === 0) {
|
|
30230
29893
|
return null;
|
|
30231
29894
|
}
|
|
30232
|
-
|
|
30233
|
-
|
|
30234
|
-
|
|
30235
|
-
|
|
30236
|
-
|
|
30237
|
-
|
|
30238
|
-
// Apply listener's filtering policy: accept frames addressed to us OR with wildcard destination
|
|
30239
|
-
// Wildcard is needed because downstream nodes don't know the sentinel's ID during initial attach
|
|
30240
|
-
const isAddressedToUs = frame.dst === this._routingNode.id || frame.dst === '*';
|
|
30241
|
-
if (isAddressedToUs) {
|
|
30242
|
-
envelopePayload = frame.payload;
|
|
30243
|
-
logger$o.debug('broadcast_channel_listener_unwrapped_transport_frame', {
|
|
30244
|
-
sender_id: senderId,
|
|
30245
|
-
src: frame.src,
|
|
30246
|
-
dst: frame.dst,
|
|
30247
|
-
});
|
|
30248
|
-
}
|
|
30249
|
-
else {
|
|
30250
|
-
// Frame addressed to a different node, ignore it
|
|
30251
|
-
logger$o.debug('broadcast_channel_listener_ignored_frame_wrong_destination', {
|
|
30252
|
-
sender_id: senderId,
|
|
30253
|
-
dst: frame.dst,
|
|
30254
|
-
expected: this._routingNode.id,
|
|
30255
|
-
});
|
|
30256
|
-
return null;
|
|
30257
|
-
}
|
|
30258
|
-
}
|
|
30259
|
-
}
|
|
30260
|
-
// If not a transport frame, try to coerce as legacy format
|
|
30261
|
-
if (!envelopePayload) {
|
|
30262
|
-
envelopePayload = coercePayload(record.payload);
|
|
30263
|
-
if (!envelopePayload) {
|
|
30264
|
-
logger$o.debug('broadcast_channel_listener_ignored_event_without_payload', {
|
|
30265
|
-
sender_id: senderId,
|
|
30266
|
-
});
|
|
30267
|
-
return null;
|
|
30268
|
-
}
|
|
29895
|
+
const payload = coercePayload(record.payload);
|
|
29896
|
+
if (!payload) {
|
|
29897
|
+
logger$o.debug('broadcast_channel_listener_ignored_event_without_payload', {
|
|
29898
|
+
sender_id: senderId,
|
|
29899
|
+
});
|
|
29900
|
+
return null;
|
|
30269
29901
|
}
|
|
30270
29902
|
let envelope;
|
|
30271
29903
|
try {
|
|
30272
|
-
const decoded = new TextDecoder().decode(
|
|
29904
|
+
const decoded = new TextDecoder().decode(payload);
|
|
30273
29905
|
const parsed = JSON.parse(decoded);
|
|
30274
29906
|
envelope = deserializeEnvelope(parsed);
|
|
30275
29907
|
}
|
|
30276
29908
|
catch (error) {
|
|
30277
29909
|
const decoded = (() => {
|
|
30278
29910
|
try {
|
|
30279
|
-
return new TextDecoder().decode(
|
|
29911
|
+
return new TextDecoder().decode(payload);
|
|
30280
29912
|
}
|
|
30281
29913
|
catch {
|
|
30282
29914
|
return null;
|
|
@@ -30396,20 +30028,6 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
30396
30028
|
inboxCapacity: this._inboxCapacity,
|
|
30397
30029
|
};
|
|
30398
30030
|
}
|
|
30399
|
-
// Automatically configure transport frame multiplexing:
|
|
30400
|
-
// Use node IDs (not connector IDs) for node-to-node targeting
|
|
30401
|
-
const broadcastConfig = connectorConfig;
|
|
30402
|
-
// Always force localNodeId to be this listener's node ID
|
|
30403
|
-
// This ensures the sentinel sets localNodeId=sentinel, not the child's ID
|
|
30404
|
-
broadcastConfig.localNodeId = routingNode.id;
|
|
30405
|
-
// Always force remoteNodeId to be the attaching child's system ID
|
|
30406
|
-
broadcastConfig.remoteNodeId = systemId;
|
|
30407
|
-
logger$o.debug('broadcast_channel_listener_configured_node_ids', {
|
|
30408
|
-
sender_id: params.senderId,
|
|
30409
|
-
system_id: systemId,
|
|
30410
|
-
local_node_id: broadcastConfig.localNodeId,
|
|
30411
|
-
remote_node_id: broadcastConfig.remoteNodeId,
|
|
30412
|
-
});
|
|
30413
30031
|
try {
|
|
30414
30032
|
const connector = await routingNode.createOriginConnector({
|
|
30415
30033
|
originType,
|
|
@@ -30479,21 +30097,6 @@ class BroadcastChannelListener extends TransportListener {
|
|
|
30479
30097
|
inboxCandidate > 0) {
|
|
30480
30098
|
config.inboxCapacity = Math.floor(inboxCandidate);
|
|
30481
30099
|
}
|
|
30482
|
-
// Extract transport frame multiplexing node IDs
|
|
30483
|
-
const localNodeIdCandidate = candidate.localNodeId ?? candidate['local_node_id'];
|
|
30484
|
-
if (typeof localNodeIdCandidate === 'string' && localNodeIdCandidate.trim().length > 0) {
|
|
30485
|
-
config.localNodeId = localNodeIdCandidate.trim();
|
|
30486
|
-
logger$o.debug('broadcast_channel_listener_extracted_local_node_id', {
|
|
30487
|
-
local_node_id: config.localNodeId,
|
|
30488
|
-
});
|
|
30489
|
-
}
|
|
30490
|
-
const remoteNodeIdCandidate = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
30491
|
-
if (typeof remoteNodeIdCandidate === 'string' && remoteNodeIdCandidate.trim().length > 0) {
|
|
30492
|
-
config.remoteNodeId = remoteNodeIdCandidate.trim();
|
|
30493
|
-
logger$o.debug('broadcast_channel_listener_extracted_remote_node_id', {
|
|
30494
|
-
remote_node_id: config.remoteNodeId,
|
|
30495
|
-
});
|
|
30496
|
-
}
|
|
30497
30100
|
return config;
|
|
30498
30101
|
}
|
|
30499
30102
|
_monitorConnectorLifecycle(senderId, systemId, connector) {
|