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