-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathindex.d.ts
More file actions
207 lines (186 loc) · 7.79 KB
/
index.d.ts
File metadata and controls
207 lines (186 loc) · 7.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// Copyright (c) 2026 RobotWebTools Contributors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// TypeScript surface for the rclnodejs Web Runtime browser SDK.
//
// Goal: minimum setup. The user supplies one string per call — the
// ROS interface name — and the SDK derives the request, response, and
// message shapes from rclnodejs's auto-generated MessagesMap / ServicesMap.
//
// const reply = await ros.call<'example_interfaces/srv/AddTwoInts'>(
// '/add_two_ints', { a: '2n', b: '40n' } // typed
// );
//
// const sub = await ros.subscribe<'std_msgs/msg/String'>(
// '/scan', (m) => render(m.data) // m.data: string
// );
//
// Untyped fallbacks (no generic) are kept so capabilities not in the
// generated maps still work.
declare module 'rclnodejs/web' {
// -------- Wire-shape mapping ----------------------------------------
/** Wire encoding of a ROS 2 64-bit integer field. */
export type Int64Wire = `${number}n`;
/**
* Map an in-process rclnodejs message shape to its on-wire JSON shape.
*
* The Web Runtime serialises messages as JSON with one transformation:
* 64-bit integer fields (`bigint` in the generated types) become the
* string `"<n>n"` so they survive `JSON.stringify`. Everything else
* passes through unchanged.
*
* Cases (checked in order):
* - `bigint` → {@link Int64Wire} (the `"<n>n"` string)
* - `ReadonlyArray<U>` → `WireType<U>[]` (recurse per element)
* - `Date` → `string` (ISO string on the wire)
* - `object` → field-wise recursion
* - everything else → passes through unchanged
*
* @experimental — exposed for advanced consumers that want to derive
* wire shapes by hand. Most users should rely on the type-name
* generics on {@link RosClient.call} / `subscribe` / etc., which
* apply this mapping internally.
*/
// The bigint check uses `[T] extends [bigint]` (tuple wrapper) instead
// of bare `T extends bigint` so the conditional doesn't distribute
// across union members like `bigint | string` (which would map only
// the bigint half and silently drop the rest).
export type WireType<T> = [T] extends [bigint] ? Int64Wire : _WireRecurse<T>;
/** Recursion step for {@link WireType}; pulled out to keep the cascade flat. */
type _WireRecurse<T> =
T extends ReadonlyArray<infer U>
? WireType<U>[]
: T extends Date
? string
: T extends object
? { [K in keyof T]: WireType<T[K]> }
: T;
// -------- Type-name lookup helpers ----------------------------------
// The maps below are declared by rclnodejs's own .d.ts files via a
// `declare module 'rclnodejs' { type MessagesMap = {...} }` augmentation.
// Reaching them across the module boundary requires the inline
// `import('rclnodejs')` form — a default-style `import type rclnodejs
// from 'rclnodejs'` would resolve to the runtime's *value* export, not
// the namespace, and `MessagesMap` would silently collapse to `never`.
/** ROS 2 message type names available in the sourced environment. */
export type MessageName = keyof import('rclnodejs').MessagesMap;
/** ROS 2 service type names available in the sourced environment. */
export type ServiceName = keyof import('rclnodejs').ServicesMap;
/** Wire shape of the named message. `Msg<'std_msgs/msg/String'>` → `{ data: string }`. */
export type Msg<TName extends MessageName> = WireType<
import('rclnodejs').MessagesMap[TName]
>;
type _SvcCtor<TName extends ServiceName> =
import('rclnodejs').ServicesMap[TName];
/** Wire shape of the named service request. */
export type SvcReq<TName extends ServiceName> = WireType<
InstanceType<_SvcCtor<TName>['Request']>
>;
/** Wire shape of the named service response. */
export type SvcResp<TName extends ServiceName> = WireType<
InstanceType<_SvcCtor<TName>['Response']>
>;
// -------- SDK ------------------------------------------------------
/**
* Subscription handle returned by {@link RosClient.subscribe}.
* Closing the handle cancels the subscription on the runtime side.
*/
export interface Subscription {
readonly subId: string;
close(): Promise<void>;
}
export interface ConnectOptions {
/**
* Reserved for future reconnect-on-close support. Setting this to
* `true` today has no effect; the SDK warns and continues with
* single-shot connection semantics.
*/
reconnect?: boolean;
}
/**
* Pair of explicit endpoints when HTTP and WebSocket live behind
* different URLs (e.g. one is fronted by a TLS proxy, the other isn't).
* Pass either field on its own to limit the client to that transport.
*/
export interface ConnectEndpoints {
/** Base URL for the HTTP capability transport (`POST /capability/...`). */
http?: string;
/** Full URL of the WebSocket capability endpoint. */
ws?: string;
}
/**
* Browser-native Web Runtime client.
*
* The user-facing verb API (`call` / `publish` / `subscribe`) is the
* same regardless of transport. The transport(s) used underneath
* are picked from the URL scheme passed to {@link connect}:
*
* - `ws://` / `wss://` — WebSocket only.
* - `http://` / `https://` — HTTP for `call`/`publish`; subscribe
* falls through to a sibling WebSocket endpoint at the same
* host with `/capability` appended.
* - {@link ConnectEndpoints} — both URLs spelled out.
*
* **Path conventions.** When a `ws://` / `wss://` URL is passed
* without a path (or with just `/`), the SDK appends the runtime's
* default `/capability` path automatically — so `'ws://host:9000'`
* and `'ws://host:9000/capability'` behave identically. Pass an
* explicit non-default path if your server changed `--path` /
* `--http-base-path` or sits behind a path-rewriting proxy.
*/
export class RosClient {
readonly url: string;
constructor(url: string | ConnectEndpoints, options?: ConnectOptions);
connect(): Promise<this>;
close(): Promise<void>;
/**
* Invoke a service capability.
*
* @example Typed via the ROS service type name (preferred)
* const reply = await ros.call<'example_interfaces/srv/AddTwoInts'>(
* '/add_two_ints', { a: '2n', b: '40n' }
* );
* console.log(reply.sum);
*
* @example Untyped (capability with a custom type not in the
* generated maps, or quick prototyping)
* const reply = await ros.call('/whatever', { foo: 1 });
*/
call<TName extends ServiceName>(
capability: string,
request: SvcReq<TName>
): Promise<SvcResp<TName>>;
call(capability: string, request: unknown): Promise<unknown>;
/** Publish a message to a topic capability. */
publish<TName extends MessageName>(
capability: string,
message: Msg<TName>
): Promise<void>;
publish(capability: string, message: unknown): Promise<void>;
/** Subscribe to messages on a topic capability. */
subscribe<TName extends MessageName>(
capability: string,
callback: (msg: Msg<TName>) => void
): Promise<Subscription>;
subscribe(
capability: string,
callback: (msg: unknown) => void
): Promise<Subscription>;
}
/**
* Open a connection to a Web Runtime capability endpoint.
* Convenience wrapper around `new RosClient(...).connect()`.
*
* @param url Either a single URL (`ws://`, `wss://`, `http://`,
* `https://`) or a {@link ConnectEndpoints} pair.
*/
export function connect(
url: string | ConnectEndpoints,
options?: ConnectOptions
): Promise<RosClient>;
}