@naylence/runtime 0.3.5-test.949 → 0.3.5-test.951

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.
@@ -119,43 +119,64 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
119
119
  return;
120
120
  }
121
121
  // Try to unwrap as transport frame
122
- const unwrapped = (0, transport_frame_js_1.unwrapTransportFrame)(busMessage.payload, this.localNodeId, this.remoteNodeId === '*' ? busMessage.senderId : this.remoteNodeId);
123
- if (unwrapped) {
124
- // Successfully unwrapped transport frame
125
- logger.debug('broadcast_channel_transport_frame_received', {
126
- channel: this.channelName,
127
- sender_id: busMessage.senderId,
128
- connector_id: this.connectorId,
129
- local_node_id: this.localNodeId,
130
- remote_node_id: this.remoteNodeId,
131
- payload_length: unwrapped.byteLength,
132
- });
133
- if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
134
- return;
135
- }
136
- try {
137
- if (typeof this.inbox.tryEnqueue === 'function') {
138
- const accepted = this.inbox.tryEnqueue(unwrapped);
139
- if (accepted) {
140
- return;
141
- }
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
142
  }
143
- this.inbox.enqueue(unwrapped);
144
- }
145
- catch (error) {
146
- if (error instanceof bounded_async_queue_js_1.QueueFullError) {
147
- logger.warning('broadcast_channel_receive_queue_full', {
148
- channel: this.channelName,
149
- });
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);
150
151
  }
151
- else {
152
- logger.error('broadcast_channel_receive_error', {
153
- channel: this.channelName,
154
- error: error instanceof Error ? error.message : String(error),
155
- });
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
+ }
156
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;
157
179
  }
158
- return;
159
180
  }
160
181
  // Fall back to legacy format (no transport frame)
161
182
  const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
@@ -11,6 +11,7 @@ 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");
14
15
  const logger = (0, logging_js_1.getLogger)('naylence.fame.connector.broadcast_channel_listener');
15
16
  const DEFAULT_CHANNEL = 'naylence-fabric';
16
17
  const DEFAULT_INBOX_CAPACITY = 2048;
@@ -213,23 +214,52 @@ class BroadcastChannelListener extends transport_listener_js_1.TransportListener
213
214
  if (typeof senderId !== 'string' || senderId.length === 0) {
214
215
  return null;
215
216
  }
