@naylence/runtime 0.3.5-test.952 → 0.3.5-test.954
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 +32 -464
- package/dist/browser/index.mjs +32 -464
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector-factory.js +2 -14
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +1 -90
- 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 -87
- 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/upstream-session-manager.js +0 -6
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +2 -14
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +1 -90
- 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 -87
- 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/upstream-session-manager.js +0 -6
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +32 -464
- package/dist/node/index.mjs +32 -464
- package/dist/node/node.cjs +32 -480
- package/dist/node/node.mjs +32 -480
- 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 +1 -4
- package/dist/types/naylence/fame/connector/inpage-connector-factory.d.ts +0 -2
- package/dist/types/naylence/fame/connector/inpage-connector.d.ts +0 -4
- 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
|
@@ -40,8 +40,7 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
40
40
|
type: broadcast_channel_connector_js_1.BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
41
41
|
channelName: connectorConfig.channelName,
|
|
42
42
|
inboxCapacity: connectorConfig.inboxCapacity,
|
|
43
|
-
|
|
44
|
-
remoteNodeId: connectorConfig.remoteNodeId,
|
|
43
|
+
initialWindow: connectorConfig.initialWindow,
|
|
45
44
|
};
|
|
46
45
|
}
|
|
47
46
|
const config = {
|
|
@@ -66,6 +65,7 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
66
65
|
purpose: 'connection',
|
|
67
66
|
channelName: normalizedConfig.channelName,
|
|
68
67
|
inboxCapacity: normalizedConfig.inboxCapacity,
|
|
68
|
+
initialWindow: normalizedConfig.initialWindow,
|
|
69
69
|
});
|
|
70
70
|
return grant;
|
|
71
71
|
}
|
|
@@ -91,8 +91,6 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
91
91
|
type: broadcast_channel_connector_js_1.BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
92
92
|
channelName,
|
|
93
93
|
inboxCapacity,
|
|
94
|
-
localNodeId: normalized.localNodeId,
|
|
95
|
-
remoteNodeId: normalized.remoteNodeId,
|
|
96
94
|
};
|
|
97
95
|
const connector = new broadcast_channel_connector_js_1.BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
98
96
|
if (options.authorization) {
|
|
@@ -154,16 +152,6 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
154
152
|
if (candidate.authorizationContext !== undefined) {
|
|
155
153
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
156
154
|
}
|
|
157
|
-
// Handle localNodeId
|
|
158
|
-
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
159
|
-
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
160
|
-
normalized.localNodeId = localNodeId.trim();
|
|
161
|
-
}
|
|
162
|
-
// Handle remoteNodeId
|
|
163
|
-
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
164
|
-
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
165
|
-
normalized.remoteNodeId = remoteNodeId.trim();
|
|
166
|
-
}
|
|
167
155
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL;
|
|
168
156
|
normalized.inboxCapacity =
|
|
169
157
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY;
|
|
@@ -6,7 +6,6 @@ const errors_js_1 = require("../errors/errors.js");
|
|
|
6
6
|
const logging_js_1 = require("../util/logging.js");
|
|
7
7
|
const bounded_async_queue_js_1 = require("../util/bounded-async-queue.js");
|
|
8
8
|
const core_1 = require("@naylence/core");
|
|
9
|
-
const transport_frame_js_1 = require("./transport-frame.js");
|
|
10
9
|
const logger = (0, logging_js_1.getLogger)('naylence.fame.connector.broadcast_channel_connector');
|
|
11
10
|
exports.BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
|
|
12
11
|
const DEFAULT_CHANNEL = 'naylence-fabric';
|
|
@@ -72,20 +71,9 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
72
71
|
this.inbox = new bounded_async_queue_js_1.BoundedAsyncQueue(preferredCapacity);
|
|
73
72
|
this.connectorId = BroadcastChannelConnector.generateConnectorId();
|
|
74
73
|
this.channel = new BroadcastChannel(this.channelName);
|
|
75
|
-
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
76
|
-
this.localNodeId =
|
|
77
|
-
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
78
|
-
? config.localNodeId.trim()
|
|
79
|
-
: this.connectorId;
|
|
80
|
-
this.remoteNodeId =
|
|
81
|
-
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
82
|
-
? config.remoteNodeId.trim()
|
|
83
|
-
: '*'; // Accept from any remote if not specified
|
|
84
74
|
logger.debug('broadcast_channel_connector_created', {
|
|
85
75
|
channel: this.channelName,
|
|
86
76
|
connector_id: this.connectorId,
|
|
87
|
-
local_node_id: this.localNodeId,
|
|
88
|
-
remote_node_id: this.remoteNodeId,
|
|
89
77
|
inbox_capacity: preferredCapacity,
|
|
90
78
|
timestamp: new Date().toISOString(),
|
|
91
79
|
});
|
|
@@ -118,67 +106,6 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
118
106
|
if (busMessage.senderId === this.connectorId) {
|
|
119
107
|
return;
|
|
120
108
|
}
|
|
121
|
-
// Try to unwrap as transport frame
|
|
122
|
-
const frame = (0, transport_frame_js_1.unwrapTransportFrame)(busMessage.payload);
|
|
123
|
-
if (frame) {
|
|
124
|
-
// Apply connector's filtering policy: strict dst check, src accepts wildcard
|
|
125
|
-
const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
|
|
126
|
-
const dstMatches = frame.dst === this.localNodeId;
|
|
127
|
-
if (dstMatches && srcMatches) {
|
|
128
|
-
// Successfully received and filtered transport frame
|
|
129
|
-
logger.debug('broadcast_channel_transport_frame_received', {
|
|
130
|
-
channel: this.channelName,
|
|
131
|
-
sender_id: busMessage.senderId,
|
|
132
|
-
connector_id: this.connectorId,
|
|
133
|
-
local_node_id: this.localNodeId,
|
|
134
|
-
remote_node_id: this.remoteNodeId,
|
|
135
|
-
frame_src: frame.src,
|
|
136
|
-
frame_dst: frame.dst,
|
|
137
|
-
payload_length: frame.payload.byteLength,
|
|
138
|
-
});
|
|
139
|
-
const unwrapped = frame.payload;
|
|
140
|
-
if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
try {
|
|
144
|
-
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
145
|
-
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
146
|
-
if (accepted) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
this.inbox.enqueue(unwrapped);
|
|
151
|
-
}
|
|
152
|
-
catch (error) {
|
|
153
|
-
if (error instanceof bounded_async_queue_js_1.QueueFullError) {
|
|
154
|
-
logger.warning('broadcast_channel_receive_queue_full', {
|
|
155
|
-
channel: this.channelName,
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
logger.error('broadcast_channel_receive_error', {
|
|
160
|
-
channel: this.channelName,
|
|
161
|
-
error: error instanceof Error ? error.message : String(error),
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
// Frame filtered out by addressing rules
|
|
169
|
-
logger.debug('broadcast_channel_transport_frame_filtered', {
|
|
170
|
-
channel: this.channelName,
|
|
171
|
-
connector_id: this.connectorId,
|
|
172
|
-
local_node_id: this.localNodeId,
|
|
173
|
-
remote_node_id: this.remoteNodeId,
|
|
174
|
-
frame_src: frame.src,
|
|
175
|
-
frame_dst: frame.dst,
|
|
176
|
-
reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
|
|
177
|
-
});
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
// Fall back to legacy format (no transport frame)
|
|
182
109
|
const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
|
|
183
110
|
if (!payload) {
|
|
184
111
|
logger.debug('broadcast_channel_payload_rejected', {
|
|
@@ -317,26 +244,10 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
317
244
|
logger.debug('broadcast_channel_message_sending', {
|
|
318
245
|
channel: this.channelName,
|
|
319
246
|
sender_id: this.connectorId,
|
|
320
|
-
local_node_id: this.localNodeId,
|
|
321
|
-
remote_node_id: this.remoteNodeId,
|
|
322
247
|
});
|
|
323
|
-
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
324
|
-
// (not using default values). This ensures backwards compatibility.
|
|
325
|
-
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
326
|
-
this.remoteNodeId !== '*';
|
|
327
|
-
let payload;
|
|
328
|
-
if (useTransportFrame) {
|
|
329
|
-
// Wrap payload in transport frame
|
|
330
|
-
const frame = (0, transport_frame_js_1.wrapTransportFrame)(data, this.localNodeId, this.remoteNodeId);
|
|
331
|
-
payload = (0, transport_frame_js_1.serializeTransportFrame)(frame);
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
// Legacy format: send raw payload
|
|
335
|
-
payload = data;
|
|
336
|
-
}
|
|
337
248
|
this.channel.postMessage({
|
|
338
249
|
senderId: this.connectorId,
|
|
339
|
-
payload,
|
|
250
|
+
payload: data,
|
|
340
251
|
});
|
|
341
252
|
}
|
|
342
253
|
async _transportReceive() {
|
|
@@ -11,7 +11,6 @@ const broadcast_channel_connector_js_1 = require("./broadcast-channel-connector.
|
|
|
11
11
|
const grant_selection_policy_js_1 = require("./grant-selection-policy.js");
|
|
12
12
|
const bounded_async_queue_js_1 = require("../util/bounded-async-queue.js");
|
|
13
13
|
const broadcast_channel_connection_grant_js_1 = require("../grants/broadcast-channel-connection-grant.js");
|
|
14
|
-
const transport_frame_js_1 = require("./transport-frame.js");
|
|
15
14
|
const logger = (0, logging_js_1.getLogger)('naylence.fame.connector.broadcast_channel_listener');
|
|
16
15
|
const DEFAULT_CHANNEL = 'naylence-fabric';
|
|
17
16
|
const DEFAULT_INBOX_CAPACITY = 2048;
|
|
@@ -143,18 +142,13 @@ class BroadcastChannelListener extends transport_listener_js_1.TransportListener
|
|
|
143
142
|
});
|
|
144
143
|
}
|
|
145
144
|
asCallbackGrant() {
|
|
146
|
-
|
|
145
|
+
return this.withLegacySnakeCaseKeys({
|
|
147
146
|
type: broadcast_channel_connector_js_1.BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
148
147
|
connectorType: broadcast_channel_connector_js_1.BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
149
148
|
connectionGrantType: broadcast_channel_connection_grant_js_1.BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE,
|
|
150
149
|
channelName: this._channelName,
|
|
151
150
|
inboxCapacity: this._inboxCapacity,
|
|
152
|
-
};
|
|
153
|
-
// Include localNodeId for transport frame multiplexing if node is available
|
|
154
|
-
if (this._routingNode) {
|
|
155
|
-
grant.localNodeId = this._routingNode.id;
|
|
156
|
-
}
|
|
157
|
-
return this.withLegacySnakeCaseKeys(grant);
|
|
151
|
+
});
|
|
158
152
|
}
|
|
159
153
|
_registerChannelListener() {
|
|
160
154
|
if (this._channelHandler) {
|
|
@@ -214,54 +208,23 @@ class BroadcastChannelListener extends transport_listener_js_1.TransportListener
|
|
|
214
208
|
if (typeof senderId !== 'string' || senderId.length === 0) {
|
|
215
209
|
return null;
|
|
216
210
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
// Apply listener's filtering policy: accept frames addressed to us OR with wildcard destination
|
|
224
|
-
// Wildcard is needed because downstream nodes don't know the sentinel's ID during initial attach
|
|
225
|
-
const isAddressedToUs = frame.dst === this._routingNode.id || frame.dst === '*';
|
|
226
|
-
if (isAddressedToUs) {
|
|
227
|
-
envelopePayload = frame.payload;
|
|
228
|
-
logger.debug('broadcast_channel_listener_unwrapped_transport_frame', {
|
|
229
|
-
sender_id: senderId,
|
|
230
|
-
src: frame.src,
|
|
231
|
-
dst: frame.dst,
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
// Frame addressed to a different node, ignore it
|
|
236
|
-
logger.debug('broadcast_channel_listener_ignored_frame_wrong_destination', {
|
|
237
|
-
sender_id: senderId,
|
|
238
|
-
dst: frame.dst,
|
|
239
|
-
expected: this._routingNode.id,
|
|
240
|
-
});
|
|
241
|
-
return null;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// If not a transport frame, try to coerce as legacy format
|
|
246
|
-
if (!envelopePayload) {
|
|
247
|
-
envelopePayload = coercePayload(record.payload);
|
|
248
|
-
if (!envelopePayload) {
|
|
249
|
-
logger.debug('broadcast_channel_listener_ignored_event_without_payload', {
|
|
250
|
-
sender_id: senderId,
|
|
251
|
-
});
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
211
|
+
const payload = coercePayload(record.payload);
|
|
212
|
+
if (!payload) {
|
|
213
|
+
logger.debug('broadcast_channel_listener_ignored_event_without_payload', {
|
|
214
|
+
sender_id: senderId,
|
|
215
|
+
});
|
|
216
|
+
return null;
|
|
254
217
|
}
|
|
255
218
|
let envelope;
|
|
256
219
|
try {
|
|
257
|
-
const decoded = new TextDecoder().decode(
|
|
220
|
+
const decoded = new TextDecoder().decode(payload);
|
|
258
221
|
const parsed = JSON.parse(decoded);
|
|
259
222
|
envelope = (0, core_1.deserializeEnvelope)(parsed);
|
|
260
223
|
}
|
|
261
224
|
catch (error) {
|
|
262
225
|
const decoded = (() => {
|
|
263
226
|
try {
|
|
264
|
-
return new TextDecoder().decode(
|
|
227
|
+
return new TextDecoder().decode(payload);
|
|
265
228
|
}
|
|
266
229
|
catch {
|
|
267
230
|
return null;
|
|
@@ -381,20 +344,6 @@ class BroadcastChannelListener extends transport_listener_js_1.TransportListener
|
|
|
381
344
|
inboxCapacity: this._inboxCapacity,
|
|
382
345
|
};
|
|
383
346
|
}
|
|
384
|
-
// Automatically configure transport frame multiplexing:
|
|
385
|
-
// Use node IDs (not connector IDs) for node-to-node targeting
|
|
386
|
-
const broadcastConfig = connectorConfig;
|
|
387
|
-
// Always force localNodeId to be this listener's node ID
|
|
388
|
-
// This ensures the sentinel sets localNodeId=sentinel, not the child's ID
|
|
389
|
-
broadcastConfig.localNodeId = routingNode.id;
|
|
390
|
-
// Always force remoteNodeId to be the attaching child's system ID
|
|
391
|
-
broadcastConfig.remoteNodeId = systemId;
|
|
392
|
-
logger.debug('broadcast_channel_listener_configured_node_ids', {
|
|
393
|
-
sender_id: params.senderId,
|
|
394
|
-
system_id: systemId,
|
|
395
|
-
local_node_id: broadcastConfig.localNodeId,
|
|
396
|
-
remote_node_id: broadcastConfig.remoteNodeId,
|
|
397
|
-
});
|
|
398
347
|
try {
|
|
399
348
|
const connector = await routingNode.createOriginConnector({
|
|
400
349
|
originType,
|
|
@@ -464,21 +413,6 @@ class BroadcastChannelListener extends transport_listener_js_1.TransportListener
|
|
|
464
413
|
inboxCandidate > 0) {
|
|
465
414
|
config.inboxCapacity = Math.floor(inboxCandidate);
|
|
466
415
|
}
|
|
467
|
-
// Extract transport frame multiplexing node IDs
|
|
468
|
-
const localNodeIdCandidate = candidate.localNodeId ?? candidate['local_node_id'];
|
|
469
|
-
if (typeof localNodeIdCandidate === 'string' && localNodeIdCandidate.trim().length > 0) {
|
|
470
|
-
config.localNodeId = localNodeIdCandidate.trim();
|
|
471
|
-
logger.debug('broadcast_channel_listener_extracted_local_node_id', {
|
|
472
|
-
local_node_id: config.localNodeId,
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
const remoteNodeIdCandidate = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
476
|
-
if (typeof remoteNodeIdCandidate === 'string' && remoteNodeIdCandidate.trim().length > 0) {
|
|
477
|
-
config.remoteNodeId = remoteNodeIdCandidate.trim();
|
|
478
|
-
logger.debug('broadcast_channel_listener_extracted_remote_node_id', {
|
|
479
|
-
remote_node_id: config.remoteNodeId,
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
416
|
return config;
|
|
483
417
|
}
|
|
484
418
|
_monitorConnectorLifecycle(senderId, systemId, connector) {
|
|
@@ -84,8 +84,6 @@ class InPageConnectorFactory extends connector_factory_js_1.ConnectorFactory {
|
|
|
84
84
|
type: inpage_connector_js_1.INPAGE_CONNECTOR_TYPE,
|
|
85
85
|
channelName,
|
|
86
86
|
inboxCapacity,
|
|
87
|
-
localNodeId: normalized.localNodeId,
|
|
88
|
-
remoteNodeId: normalized.remoteNodeId,
|
|
89
87
|
};
|
|
90
88
|
const connector = new inpage_connector_js_1.InPageConnector(connectorConfig, baseConfig);
|
|
91
89
|
if (options.authorization) {
|
|
@@ -154,16 +152,6 @@ class InPageConnectorFactory extends connector_factory_js_1.ConnectorFactory {
|
|
|
154
152
|
if (candidate.authorizationContext !== undefined) {
|
|
155
153
|
normalized.authorizationContext = candidate.authorizationContext;
|
|
156
154
|
}
|
|
157
|
-
// Handle localNodeId
|
|
158
|
-
const localNodeId = candidate.localNodeId ?? candidate['local_node_id'];
|
|
159
|
-
if (typeof localNodeId === 'string' && localNodeId.trim().length > 0) {
|
|
160
|
-
normalized.localNodeId = localNodeId.trim();
|
|
161
|
-
}
|
|
162
|
-
// Handle remoteNodeId
|
|
163
|
-
const remoteNodeId = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
164
|
-
if (typeof remoteNodeId === 'string' && remoteNodeId.trim().length > 0) {
|
|
165
|
-
normalized.remoteNodeId = remoteNodeId.trim();
|
|
166
|
-
}
|
|
167
155
|
normalized.channelName = normalized.channelName ?? DEFAULT_CHANNEL;
|
|
168
156
|
normalized.inboxCapacity =
|
|
169
157
|
normalized.inboxCapacity ?? DEFAULT_INBOX_CAPACITY;
|
|
@@ -10,7 +10,6 @@ const errors_js_1 = require("../errors/errors.js");
|
|
|
10
10
|
const logging_js_1 = require("../util/logging.js");
|
|
11
11
|
const bounded_async_queue_js_1 = require("../util/bounded-async-queue.js");
|
|
12
12
|
const core_1 = require("@naylence/core");
|
|
13
|
-
const transport_frame_js_1 = require("./transport-frame.js");
|
|
14
13
|
const logger = (0, logging_js_1.getLogger)('naylence.fame.connector.inpage_connector');
|
|
15
14
|
exports.INPAGE_CONNECTOR_TYPE = 'inpage-connector';
|
|
16
15
|
const DEFAULT_CHANNEL = 'naylence-fabric';
|
|
@@ -81,20 +80,9 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
81
80
|
: DEFAULT_INBOX_CAPACITY;
|
|
82
81
|
this.inbox = new bounded_async_queue_js_1.BoundedAsyncQueue(preferredCapacity);
|
|
83
82
|
this.connectorId = InPageConnector.generateConnectorId();
|
|
84
|
-
// Set local and remote node IDs (defaults to connector ID for backwards compatibility)
|
|
85
|
-
this.localNodeId =
|
|
86
|
-
typeof config.localNodeId === 'string' && config.localNodeId.trim().length > 0
|
|
87
|
-
? config.localNodeId.trim()
|
|
88
|
-
: this.connectorId;
|
|
89
|
-
this.remoteNodeId =
|
|
90
|
-
typeof config.remoteNodeId === 'string' && config.remoteNodeId.trim().length > 0
|
|
91
|
-
? config.remoteNodeId.trim()
|
|
92
|
-
: '*'; // Accept from any remote if not specified
|
|
93
83
|
logger.debug('inpage_connector_initialized', {
|
|
94
84
|
channel: this.channelName,
|
|
95
85
|
connector_id: this.connectorId,
|
|
96
|
-
local_node_id: this.localNodeId,
|
|
97
|
-
remote_node_id: this.remoteNodeId,
|
|
98
86
|
});
|
|
99
87
|
this.onMsg = (event) => {
|
|
100
88
|
const messageEvent = event;
|
|
@@ -128,64 +116,6 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
128
116
|
if (busMessage.senderId === this.connectorId) {
|
|
129
117
|
return;
|
|
130
118
|
}
|
|
131
|
-
// Try to unwrap as transport frame
|
|
132
|
-
const frame = (0, transport_frame_js_1.unwrapTransportFrame)(busMessage.payload);
|
|
133
|
-
if (frame) {
|
|
134
|
-
// Apply connector's filtering policy: strict dst check, src accepts wildcard
|
|
135
|
-
const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
|
|
136
|
-
const dstMatches = frame.dst === this.localNodeId;
|
|
137
|
-
if (dstMatches && srcMatches) {
|
|
138
|
-
// Successfully received and filtered transport frame
|
|
139
|
-
logger.debug('inpage_transport_frame_received', {
|
|
140
|
-
channel: this.channelName,
|
|
141
|
-
sender_id: busMessage.senderId,
|
|
142
|
-
connector_id: this.connectorId,
|
|
143
|
-
local_node_id: this.localNodeId,
|
|
144
|
-
remote_node_id: this.remoteNodeId,
|
|
145
|
-
frame_src: frame.src,
|
|
146
|
-
frame_dst: frame.dst,
|
|
147
|
-
payload_length: frame.payload.byteLength,
|
|
148
|
-
});
|
|
149
|
-
const unwrapped = frame.payload;
|
|
150
|
-
try {
|
|
151
|
-
if (typeof this.inbox.tryEnqueue === 'function') {
|
|
152
|
-
const accepted = this.inbox.tryEnqueue(unwrapped);
|
|
153
|
-
if (accepted) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
this.inbox.enqueue(unwrapped);
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
if (error instanceof bounded_async_queue_js_1.QueueFullError) {
|
|
161
|
-
logger.warning('inpage_receive_queue_full', {
|
|
162
|
-
channel: this.channelName,
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
logger.error('inpage_receive_error', {
|
|
167
|
-
channel: this.channelName,
|
|
168
|
-
error: error instanceof Error ? error.message : String(error),
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
// Frame filtered out by addressing rules
|
|
176
|
-
logger.debug('inpage_transport_frame_filtered', {
|
|
177
|
-
channel: this.channelName,
|
|
178
|
-
connector_id: this.connectorId,
|
|
179
|
-
local_node_id: this.localNodeId,
|
|
180
|
-
remote_node_id: this.remoteNodeId,
|
|
181
|
-
frame_src: frame.src,
|
|
182
|
-
frame_dst: frame.dst,
|
|
183
|
-
reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
|
|
184
|
-
});
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
// Fall back to legacy format (no transport frame)
|
|
189
119
|
const payload = InPageConnector.coercePayload(busMessage.payload);
|
|
190
120
|
if (!payload) {
|
|
191
121
|
logger.debug('inpage_payload_rejected', {
|
|
@@ -344,27 +274,11 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
344
274
|
logger.debug('inpage_message_sending', {
|
|
345
275
|
channel: this.channelName,
|
|
346
276
|
sender_id: this.connectorId,
|
|
347
|
-
local_node_id: this.localNodeId,
|
|
348
|
-
remote_node_id: this.remoteNodeId,
|
|
349
277
|
});
|
|
350
|
-
// Only use transport framing if both localNodeId and remoteNodeId are explicitly set
|
|
351
|
-
// (not using default values). This ensures backwards compatibility.
|
|
352
|
-
const useTransportFrame = this.localNodeId !== this.connectorId ||
|
|
353
|
-
this.remoteNodeId !== '*';
|
|
354
|
-
let payload;
|
|
355
|
-
if (useTransportFrame) {
|
|
356
|
-
// Wrap payload in transport frame
|
|
357
|
-
const frame = (0, transport_frame_js_1.wrapTransportFrame)(data, this.localNodeId, this.remoteNodeId);
|
|
358
|
-
payload = (0, transport_frame_js_1.serializeTransportFrame)(frame);
|
|
359
|
-
}
|
|
360
|
-
else {
|
|
361
|
-
// Legacy format: send raw payload
|
|
362
|
-
payload = data;
|
|
363
|
-
}
|
|
364
278
|
const event = new MessageEvent(this.channelName, {
|
|
365
279
|
data: {
|
|
366
280
|
senderId: this.connectorId,
|
|
367
|
-
payload,
|
|
281
|
+
payload: data,
|
|
368
282
|
},
|
|
369
283
|
});
|
|
370
284
|
getSharedBus().dispatchEvent(event);
|
|
@@ -65,7 +65,6 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
65
65
|
this._busHandler = null;
|
|
66
66
|
this._senderRegistry = new Map();
|
|
67
67
|
this._systemToSender = new Map();
|
|
68
|
-
this._flowIdToSender = new Map();
|
|
69
68
|
this._pendingAttachments = new Map();
|
|
70
69
|
ensureBrowserEnvironment();
|
|
71
70
|
const channelCandidate = options?.channelName;
|
|
@@ -132,7 +131,6 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
132
131
|
this._unregisterBusListener();
|
|
133
132
|
this._senderRegistry.clear();
|
|
134
133
|
this._systemToSender.clear();
|
|
135
|
-
this._flowIdToSender.clear();
|
|
136
134
|
this._pendingAttachments.clear();
|
|
137
135
|
logger.debug('inpage_listener_stopped', {
|
|
138
136
|
channel: this._channelName,
|
|
@@ -186,25 +184,10 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
186
184
|
await this._handleAttachFrame(senderId, envelope);
|
|
187
185
|
return;
|
|
188
186
|
}
|
|
189
|
-
|
|
190
|
-
let entry = this._senderRegistry.get(senderId);
|
|
191
|
-
// If not found and we have a flowId, try to route based on flow
|
|
192
|
-
if (!entry && envelope.flowId) {
|
|
193
|
-
const originalSenderId = this._flowIdToSender.get(envelope.flowId);
|
|
194
|
-
if (originalSenderId) {
|
|
195
|
-
entry = this._senderRegistry.get(originalSenderId);
|
|
196
|
-
logger.debug('inpage_listener_routed_by_flow_id', {
|
|
197
|
-
sender_id: senderId,
|
|
198
|
-
original_sender_id: originalSenderId,
|
|
199
|
-
flow_id: envelope.flowId,
|
|
200
|
-
frame_type: envelope.frame?.type ?? 'unknown',
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
}
|
|
187
|
+
const entry = this._senderRegistry.get(senderId);
|
|
204
188
|
if (!entry) {
|
|
205
189
|
logger.debug('inpage_listener_no_connector_for_sender', {
|
|
206
190
|
sender_id: senderId,
|
|
207
|
-
flow_id: envelope.flowId,
|
|
208
191
|
frame_type: envelope.frame?.type ?? 'unknown',
|
|
209
192
|
});
|
|
210
193
|
return;
|
|
@@ -281,15 +264,6 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
281
264
|
}
|
|
282
265
|
this._senderRegistry.set(senderId, entry);
|
|
283
266
|
this._systemToSender.set(entry.systemId, senderId);
|
|
284
|
-
// Track the flowId if present so we can route responses back
|
|
285
|
-
if (envelope.flowId) {
|
|
286
|
-
this._flowIdToSender.set(envelope.flowId, senderId);
|
|
287
|
-
logger.debug('inpage_listener_registered_flow_id', {
|
|
288
|
-
sender_id: senderId,
|
|
289
|
-
system_id: entry.systemId,
|
|
290
|
-
flow_id: envelope.flowId,
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
267
|
await this._deliverEnvelope(entry, envelope);
|
|
294
268
|
}
|
|
295
269
|
async _createConnectorForAttach(params) {
|
|
@@ -337,7 +311,7 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
337
311
|
origin_type: originType,
|
|
338
312
|
connector_type: connector.constructor?.name ?? 'unknown',
|
|
339
313
|
});
|
|
340
|
-
return { connector, systemId, originType
|
|
314
|
+
return { connector, systemId, originType };
|
|
341
315
|
}
|
|
342
316
|
catch (error) {
|
|
343
317
|
logger.error('inpage_listener_connector_creation_failed', {
|
|
@@ -391,12 +365,6 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
391
365
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
392
366
|
this._systemToSender.delete(systemId);
|
|
393
367
|
}
|
|
394
|
-
// Clean up flowId mappings for this sender
|
|
395
|
-
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
396
|
-
if (sid === senderId) {
|
|
397
|
-
this._flowIdToSender.delete(flowId);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
368
|
})
|
|
401
369
|
.catch((error) => {
|
|
402
370
|
logger.debug('inpage_listener_wait_until_closed_failed', {
|
|
@@ -408,24 +376,9 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
408
376
|
if (this._systemToSender.get(systemId) === senderId) {
|
|
409
377
|
this._systemToSender.delete(systemId);
|
|
410
378
|
}
|
|
411
|
-
// Clean up flowId mappings for this sender
|
|
412
|
-
for (const [flowId, sid] of this._flowIdToSender.entries()) {
|
|
413
|
-
if (sid === senderId) {
|
|
414
|
-
this._flowIdToSender.delete(flowId);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
379
|
});
|
|
418
380
|
}
|
|
419
381
|
async _deliverEnvelope(entry, envelope) {
|
|
420
|
-
// Track flowId for routing responses back
|
|
421
|
-
if (envelope.flowId && !this._flowIdToSender.has(envelope.flowId)) {
|
|
422
|
-
this._flowIdToSender.set(envelope.flowId, entry.senderId);
|
|
423
|
-
logger.debug('inpage_listener_registered_flow_id_on_delivery', {
|
|
424
|
-
sender_id: entry.senderId,
|
|
425
|
-
system_id: entry.systemId,
|
|
426
|
-
flow_id: envelope.flowId,
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
382
|
const message = this._buildChannelMessage({
|
|
430
383
|
envelope,
|
|
431
384
|
connector: entry.connector,
|
|
@@ -25,12 +25,9 @@ function isBroadcastChannelConnectionGrant(candidate) {
|
|
|
25
25
|
record.inboxCapacity <= 0)) {
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
|
-
if (record.
|
|
29
|
-
(
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
if (record.remoteNodeId !== undefined &&
|
|
33
|
-
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
28
|
+
if (record.initialWindow !== undefined &&
|
|
29
|
+
(!Number.isFinite(record.initialWindow) ||
|
|
30
|
+
record.initialWindow <= 0)) {
|
|
34
31
|
return false;
|
|
35
32
|
}
|
|
36
33
|
return true;
|
|
@@ -66,19 +63,14 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
|
66
63
|
}
|
|
67
64
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
68
65
|
}
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
71
|
-
if (typeof
|
|
72
|
-
|
|
66
|
+
const windowValue = candidate.initialWindow ?? candidate['initial_window'];
|
|
67
|
+
if (windowValue !== undefined) {
|
|
68
|
+
if (typeof windowValue !== 'number' ||
|
|
69
|
+
!Number.isFinite(windowValue) ||
|
|
70
|
+
windowValue <= 0) {
|
|
71
|
+
throw new TypeError('BroadcastChannelConnectionGrant "initialWindow" must be a positive number when provided');
|
|
73
72
|
}
|
|
74
|
-
result.
|
|
75
|
-
}
|
|
76
|
-
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
77
|
-
if (remoteNodeIdValue !== undefined) {
|
|
78
|
-
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
79
|
-
throw new TypeError('BroadcastChannelConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
80
|
-
}
|
|
81
|
-
result.remoteNodeId = remoteNodeIdValue.trim();
|
|
73
|
+
result.initialWindow = Math.floor(windowValue);
|
|
82
74
|
}
|
|
83
75
|
return result;
|
|
84
76
|
}
|
|
@@ -93,11 +85,8 @@ function broadcastChannelGrantToConnectorConfig(grant) {
|
|
|
93
85
|
if (normalized.inboxCapacity !== undefined) {
|
|
94
86
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
95
87
|
}
|
|
96
|
-
if (normalized.
|
|
97
|
-
config.
|
|
98
|
-
}
|
|
99
|
-
if (normalized.remoteNodeId) {
|
|
100
|
-
config.remoteNodeId = normalized.remoteNodeId;
|
|
88
|
+
if (normalized.initialWindow !== undefined) {
|
|
89
|
+
config.initialWindow = normalized.initialWindow;
|
|
101
90
|
}
|
|
102
91
|
return config;
|
|
103
92
|
}
|
|
@@ -25,14 +25,6 @@ function isInPageConnectionGrant(candidate) {
|
|
|
25
25
|
record.inboxCapacity <= 0)) {
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
|
-
if (record.localNodeId !== undefined &&
|
|
29
|
-
(typeof record.localNodeId !== 'string' || record.localNodeId.length === 0)) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
if (record.remoteNodeId !== undefined &&
|
|
33
|
-
(typeof record.remoteNodeId !== 'string' || record.remoteNodeId.length === 0)) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
28
|
return true;
|
|
37
29
|
}
|
|
38
30
|
function normalizeInPageConnectionGrant(candidate) {
|
|
@@ -66,20 +58,6 @@ function normalizeInPageConnectionGrant(candidate) {
|
|
|
66
58
|
}
|
|
67
59
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
68
60
|
}
|
|
69
|
-
const localNodeIdValue = candidate.localNodeId ?? candidate['local_node_id'];
|
|
70
|
-
if (localNodeIdValue !== undefined) {
|
|
71
|
-
if (typeof localNodeIdValue !== 'string' || localNodeIdValue.trim().length === 0) {
|
|
72
|
-
throw new TypeError('InPageConnectionGrant "localNodeId" must be a non-empty string when provided');
|
|
73
|
-
}
|
|
74
|
-
result.localNodeId = localNodeIdValue.trim();
|
|
75
|
-
}
|
|
76
|
-
const remoteNodeIdValue = candidate.remoteNodeId ?? candidate['remote_node_id'];
|
|
77
|
-
if (remoteNodeIdValue !== undefined) {
|
|
78
|
-
if (typeof remoteNodeIdValue !== 'string' || remoteNodeIdValue.trim().length === 0) {
|
|
79
|
-
throw new TypeError('InPageConnectionGrant "remoteNodeId" must be a non-empty string when provided');
|
|
80
|
-
}
|
|
81
|
-
result.remoteNodeId = remoteNodeIdValue.trim();
|
|
82
|
-
}
|
|
83
61
|
return result;
|
|
84
62
|
}
|
|
85
63
|
function inPageGrantToConnectorConfig(grant) {
|
|
@@ -93,11 +71,5 @@ function inPageGrantToConnectorConfig(grant) {
|
|
|
93
71
|
if (normalized.inboxCapacity !== undefined) {
|
|
94
72
|
config.inboxCapacity = normalized.inboxCapacity;
|
|
95
73
|
}
|
|
96
|
-
if (normalized.localNodeId) {
|
|
97
|
-
config.localNodeId = normalized.localNodeId;
|
|
98
|
-
}
|
|
99
|
-
if (normalized.remoteNodeId) {
|
|
100
|
-
config.remoteNodeId = normalized.remoteNodeId;
|
|
101
|
-
}
|
|
102
74
|
return config;
|
|
103
75
|
}
|