Skip to content

Commit c0a3d1c

Browse files
committed
Address comments
1 parent 15c6fc0 commit c0a3d1c

2 files changed

Lines changed: 114 additions & 0 deletions

File tree

lib/runtime/connection.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2026 RobotWebTools Contributors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
9+
'use strict';
10+
11+
const EventEmitter = require('events');
12+
13+
/**
14+
* @typedef {Object} CapabilityFrame
15+
* @property {string|number} [id] - Caller-assigned request id (echoed in reply).
16+
* @property {'call'|'publish'|'subscribe'|'unsubscribe'|'action'} [kind] - Request kind (C→S only). `'action'` is reserved and currently returns `code: 'not_implemented'`.
17+
* @property {string} [capability] - Capability name, e.g. `/cmd_vel`.
18+
* @property {*} [payload] - Message payload (call request, publish msg, sub event).
19+
* @property {string|number} [subId] - For unsubscribe: id of the original subscribe.
20+
* @property {boolean} [ok] - Reply success flag (S→C only).
21+
* @property {string} [event] - `'message'` for streamed subscription deliveries.
22+
* @property {string} [error] - Human-readable error message on failure.
23+
* @property {string} [code] - Stable machine-readable error code.
24+
*/
25+
26+
/**
27+
* Per-connection abstraction handed to the runtime by a transport adapter.
28+
*
29+
* The transport owns the wire (WebSocket today; other adapters may follow)
30+
* and exposes each connection as a `Connection` so the runtime can stay
31+
* transport-agnostic. Concrete adapters subclass `Connection` and call
32+
* `this.emit('message', frame)` / `this.emit('close')` as frames arrive on
33+
* the wire, and implement `send(frame)` / `close(code, reason)` to push
34+
* frames back out.
35+
*
36+
* @experimental — the base class shape may grow (e.g. backpressure hooks)
37+
* and is not part of the SemVer-stable surface for third-party adapter
38+
* authors. The first-party `WebSocketTransport` is stable and recommended
39+
* for production use.
40+
*
41+
* @event Connection#message
42+
* @type {CapabilityFrame}
43+
*
44+
* @event Connection#close
45+
*/
46+
class Connection extends EventEmitter {
47+
/**
48+
* Push a frame to the remote peer. Implementations should silently drop
49+
* sends on a closed connection rather than throwing.
50+
* @param {CapabilityFrame} frame
51+
*/
52+
// eslint-disable-next-line no-unused-vars
53+
send(frame) {
54+
throw new Error('Connection.send() must be implemented by the transport');
55+
}
56+
57+
/**
58+
* Close the connection.
59+
* @param {number} [code]
60+
* @param {string} [reason]
61+
*/
62+
// eslint-disable-next-line no-unused-vars
63+
close(code, reason) {
64+
throw new Error('Connection.close() must be implemented by the transport');
65+
}
66+
}
67+
68+
module.exports = { Connection };

lib/runtime/transport_adapter.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) 2026 RobotWebTools Contributors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
9+
'use strict';
10+
11+
/**
12+
* Base class / contract for transport adapters.
13+
*
14+
* A transport adapter:
15+
* 1. Owns the network listener (WS / HTTP / SSE / ...).
16+
* 2. Builds a {@link import('./connection.js').Connection} per accepted client.
17+
* 3. Calls `onConnection(conn)` from the start options once per client.
18+
*
19+
* The runtime never speaks to the wire directly — it only consumes the
20+
* Connection event surface. This is the seam that lets future adapters
21+
* (HTTP, etc.) drop in without touching the runtime or the SDK.
22+
*
23+
* @experimental — same forward-compat caveat as
24+
* {@link import('./connection.js').Connection}: the adapter contract may
25+
* grow to support new transports. First-party `WebSocketTransport` is
26+
* stable.
27+
*/
28+
class TransportAdapter {
29+
/**
30+
* Begin accepting connections.
31+
* @param {object} options
32+
* @param {(conn: import('./connection.js').Connection) => void} options.onConnection
33+
* @returns {Promise<{address: string, port: number}>}
34+
*/
35+
// eslint-disable-next-line no-unused-vars
36+
async start(options) {
37+
throw new Error('TransportAdapter.start() must be implemented');
38+
}
39+
40+
/** Stop accepting and close all open connections. */
41+
async stop() {
42+
throw new Error('TransportAdapter.stop() must be implemented');
43+
}
44+
}
45+
46+
module.exports = { TransportAdapter };

0 commit comments

Comments
 (0)