@sixfathoms/lplex 0.2.0 → 0.3.0
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/README.md +11 -2
- package/dist/index.cjs +60 -3
- package/dist/index.d.cts +52 -2
- package/dist/index.d.ts +52 -2
- package/dist/index.js +60 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ for (const d of devices) {
|
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
### `client.values(signal?): Promise<DeviceValues[]>`
|
|
61
|
+
### `client.values(filter?, signal?): Promise<DeviceValues[]>`
|
|
62
62
|
|
|
63
63
|
Returns the last-seen value for each (device, PGN) pair, grouped by device. Useful for getting a snapshot of current bus state without subscribing to SSE.
|
|
64
64
|
|
|
@@ -72,6 +72,15 @@ for (const device of snapshot) {
|
|
|
72
72
|
}
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
Pass a `Filter` to narrow results by PGN and/or device criteria:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const positions = await client.values({
|
|
79
|
+
pgn: [129025],
|
|
80
|
+
manufacturer: ["Garmin"],
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
75
84
|
### `client.subscribe(filter?, signal?): Promise<AsyncIterable<Event>>`
|
|
76
85
|
|
|
77
86
|
Opens an ephemeral SSE stream. No session state, no replay. Frames flow until you stop reading or abort.
|
|
@@ -326,7 +335,7 @@ interface DeviceValues {
|
|
|
326
335
|
| `/clients/{id}/ack` | PUT | ACK sequence number. JSON body: `{ "seq": N }`. Returns 204. |
|
|
327
336
|
| `/send` | POST | Transmit CAN frame. JSON body: `pgn`, `src`, `dst`, `prio`, `data`. Returns 202. |
|
|
328
337
|
| `/devices` | GET | Device snapshot. Returns JSON array. |
|
|
329
|
-
| `/values` | GET | Last-seen value per (device, PGN). Returns JSON array grouped by device. |
|
|
338
|
+
| `/values` | GET | Last-seen value per (device, PGN). Query params: `pgn`, `manufacturer`, `instance`, `name` (repeatable). Returns JSON array grouped by device. |
|
|
330
339
|
|
|
331
340
|
## License
|
|
332
341
|
|
package/dist/index.cjs
CHANGED
|
@@ -171,8 +171,10 @@ var Client = class {
|
|
|
171
171
|
return resp.json();
|
|
172
172
|
}
|
|
173
173
|
/** Fetch the last-seen value for each (device, PGN) pair. */
|
|
174
|
-
async values(signal) {
|
|
175
|
-
|
|
174
|
+
async values(filter, signal) {
|
|
175
|
+
let url = `${this.#baseURL}/values`;
|
|
176
|
+
const qs = filterToQueryString(filter);
|
|
177
|
+
if (qs) url += `?${qs}`;
|
|
176
178
|
const resp = await this.#fetch(url, { signal });
|
|
177
179
|
if (!resp.ok) {
|
|
178
180
|
const body = await resp.text();
|
|
@@ -201,6 +203,18 @@ var Client = class {
|
|
|
201
203
|
}
|
|
202
204
|
return parseSSE(resp.body);
|
|
203
205
|
}
|
|
206
|
+
/** Fetch the last-seen decoded values for each (device, PGN) pair. */
|
|
207
|
+
async decodedValues(filter, signal) {
|
|
208
|
+
let url = `${this.#baseURL}/values/decoded`;
|
|
209
|
+
const qs = filterToQueryString(filter);
|
|
210
|
+
if (qs) url += `?${qs}`;
|
|
211
|
+
const resp = await this.#fetch(url, { signal });
|
|
212
|
+
if (!resp.ok) {
|
|
213
|
+
const body = await resp.text();
|
|
214
|
+
throw new HttpError("GET", url, resp.status, body);
|
|
215
|
+
}
|
|
216
|
+
return resp.json();
|
|
217
|
+
}
|
|
204
218
|
/** Transmit a CAN frame through the server. */
|
|
205
219
|
async send(params, signal) {
|
|
206
220
|
const url = `${this.#baseURL}/send`;
|
|
@@ -215,6 +229,44 @@ var Client = class {
|
|
|
215
229
|
throw new HttpError("POST", url, resp.status, body);
|
|
216
230
|
}
|
|
217
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Send an ISO Request (PGN 59904) and wait for the response frame.
|
|
234
|
+
* Returns the response frame, or throws HttpError with status 504 on timeout.
|
|
235
|
+
*/
|
|
236
|
+
async query(params, signal) {
|
|
237
|
+
const url = `${this.#baseURL}/query`;
|
|
238
|
+
const resp = await this.#fetch(url, {
|
|
239
|
+
method: "POST",
|
|
240
|
+
headers: { "Content-Type": "application/json" },
|
|
241
|
+
body: JSON.stringify(params),
|
|
242
|
+
signal
|
|
243
|
+
});
|
|
244
|
+
if (!resp.ok) {
|
|
245
|
+
const body = await resp.text();
|
|
246
|
+
throw new HttpError("POST", url, resp.status, body);
|
|
247
|
+
}
|
|
248
|
+
return resp.json();
|
|
249
|
+
}
|
|
250
|
+
/** Check server health. */
|
|
251
|
+
async health(signal) {
|
|
252
|
+
const url = `${this.#baseURL}/healthz`;
|
|
253
|
+
const resp = await this.#fetch(url, { signal });
|
|
254
|
+
if (!resp.ok) {
|
|
255
|
+
const body = await resp.text();
|
|
256
|
+
throw new HttpError("GET", url, resp.status, body);
|
|
257
|
+
}
|
|
258
|
+
return resp.json();
|
|
259
|
+
}
|
|
260
|
+
/** Fetch boat-side replication status (only available when replication is configured). */
|
|
261
|
+
async replicationStatus(signal) {
|
|
262
|
+
const url = `${this.#baseURL}/replication/status`;
|
|
263
|
+
const resp = await this.#fetch(url, { signal });
|
|
264
|
+
if (!resp.ok) {
|
|
265
|
+
const body = await resp.text();
|
|
266
|
+
throw new HttpError("GET", url, resp.status, body);
|
|
267
|
+
}
|
|
268
|
+
return resp.json();
|
|
269
|
+
}
|
|
218
270
|
/** Create or reconnect a buffered session on the server. */
|
|
219
271
|
async createSession(config, signal) {
|
|
220
272
|
const url = `${this.#baseURL}/clients/${config.clientId}`;
|
|
@@ -239,23 +291,28 @@ var Client = class {
|
|
|
239
291
|
}
|
|
240
292
|
};
|
|
241
293
|
function filterIsEmpty(f) {
|
|
242
|
-
return !f.pgn?.length && !f.manufacturer?.length && !f.instance?.length && !f.name?.length;
|
|
294
|
+
return !f.pgn?.length && !f.exclude_pgn?.length && !f.manufacturer?.length && !f.instance?.length && !f.name?.length && !f.exclude_name?.length;
|
|
243
295
|
}
|
|
244
296
|
function filterToQueryString(f) {
|
|
245
297
|
if (!f || filterIsEmpty(f)) return "";
|
|
246
298
|
const params = new URLSearchParams();
|
|
247
299
|
for (const p of f.pgn ?? []) params.append("pgn", p.toString());
|
|
300
|
+
for (const p of f.exclude_pgn ?? [])
|
|
301
|
+
params.append("exclude_pgn", p.toString());
|
|
248
302
|
for (const m of f.manufacturer ?? []) params.append("manufacturer", m);
|
|
249
303
|
for (const i of f.instance ?? []) params.append("instance", i.toString());
|
|
250
304
|
for (const n of f.name ?? []) params.append("name", n);
|
|
305
|
+
for (const n of f.exclude_name ?? []) params.append("exclude_name", n);
|
|
251
306
|
return params.toString();
|
|
252
307
|
}
|
|
253
308
|
function filterToJSON(f) {
|
|
254
309
|
const m = {};
|
|
255
310
|
if (f.pgn?.length) m.pgn = f.pgn;
|
|
311
|
+
if (f.exclude_pgn?.length) m.exclude_pgn = f.exclude_pgn;
|
|
256
312
|
if (f.manufacturer?.length) m.manufacturer = f.manufacturer;
|
|
257
313
|
if (f.instance?.length) m.instance = f.instance;
|
|
258
314
|
if (f.name?.length) m.name = f.name;
|
|
315
|
+
if (f.exclude_name?.length) m.exclude_name = f.exclude_name;
|
|
259
316
|
return m;
|
|
260
317
|
}
|
|
261
318
|
|
package/dist/index.d.cts
CHANGED
|
@@ -42,9 +42,11 @@ type Event = {
|
|
|
42
42
|
*/
|
|
43
43
|
interface Filter {
|
|
44
44
|
pgn?: number[];
|
|
45
|
+
exclude_pgn?: number[];
|
|
45
46
|
manufacturer?: string[];
|
|
46
47
|
instance?: number[];
|
|
47
48
|
name?: string[];
|
|
49
|
+
exclude_name?: string[];
|
|
48
50
|
}
|
|
49
51
|
/** Configuration for creating a buffered session. */
|
|
50
52
|
interface SessionConfig {
|
|
@@ -82,6 +84,43 @@ interface DeviceValues {
|
|
|
82
84
|
model_id?: string;
|
|
83
85
|
values: PGNValue[];
|
|
84
86
|
}
|
|
87
|
+
/** A single PGN's decoded value for a device. */
|
|
88
|
+
interface DecodedPGNValue {
|
|
89
|
+
pgn: number;
|
|
90
|
+
ts: string;
|
|
91
|
+
data: string;
|
|
92
|
+
seq: number;
|
|
93
|
+
decoded: Record<string, unknown>;
|
|
94
|
+
}
|
|
95
|
+
/** Decoded values grouped by device. */
|
|
96
|
+
interface DecodedDeviceValues {
|
|
97
|
+
name: string;
|
|
98
|
+
src: number;
|
|
99
|
+
manufacturer?: string;
|
|
100
|
+
model_id?: string;
|
|
101
|
+
values: DecodedPGNValue[];
|
|
102
|
+
}
|
|
103
|
+
/** Parameters for an ISO Request query (POST /query). */
|
|
104
|
+
interface QueryParams {
|
|
105
|
+
pgn: number;
|
|
106
|
+
dst: number;
|
|
107
|
+
timeout?: string;
|
|
108
|
+
}
|
|
109
|
+
/** Health check response from GET /healthz. */
|
|
110
|
+
interface HealthStatus {
|
|
111
|
+
status: string;
|
|
112
|
+
}
|
|
113
|
+
/** Boat-side replication status from GET /replication/status. */
|
|
114
|
+
interface ReplicationStatus {
|
|
115
|
+
connected: boolean;
|
|
116
|
+
instance_id: string;
|
|
117
|
+
local_head_seq: number;
|
|
118
|
+
cloud_cursor: number;
|
|
119
|
+
holes: SeqRange[];
|
|
120
|
+
live_lag: number;
|
|
121
|
+
backfill_remaining_seqs: number;
|
|
122
|
+
last_ack: string;
|
|
123
|
+
}
|
|
85
124
|
/** Summary of a cloud instance, returned by GET /instances. */
|
|
86
125
|
interface InstanceSummary {
|
|
87
126
|
id: string;
|
|
@@ -143,14 +182,25 @@ declare class Client {
|
|
|
143
182
|
/** Fetch a snapshot of all NMEA 2000 devices discovered by the server. */
|
|
144
183
|
devices(signal?: AbortSignal): Promise<Device[]>;
|
|
145
184
|
/** Fetch the last-seen value for each (device, PGN) pair. */
|
|
146
|
-
values(signal?: AbortSignal): Promise<DeviceValues[]>;
|
|
185
|
+
values(filter?: Filter, signal?: AbortSignal): Promise<DeviceValues[]>;
|
|
147
186
|
/**
|
|
148
187
|
* Open an ephemeral SSE stream with optional filtering.
|
|
149
188
|
* No session, no replay, no ACK.
|
|
150
189
|
*/
|
|
151
190
|
subscribe(filter?: Filter, signal?: AbortSignal): Promise<AsyncIterable<Event>>;
|
|
191
|
+
/** Fetch the last-seen decoded values for each (device, PGN) pair. */
|
|
192
|
+
decodedValues(filter?: Filter, signal?: AbortSignal): Promise<DecodedDeviceValues[]>;
|
|
152
193
|
/** Transmit a CAN frame through the server. */
|
|
153
194
|
send(params: SendParams, signal?: AbortSignal): Promise<void>;
|
|
195
|
+
/**
|
|
196
|
+
* Send an ISO Request (PGN 59904) and wait for the response frame.
|
|
197
|
+
* Returns the response frame, or throws HttpError with status 504 on timeout.
|
|
198
|
+
*/
|
|
199
|
+
query(params: QueryParams, signal?: AbortSignal): Promise<Frame>;
|
|
200
|
+
/** Check server health. */
|
|
201
|
+
health(signal?: AbortSignal): Promise<HealthStatus>;
|
|
202
|
+
/** Fetch boat-side replication status (only available when replication is configured). */
|
|
203
|
+
replicationStatus(signal?: AbortSignal): Promise<ReplicationStatus>;
|
|
154
204
|
/** Create or reconnect a buffered session on the server. */
|
|
155
205
|
createSession(config: SessionConfig, signal?: AbortSignal): Promise<Session>;
|
|
156
206
|
}
|
|
@@ -191,4 +241,4 @@ declare class HttpError extends LplexError {
|
|
|
191
241
|
constructor(method: string, path: string, status: number, body: string);
|
|
192
242
|
}
|
|
193
243
|
|
|
194
|
-
export { Client, type ClientOptions, CloudClient, type CloudClientOptions, type Device, type DeviceValues, type Event, type Filter, type Frame, HttpError, type InstanceStatus, type InstanceSummary, LplexError, type PGNValue, type ReplicationEvent, type ReplicationEventType, type SendParams, type SeqRange, Session, type SessionConfig, type SessionInfo };
|
|
244
|
+
export { Client, type ClientOptions, CloudClient, type CloudClientOptions, type DecodedDeviceValues, type DecodedPGNValue, type Device, type DeviceValues, type Event, type Filter, type Frame, type HealthStatus, HttpError, type InstanceStatus, type InstanceSummary, LplexError, type PGNValue, type QueryParams, type ReplicationEvent, type ReplicationEventType, type ReplicationStatus, type SendParams, type SeqRange, Session, type SessionConfig, type SessionInfo };
|
package/dist/index.d.ts
CHANGED
|
@@ -42,9 +42,11 @@ type Event = {
|
|
|
42
42
|
*/
|
|
43
43
|
interface Filter {
|
|
44
44
|
pgn?: number[];
|
|
45
|
+
exclude_pgn?: number[];
|
|
45
46
|
manufacturer?: string[];
|
|
46
47
|
instance?: number[];
|
|
47
48
|
name?: string[];
|
|
49
|
+
exclude_name?: string[];
|
|
48
50
|
}
|
|
49
51
|
/** Configuration for creating a buffered session. */
|
|
50
52
|
interface SessionConfig {
|
|
@@ -82,6 +84,43 @@ interface DeviceValues {
|
|
|
82
84
|
model_id?: string;
|
|
83
85
|
values: PGNValue[];
|
|
84
86
|
}
|
|
87
|
+
/** A single PGN's decoded value for a device. */
|
|
88
|
+
interface DecodedPGNValue {
|
|
89
|
+
pgn: number;
|
|
90
|
+
ts: string;
|
|
91
|
+
data: string;
|
|
92
|
+
seq: number;
|
|
93
|
+
decoded: Record<string, unknown>;
|
|
94
|
+
}
|
|
95
|
+
/** Decoded values grouped by device. */
|
|
96
|
+
interface DecodedDeviceValues {
|
|
97
|
+
name: string;
|
|
98
|
+
src: number;
|
|
99
|
+
manufacturer?: string;
|
|
100
|
+
model_id?: string;
|
|
101
|
+
values: DecodedPGNValue[];
|
|
102
|
+
}
|
|
103
|
+
/** Parameters for an ISO Request query (POST /query). */
|
|
104
|
+
interface QueryParams {
|
|
105
|
+
pgn: number;
|
|
106
|
+
dst: number;
|
|
107
|
+
timeout?: string;
|
|
108
|
+
}
|
|
109
|
+
/** Health check response from GET /healthz. */
|
|
110
|
+
interface HealthStatus {
|
|
111
|
+
status: string;
|
|
112
|
+
}
|
|
113
|
+
/** Boat-side replication status from GET /replication/status. */
|
|
114
|
+
interface ReplicationStatus {
|
|
115
|
+
connected: boolean;
|
|
116
|
+
instance_id: string;
|
|
117
|
+
local_head_seq: number;
|
|
118
|
+
cloud_cursor: number;
|
|
119
|
+
holes: SeqRange[];
|
|
120
|
+
live_lag: number;
|
|
121
|
+
backfill_remaining_seqs: number;
|
|
122
|
+
last_ack: string;
|
|
123
|
+
}
|
|
85
124
|
/** Summary of a cloud instance, returned by GET /instances. */
|
|
86
125
|
interface InstanceSummary {
|
|
87
126
|
id: string;
|
|
@@ -143,14 +182,25 @@ declare class Client {
|
|
|
143
182
|
/** Fetch a snapshot of all NMEA 2000 devices discovered by the server. */
|
|
144
183
|
devices(signal?: AbortSignal): Promise<Device[]>;
|
|
145
184
|
/** Fetch the last-seen value for each (device, PGN) pair. */
|
|
146
|
-
values(signal?: AbortSignal): Promise<DeviceValues[]>;
|
|
185
|
+
values(filter?: Filter, signal?: AbortSignal): Promise<DeviceValues[]>;
|
|
147
186
|
/**
|
|
148
187
|
* Open an ephemeral SSE stream with optional filtering.
|
|
149
188
|
* No session, no replay, no ACK.
|
|
150
189
|
*/
|
|
151
190
|
subscribe(filter?: Filter, signal?: AbortSignal): Promise<AsyncIterable<Event>>;
|
|
191
|
+
/** Fetch the last-seen decoded values for each (device, PGN) pair. */
|
|
192
|
+
decodedValues(filter?: Filter, signal?: AbortSignal): Promise<DecodedDeviceValues[]>;
|
|
152
193
|
/** Transmit a CAN frame through the server. */
|
|
153
194
|
send(params: SendParams, signal?: AbortSignal): Promise<void>;
|
|
195
|
+
/**
|
|
196
|
+
* Send an ISO Request (PGN 59904) and wait for the response frame.
|
|
197
|
+
* Returns the response frame, or throws HttpError with status 504 on timeout.
|
|
198
|
+
*/
|
|
199
|
+
query(params: QueryParams, signal?: AbortSignal): Promise<Frame>;
|
|
200
|
+
/** Check server health. */
|
|
201
|
+
health(signal?: AbortSignal): Promise<HealthStatus>;
|
|
202
|
+
/** Fetch boat-side replication status (only available when replication is configured). */
|
|
203
|
+
replicationStatus(signal?: AbortSignal): Promise<ReplicationStatus>;
|
|
154
204
|
/** Create or reconnect a buffered session on the server. */
|
|
155
205
|
createSession(config: SessionConfig, signal?: AbortSignal): Promise<Session>;
|
|
156
206
|
}
|
|
@@ -191,4 +241,4 @@ declare class HttpError extends LplexError {
|
|
|
191
241
|
constructor(method: string, path: string, status: number, body: string);
|
|
192
242
|
}
|
|
193
243
|
|
|
194
|
-
export { Client, type ClientOptions, CloudClient, type CloudClientOptions, type Device, type DeviceValues, type Event, type Filter, type Frame, HttpError, type InstanceStatus, type InstanceSummary, LplexError, type PGNValue, type ReplicationEvent, type ReplicationEventType, type SendParams, type SeqRange, Session, type SessionConfig, type SessionInfo };
|
|
244
|
+
export { Client, type ClientOptions, CloudClient, type CloudClientOptions, type DecodedDeviceValues, type DecodedPGNValue, type Device, type DeviceValues, type Event, type Filter, type Frame, type HealthStatus, HttpError, type InstanceStatus, type InstanceSummary, LplexError, type PGNValue, type QueryParams, type ReplicationEvent, type ReplicationEventType, type ReplicationStatus, type SendParams, type SeqRange, Session, type SessionConfig, type SessionInfo };
|
package/dist/index.js
CHANGED
|
@@ -141,8 +141,10 @@ var Client = class {
|
|
|
141
141
|
return resp.json();
|
|
142
142
|
}
|
|
143
143
|
/** Fetch the last-seen value for each (device, PGN) pair. */
|
|
144
|
-
async values(signal) {
|
|
145
|
-
|
|
144
|
+
async values(filter, signal) {
|
|
145
|
+
let url = `${this.#baseURL}/values`;
|
|
146
|
+
const qs = filterToQueryString(filter);
|
|
147
|
+
if (qs) url += `?${qs}`;
|
|
146
148
|
const resp = await this.#fetch(url, { signal });
|
|
147
149
|
if (!resp.ok) {
|
|
148
150
|
const body = await resp.text();
|
|
@@ -171,6 +173,18 @@ var Client = class {
|
|
|
171
173
|
}
|
|
172
174
|
return parseSSE(resp.body);
|
|
173
175
|
}
|
|
176
|
+
/** Fetch the last-seen decoded values for each (device, PGN) pair. */
|
|
177
|
+
async decodedValues(filter, signal) {
|
|
178
|
+
let url = `${this.#baseURL}/values/decoded`;
|
|
179
|
+
const qs = filterToQueryString(filter);
|
|
180
|
+
if (qs) url += `?${qs}`;
|
|
181
|
+
const resp = await this.#fetch(url, { signal });
|
|
182
|
+
if (!resp.ok) {
|
|
183
|
+
const body = await resp.text();
|
|
184
|
+
throw new HttpError("GET", url, resp.status, body);
|
|
185
|
+
}
|
|
186
|
+
return resp.json();
|
|
187
|
+
}
|
|
174
188
|
/** Transmit a CAN frame through the server. */
|
|
175
189
|
async send(params, signal) {
|
|
176
190
|
const url = `${this.#baseURL}/send`;
|
|
@@ -185,6 +199,44 @@ var Client = class {
|
|
|
185
199
|
throw new HttpError("POST", url, resp.status, body);
|
|
186
200
|
}
|
|
187
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Send an ISO Request (PGN 59904) and wait for the response frame.
|
|
204
|
+
* Returns the response frame, or throws HttpError with status 504 on timeout.
|
|
205
|
+
*/
|
|
206
|
+
async query(params, signal) {
|
|
207
|
+
const url = `${this.#baseURL}/query`;
|
|
208
|
+
const resp = await this.#fetch(url, {
|
|
209
|
+
method: "POST",
|
|
210
|
+
headers: { "Content-Type": "application/json" },
|
|
211
|
+
body: JSON.stringify(params),
|
|
212
|
+
signal
|
|
213
|
+
});
|
|
214
|
+
if (!resp.ok) {
|
|
215
|
+
const body = await resp.text();
|
|
216
|
+
throw new HttpError("POST", url, resp.status, body);
|
|
217
|
+
}
|
|
218
|
+
return resp.json();
|
|
219
|
+
}
|
|
220
|
+
/** Check server health. */
|
|
221
|
+
async health(signal) {
|
|
222
|
+
const url = `${this.#baseURL}/healthz`;
|
|
223
|
+
const resp = await this.#fetch(url, { signal });
|
|
224
|
+
if (!resp.ok) {
|
|
225
|
+
const body = await resp.text();
|
|
226
|
+
throw new HttpError("GET", url, resp.status, body);
|
|
227
|
+
}
|
|
228
|
+
return resp.json();
|
|
229
|
+
}
|
|
230
|
+
/** Fetch boat-side replication status (only available when replication is configured). */
|
|
231
|
+
async replicationStatus(signal) {
|
|
232
|
+
const url = `${this.#baseURL}/replication/status`;
|
|
233
|
+
const resp = await this.#fetch(url, { signal });
|
|
234
|
+
if (!resp.ok) {
|
|
235
|
+
const body = await resp.text();
|
|
236
|
+
throw new HttpError("GET", url, resp.status, body);
|
|
237
|
+
}
|
|
238
|
+
return resp.json();
|
|
239
|
+
}
|
|
188
240
|
/** Create or reconnect a buffered session on the server. */
|
|
189
241
|
async createSession(config, signal) {
|
|
190
242
|
const url = `${this.#baseURL}/clients/${config.clientId}`;
|
|
@@ -209,23 +261,28 @@ var Client = class {
|
|
|
209
261
|
}
|
|
210
262
|
};
|
|
211
263
|
function filterIsEmpty(f) {
|
|
212
|
-
return !f.pgn?.length && !f.manufacturer?.length && !f.instance?.length && !f.name?.length;
|
|
264
|
+
return !f.pgn?.length && !f.exclude_pgn?.length && !f.manufacturer?.length && !f.instance?.length && !f.name?.length && !f.exclude_name?.length;
|
|
213
265
|
}
|
|
214
266
|
function filterToQueryString(f) {
|
|
215
267
|
if (!f || filterIsEmpty(f)) return "";
|
|
216
268
|
const params = new URLSearchParams();
|
|
217
269
|
for (const p of f.pgn ?? []) params.append("pgn", p.toString());
|
|
270
|
+
for (const p of f.exclude_pgn ?? [])
|
|
271
|
+
params.append("exclude_pgn", p.toString());
|
|
218
272
|
for (const m of f.manufacturer ?? []) params.append("manufacturer", m);
|
|
219
273
|
for (const i of f.instance ?? []) params.append("instance", i.toString());
|
|
220
274
|
for (const n of f.name ?? []) params.append("name", n);
|
|
275
|
+
for (const n of f.exclude_name ?? []) params.append("exclude_name", n);
|
|
221
276
|
return params.toString();
|
|
222
277
|
}
|
|
223
278
|
function filterToJSON(f) {
|
|
224
279
|
const m = {};
|
|
225
280
|
if (f.pgn?.length) m.pgn = f.pgn;
|
|
281
|
+
if (f.exclude_pgn?.length) m.exclude_pgn = f.exclude_pgn;
|
|
226
282
|
if (f.manufacturer?.length) m.manufacturer = f.manufacturer;
|
|
227
283
|
if (f.instance?.length) m.instance = f.instance;
|
|
228
284
|
if (f.name?.length) m.name = f.name;
|
|
285
|
+
if (f.exclude_name?.length) m.exclude_name = f.exclude_name;
|
|
229
286
|
return m;
|
|
230
287
|
}
|
|
231
288
|
|