216
- const payload = coercePayload(record.payload);
217
- if (!payload) {
218
- logger.debug('broadcast_channel_listener_ignored_event_without_payload', {
219
- sender_id: senderId,
220
- });
221
- return null;
217
+ // Check if payload is a transport frame object first
218
+ let envelopePayload = null;
219
+ if (this._routingNode && record.payload && typeof record.payload === 'object') {
220
+ // Try to unwrap as transport frame
221
+ const frame = (0, transport_frame_js_1.unwrapTransportFrame)(record.payload);
222
+ if (frame) {
223
+ // Apply listener's filtering policy: dst must match, src can be anything
224
+ if (frame.dst === this._routingNode.id) {
225
+ envelopePayload = frame.payload;
226
+ logger.debug('broadcast_channel_listener_unwrapped_transport_frame', {
227
+ sender_id: senderId,
228
+ src: frame.src,
229
+ dst: frame.dst,
230
+ });
231
+ }
232
+ else {
233
+ // Frame not addressed to us, ignore it
234
+ logger.debug('broadcast_channel_listener_ignored_frame_wrong_destination', {
235
+ sender_id: senderId,
236
+ dst: frame.dst,
237
+ expected: this._routingNode.id,
238
+ });
239
+ return null;
240
+ }
241
+ }
242
+ }
243
+ // If not a transport frame, try to coerce as legacy format
244
+ if (!envelopePayload) {
245
+ envelopePayload = coercePayload(record.payload);
246
+ if (!envelopePayload) {
247
+ logger.debug('broadcast_channel_listener_ignored_event_without_payload', {
248
+ sender_id: senderId,
249
+ });
250
+ return null;
251
+ }
222
252
  }
223
253
  let envelope;
224
254
  try {
225
- const decoded = new TextDecoder().decode(payload);
255
+ const decoded = new TextDecoder().decode(envelopePayload);
226
256
  const parsed = JSON.parse(decoded);
227
257
  envelope = (0, core_1.deserializeEnvelope)(parsed);
228
258
  }
229
259
  catch (error) {
230
260
  const decoded = (() => {
231
261
  try {
232
- return new TextDecoder().decode(payload);
262
+ return new TextDecoder().decode(envelopePayload);
233
263
  }
234
264
  catch {
235
265
  return null;
@@ -129,40 +129,61 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
129
129
  return;
130
130
  }
131
131
  // Try to unwrap as transport frame
132
- const unwrapped = (0, transport_frame_js_1.unwrapTransportFrame)(busMessage.payload, this.localNodeId, this.remoteNodeId === '*' ? busMessage.senderId : this.remoteNodeId);
133
- if (unwrapped) {
134
- // Successfully unwrapped transport frame
135
- logger.debug('inpage_transport_frame_received', {
136
- channel: this.channelName,
137
- sender_id: busMessage.senderId,
138
- connector_id: this.connectorId,
139
- local_node_id: this.localNodeId,
140
- remote_node_id: this.remoteNodeId,
141
- payload_length: unwrapped.byteLength,
142
- });
143
- try {
144
- if (typeof this.inbox.tryEnqueue === 'function') {
145
- const accepted = this.inbox.tryEnqueue(unwrapped);
146
- if (accepted) {
147
- return;
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
+ }
148
156
  }
157
+ this.inbox.enqueue(unwrapped);
149
158
  }
150
- this.inbox.enqueue(unwrapped);
151
- }
152
- catch (error) {
153
- if (error instanceof bounded_async_queue_js_1.QueueFullError) {
154
- logger.warning('inpage_receive_queue_full', {
155
- channel: this.channelName,
156
- });
157
- }
158
- else {
159
- logger.error('inpage_receive_error', {
160
- channel: this.channelName,
161
- error: error instanceof Error ? error.message : String(error),
162
- });
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
+ }
163
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;
164
186
  }
165
- return;
166
187
  }
167
188
  // Fall back to legacy format (no transport frame)
168
189
  const payload = InPageConnector.coercePayload(busMessage.payload);
@@ -51,14 +51,12 @@ function serializeTransportFrame(frame) {
51
51
  return serializable;
52
52
  }
53
53
  /**
54
- * Unwrap a transport frame, validating source and destination
54
+ * Unwrap a transport frame (pure deserializer - no filtering)
55
55
  *
56
56
  * @param raw - Raw data from the bus
57
- * @param localNodeId - This connector's node ID
58
- * @param remoteNodeId - Expected remote node ID
59
- * @returns Unwrapped payload if frame is valid and addressed to us, null otherwise
57
+ * @returns Unwrapped frame with payload as Uint8Array, or null if invalid structure
60
58
  */
61
- function unwrapTransportFrame(raw, localNodeId, remoteNodeId) {
59
+ function unwrapTransportFrame(raw) {
62
60
  // Validate basic structure
63
61
  if (!raw || typeof raw !== 'object') {
64
62
  return null;
@@ -72,16 +70,17 @@ function unwrapTransportFrame(raw, localNodeId, remoteNodeId) {
72
70
  if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
73
71
  return null;
74
72
  }
75
- // Only accept frames addressed to us from the expected remote
76
- if (frame.dst !== localNodeId || frame.src !== remoteNodeId) {
77
- return null;
78
- }
79
73
  // Extract payload
80
74
  if (!frame.payload || !Array.isArray(frame.payload)) {
81
75
  return null;
82
76
  }
83
- // Convert array back to Uint8Array
84
- return Uint8Array.from(frame.payload);
77
+ // Convert array back to Uint8Array and return full frame
78
+ return {
79
+ v: frame.v,
80
+ src: frame.src,
81
+ dst: frame.dst,
82
+ payload: Uint8Array.from(frame.payload),
83
+ };
85
84
  }
86
85
  /**
87
86
  * Check if raw data looks like a transport frame
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  // This file is auto-generated during build - do not edit manually
3
- // Generated from package.json version: 0.3.5-test.949
3
+ // Generated from package.json version: 0.3.5-test.951
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.VERSION = void 0;
6
6
  /**
7
7
  * The package version, injected at build time.
8
8
  * @internal
9
9
  */
10
- exports.VERSION = '0.3.5-test.949';
10
+ exports.VERSION = '0.3.5-test.951';
@@ -116,43 +116,64 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
116
116
  return;
117
117
  }
118
118
  // Try to unwrap as transport frame
119
- const unwrapped = unwrapTransportFrame(busMessage.payload, this.localNodeId, this.remoteNodeId === '*' ? busMessage.senderId : this.remoteNodeId);
120
- if (unwrapped) {
121
- // Successfully unwrapped transport frame
122
- logger.debug('broadcast_channel_transport_frame_received', {
123
- channel: this.channelName,
124
- sender_id: busMessage.senderId,
125
- connector_id: this.connectorId,
126
- local_node_id: this.localNodeId,
127
- remote_node_id: this.remoteNodeId,
128
- payload_length: unwrapped.byteLength,
129
- });
130
- if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
131
- return;
132
- }
133
- try {
134
- if (typeof this.inbox.tryEnqueue === 'function') {
135
- const accepted = this.inbox.tryEnqueue(unwrapped);
136
- if (accepted) {
137
- return;
138
- }
119
+ const frame = unwrapTransportFrame(busMessage.payload);
120
+ if (frame) {
121
+ // Apply connector's filtering policy: strict dst check, src accepts wildcard
122
+ const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
123
+ const dstMatches = frame.dst === this.localNodeId;
124
+ if (dstMatches && srcMatches) {
125
+ // Successfully received and filtered transport frame
126
+ logger.debug('broadcast_channel_transport_frame_received', {
127
+ channel: this.channelName,
128
+ sender_id: busMessage.senderId,
129
+ connector_id: this.connectorId,
130
+ local_node_id: this.localNodeId,
131
+ remote_node_id: this.remoteNodeId,
132
+ frame_src: frame.src,
133
+ frame_dst: frame.dst,
134
+ payload_length: frame.payload.byteLength,
135
+ });
136
+ const unwrapped = frame.payload;
137
+ if (this._shouldSkipDuplicateAck(busMessage.senderId, unwrapped)) {
138
+ return;
139
139
  }
140
- this.inbox.enqueue(unwrapped);
141
- }
142
- catch (error) {
143
- if (error instanceof QueueFullError) {
144
- logger.warning('broadcast_channel_receive_queue_full', {
145
- channel: this.channelName,
146
- });
140
+ try {
141
+ if (typeof this.inbox.tryEnqueue === 'function') {
142
+ const accepted = this.inbox.tryEnqueue(unwrapped);
143
+ if (accepted) {
144
+ return;
145
+ }
146
+ }
147
+ this.inbox.enqueue(unwrapped);
147
148
  }
148
- else {
149
- logger.error('broadcast_channel_receive_error', {
150
- channel: this.channelName,
151
- error: error instanceof Error ? error.message : String(error),
152
- });
149
+ catch (error) {
150
+ if (error instanceof QueueFullError) {
151
+ logger.warning('broadcast_channel_receive_queue_full', {
152
+ channel: this.channelName,
153
+ });
154
+ }
155
+ else {
156
+ logger.error('broadcast_channel_receive_error', {
157
+ channel: this.channelName,
158
+ error: error instanceof Error ? error.message : String(error),
159
+ });
160
+ }
153
161
  }
162
+ return;
163
+ }
164
+ else {
165
+ // Frame filtered out by addressing rules
166
+ logger.debug('broadcast_channel_transport_frame_filtered', {
167
+ channel: this.channelName,
168
+ connector_id: this.connectorId,
169
+ local_node_id: this.localNodeId,
170
+ remote_node_id: this.remoteNodeId,
171
+ frame_src: frame.src,
172
+ frame_dst: frame.dst,
173
+ reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
174
+ });
175
+ return;
154
176
  }
155
- return;
156
177
  }
157
178
  // Fall back to legacy format (no transport frame)
158
179
  const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
@@ -7,6 +7,7 @@ import { BROADCAST_CHANNEL_CONNECTOR_TYPE, } from './broadcast-channel-connector
7
7
  import { GrantSelectionContext, defaultGrantSelectionPolicy, } from './grant-selection-policy.js';
8
8
  import { QueueFullError } from '../util/bounded-async-queue.js';
9
9
  import { BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE, broadcastChannelGrantToConnectorConfig, } from '../grants/broadcast-channel-connection-grant.js';
10
+ import { unwrapTransportFrame, } from './transport-frame.js';
10
11
  const logger = getLogger('naylence.fame.connector.broadcast_channel_listener');
11
12
  const DEFAULT_CHANNEL = 'naylence-fabric';
12
13
  const DEFAULT_INBOX_CAPACITY = 2048;
@@ -209,23 +210,52 @@ export class BroadcastChannelListener extends TransportListener {
209
210
  if (typeof senderId !== 'string' || senderId.length === 0) {
210
211
  return null;
211
212
  }
212
- const payload = coercePayload(record.payload);
213
- if (!payload) {
214
- logger.debug('broadcast_channel_listener_ignored_event_without_payload', {
215
- sender_id: senderId,
216
- });
217
- return null;
213
+ // Check if payload is a transport frame object first
214
+ let envelopePayload = null;
215
+ if (this._routingNode && record.payload && typeof record.payload === 'object') {
216
+ // Try to unwrap as transport frame
217
+ const frame = unwrapTransportFrame(record.payload);
218
+ if (frame) {
219
+ // Apply listener's filtering policy: dst must match, src can be anything
220
+ if (frame.dst === this._routingNode.id) {
221
+ envelopePayload = frame.payload;
222
+ logger.debug('broadcast_channel_listener_unwrapped_transport_frame', {
223
+ sender_id: senderId,
224
+ src: frame.src,
225
+ dst: frame.dst,
226
+ });
227
+ }
228
+ else {
229
+ // Frame not addressed to us, ignore it
230
+ logger.debug('broadcast_channel_listener_ignored_frame_wrong_destination', {
231
+ sender_id: senderId,
232
+ dst: frame.dst,
233
+ expected: this._routingNode.id,
234
+ });
235
+ return null;
236
+ }
237
+ }
238
+ }
239
+ // If not a transport frame, try to coerce as legacy format
240
+ if (!envelopePayload) {
241
+ envelopePayload = coercePayload(record.payload);
242
+ if (!envelopePayload) {
243
+ logger.debug('broadcast_channel_listener_ignored_event_without_payload', {
244
+ sender_id: senderId,
245
+ });
246
+ return null;
247
+ }
218
248
  }
219
249
  let envelope;
220
250
  try {
221
- const decoded = new TextDecoder().decode(payload);
251
+ const decoded = new TextDecoder().decode(envelopePayload);
222
252
  const parsed = JSON.parse(decoded);
223
253
  envelope = deserializeEnvelope(parsed);
224
254
  }
225
255
  catch (error) {
226
256
  const decoded = (() => {
227
257
  try {
228
- return new TextDecoder().decode(payload);
258
+ return new TextDecoder().decode(envelopePayload);
229
259
  }
230
260
  catch {
231
261
  return null;
@@ -126,40 +126,61 @@ export class InPageConnector extends BaseAsyncConnector {
126
126
  return;
127
127
  }
128
128
  // Try to unwrap as transport frame
129
- const unwrapped = unwrapTransportFrame(busMessage.payload, this.localNodeId, this.remoteNodeId === '*' ? busMessage.senderId : this.remoteNodeId);
130
- if (unwrapped) {
131
- // Successfully unwrapped transport frame
132
- logger.debug('inpage_transport_frame_received', {
133
- channel: this.channelName,
134
- sender_id: busMessage.senderId,
135
- connector_id: this.connectorId,
136
- local_node_id: this.localNodeId,
137
- remote_node_id: this.remoteNodeId,
138
- payload_length: unwrapped.byteLength,
139
- });
140
- try {
141
- if (typeof this.inbox.tryEnqueue === 'function') {
142
- const accepted = this.inbox.tryEnqueue(unwrapped);
143
- if (accepted) {
144
- return;
129
+ const frame = unwrapTransportFrame(busMessage.payload);
130
+ if (frame) {
131
+ // Apply connector's filtering policy: strict dst check, src accepts wildcard
132
+ const srcMatches = this.remoteNodeId === '*' || frame.src === this.remoteNodeId;
133
+ const dstMatches = frame.dst === this.localNodeId;
134
+ if (dstMatches && srcMatches) {
135
+ // Successfully received and filtered transport frame
136
+ logger.debug('inpage_transport_frame_received', {
137
+ channel: this.channelName,
138
+ sender_id: busMessage.senderId,
139
+ connector_id: this.connectorId,
140
+ local_node_id: this.localNodeId,
141
+ remote_node_id: this.remoteNodeId,
142
+ frame_src: frame.src,
143
+ frame_dst: frame.dst,
144
+ payload_length: frame.payload.byteLength,
145
+ });
146
+ const unwrapped = frame.payload;
147
+ try {
148
+ if (typeof this.inbox.tryEnqueue === 'function') {
149
+ const accepted = this.inbox.tryEnqueue(unwrapped);
150
+ if (accepted) {
151
+ return;
152
+ }
145
153
  }
154
+ this.inbox.enqueue(unwrapped);
146
155
  }
147
- this.inbox.enqueue(unwrapped);
148
- }
149
- catch (error) {
150
- if (error instanceof QueueFullError) {
151
- logger.warning('inpage_receive_queue_full', {
152
- channel: this.channelName,
153
- });
154
- }
155
- else {
156
- logger.error('inpage_receive_error', {
157
- channel: this.channelName,
158
- error: error instanceof Error ? error.message : String(error),
159
- });
156
+ catch (error) {
157
+ if (error instanceof QueueFullError) {
158
+ logger.warning('inpage_receive_queue_full', {
159
+ channel: this.channelName,
160
+ });
161
+ }
162
+ else {
163
+ logger.error('inpage_receive_error', {
164
+ channel: this.channelName,
165
+ error: error instanceof Error ? error.message : String(error),
166
+ });
167
+ }
160
168
  }
169
+ return;
170
+ }
171
+ else {
172
+ // Frame filtered out by addressing rules
173
+ logger.debug('inpage_transport_frame_filtered', {
174
+ channel: this.channelName,
175
+ connector_id: this.connectorId,
176
+ local_node_id: this.localNodeId,
177
+ remote_node_id: this.remoteNodeId,
178
+ frame_src: frame.src,
179
+ frame_dst: frame.dst,
180
+ reason: !dstMatches ? 'wrong_destination' : 'wrong_source',
181
+ });
182
+ return;
161
183
  }
162
- return;
163
184
  }
164
185
  // Fall back to legacy format (no transport frame)
165
186
  const payload = InPageConnector.coercePayload(busMessage.payload);
@@ -44,14 +44,12 @@ export function serializeTransportFrame(frame) {
44
44
  return serializable;
45
45
  }
46
46
  /**
47
- * Unwrap a transport frame, validating source and destination
47
+ * Unwrap a transport frame (pure deserializer - no filtering)
48
48
  *
49
49
  * @param raw - Raw data from the bus
50
- * @param localNodeId - This connector's node ID
51
- * @param remoteNodeId - Expected remote node ID
52
- * @returns Unwrapped payload if frame is valid and addressed to us, null otherwise
50
+ * @returns Unwrapped frame with payload as Uint8Array, or null if invalid structure
53
51
  */
54
- export function unwrapTransportFrame(raw, localNodeId, remoteNodeId) {
52
+ export function unwrapTransportFrame(raw) {
55
53
  // Validate basic structure
56
54
  if (!raw || typeof raw !== 'object') {
57
55
  return null;
@@ -65,16 +63,17 @@ export function unwrapTransportFrame(raw, localNodeId, remoteNodeId) {
65
63
  if (typeof frame.src !== 'string' || typeof frame.dst !== 'string') {
66
64
  return null;
67
65
  }
68
- // Only accept frames addressed to us from the expected remote
69
- if (frame.dst !== localNodeId || frame.src !== remoteNodeId) {
70
- return null;
71
- }
72
66
  // Extract payload
73
67
  if (!frame.payload || !Array.isArray(frame.payload)) {
74
68
  return null;
75
69
  }
76
- // Convert array back to Uint8Array
77
- return Uint8Array.from(frame.payload);
70
+ // Convert array back to Uint8Array and return full frame
71
+ return {
72
+ v: frame.v,
73
+ src: frame.src,
74
+ dst: frame.dst,
75
+ payload: Uint8Array.from(frame.payload),
76
+ };
78
77
  }
79
78
  /**
80
79
  * Check if raw data looks like a transport frame
@@ -1,7 +1,7 @@
1
1
  // This file is auto-generated during build - do not edit manually
2
- // Generated from package.json version: 0.3.5-test.949
2
+ // Generated from package.json version: 0.3.5-test.951
3
3
  /**
4
4
  * The package version, injected at build time.
5
5
  * @internal
6
6
  */
7
- export const VERSION = '0.3.5-test.949';
7
+ export const VERSION = '0.3.5-test.951';