@ceralive/cerastream 2026.6.0-rc.1
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 +88 -0
- package/dist/client.d.ts +58 -0
- package/dist/client.js +274 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.js +54 -0
- package/dist/constants.d.ts +31 -0
- package/dist/constants.js +35 -0
- package/dist/envelope.d.ts +49 -0
- package/dist/envelope.js +52 -0
- package/dist/errors.d.ts +71 -0
- package/dist/errors.js +95 -0
- package/dist/events.d.ts +334 -0
- package/dist/events.js +97 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +13 -0
- package/dist/messages.d.ts +394 -0
- package/dist/messages.js +152 -0
- package/dist/paths.d.ts +14 -0
- package/dist/paths.js +72 -0
- package/dist/transport.d.ts +30 -0
- package/dist/transport.js +98 -0
- package/dist/types.d.ts +110 -0
- package/dist/types.js +69 -0
- package/package.json +41 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const startParamsSchema: z.ZodObject<{
|
|
3
|
+
pipeline: z.ZodString;
|
|
4
|
+
srt: z.ZodObject<{
|
|
5
|
+
host: z.ZodString;
|
|
6
|
+
port: z.ZodNumber;
|
|
7
|
+
streamid: z.ZodOptional<z.ZodString>;
|
|
8
|
+
latency_ms: z.ZodNumber;
|
|
9
|
+
reduced_packet_size: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
bitrate: z.ZodObject<{
|
|
12
|
+
min_bitrate: z.ZodNumber;
|
|
13
|
+
max_bitrate: z.ZodNumber;
|
|
14
|
+
balancer: z.ZodDefault<z.ZodEnum<{
|
|
15
|
+
adaptive: "adaptive";
|
|
16
|
+
fixed: "fixed";
|
|
17
|
+
aimd: "aimd";
|
|
18
|
+
}>>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
input_id: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
export type StartParams = z.infer<typeof startParamsSchema>;
|
|
23
|
+
export declare const startResultSchema: z.ZodObject<{
|
|
24
|
+
session_id: z.ZodString;
|
|
25
|
+
state: z.ZodEnum<{
|
|
26
|
+
idle: "idle";
|
|
27
|
+
starting: "starting";
|
|
28
|
+
streaming: "streaming";
|
|
29
|
+
stopping: "stopping";
|
|
30
|
+
}>;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
export type StartResult = z.infer<typeof startResultSchema>;
|
|
33
|
+
export declare const stopParamsSchema: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
export type StopParams = z.infer<typeof stopParamsSchema>;
|
|
37
|
+
export declare const stopResultSchema: z.ZodObject<{
|
|
38
|
+
state: z.ZodEnum<{
|
|
39
|
+
idle: "idle";
|
|
40
|
+
starting: "starting";
|
|
41
|
+
streaming: "streaming";
|
|
42
|
+
stopping: "stopping";
|
|
43
|
+
}>;
|
|
44
|
+
}, z.core.$strip>;
|
|
45
|
+
export type StopResult = z.infer<typeof stopResultSchema>;
|
|
46
|
+
export declare const reloadConfigParamsSchema: z.ZodObject<{
|
|
47
|
+
bitrate: z.ZodOptional<z.ZodObject<{
|
|
48
|
+
min_bitrate: z.ZodOptional<z.ZodNumber>;
|
|
49
|
+
max_bitrate: z.ZodOptional<z.ZodNumber>;
|
|
50
|
+
balancer: z.ZodOptional<z.ZodEnum<{
|
|
51
|
+
adaptive: "adaptive";
|
|
52
|
+
fixed: "fixed";
|
|
53
|
+
aimd: "aimd";
|
|
54
|
+
}>>;
|
|
55
|
+
}, z.core.$strip>>;
|
|
56
|
+
srt: z.ZodOptional<z.ZodObject<{
|
|
57
|
+
latency_ms: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
}, z.core.$strip>>;
|
|
59
|
+
}, z.core.$strip>;
|
|
60
|
+
export type ReloadConfigParams = z.infer<typeof reloadConfigParamsSchema>;
|
|
61
|
+
export declare const reloadConfigResultSchema: z.ZodObject<{
|
|
62
|
+
applied: z.ZodObject<{
|
|
63
|
+
bitrate: z.ZodOptional<z.ZodObject<{
|
|
64
|
+
min_bitrate: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
max_bitrate: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
balancer: z.ZodOptional<z.ZodEnum<{
|
|
67
|
+
adaptive: "adaptive";
|
|
68
|
+
fixed: "fixed";
|
|
69
|
+
aimd: "aimd";
|
|
70
|
+
}>>;
|
|
71
|
+
}, z.core.$strip>>;
|
|
72
|
+
srt: z.ZodOptional<z.ZodObject<{
|
|
73
|
+
latency_ms: z.ZodOptional<z.ZodNumber>;
|
|
74
|
+
}, z.core.$strip>>;
|
|
75
|
+
}, z.core.$strip>;
|
|
76
|
+
}, z.core.$strip>;
|
|
77
|
+
export type ReloadConfigResult = z.infer<typeof reloadConfigResultSchema>;
|
|
78
|
+
export declare const setBitrateParamsSchema: z.ZodObject<{
|
|
79
|
+
max_bitrate: z.ZodNumber;
|
|
80
|
+
}, z.core.$strip>;
|
|
81
|
+
export type SetBitrateParams = z.infer<typeof setBitrateParamsSchema>;
|
|
82
|
+
export declare const setBitrateResultSchema: z.ZodObject<{
|
|
83
|
+
applied: z.ZodObject<{
|
|
84
|
+
max_bitrate: z.ZodNumber;
|
|
85
|
+
}, z.core.$strip>;
|
|
86
|
+
}, z.core.$strip>;
|
|
87
|
+
export type SetBitrateResult = z.infer<typeof setBitrateResultSchema>;
|
|
88
|
+
export declare const switchInputParamsSchema: z.ZodObject<{
|
|
89
|
+
input_id: z.ZodString;
|
|
90
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
91
|
+
manual: "manual";
|
|
92
|
+
auto: "auto";
|
|
93
|
+
}>>;
|
|
94
|
+
}, z.core.$strip>;
|
|
95
|
+
export type SwitchInputParams = z.infer<typeof switchInputParamsSchema>;
|
|
96
|
+
export declare const switchInputResultSchema: z.ZodObject<{
|
|
97
|
+
active_input: z.ZodString;
|
|
98
|
+
mode: z.ZodEnum<{
|
|
99
|
+
manual: "manual";
|
|
100
|
+
auto: "auto";
|
|
101
|
+
}>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
export type SwitchInputResult = z.infer<typeof switchInputResultSchema>;
|
|
104
|
+
export declare const listDevicesParamsSchema: z.ZodOptional<z.ZodObject<{
|
|
105
|
+
media_class: z.ZodOptional<z.ZodEnum<{
|
|
106
|
+
video: "video";
|
|
107
|
+
audio: "audio";
|
|
108
|
+
}>>;
|
|
109
|
+
}, z.core.$strip>>;
|
|
110
|
+
export type ListDevicesParams = z.infer<typeof listDevicesParamsSchema>;
|
|
111
|
+
export declare const listDevicesResultSchema: z.ZodObject<{
|
|
112
|
+
devices: z.ZodArray<z.ZodObject<{
|
|
113
|
+
input_id: z.ZodString;
|
|
114
|
+
device_path: z.ZodString;
|
|
115
|
+
display_name: z.ZodString;
|
|
116
|
+
media_class: z.ZodEnum<{
|
|
117
|
+
video: "video";
|
|
118
|
+
audio: "audio";
|
|
119
|
+
}>;
|
|
120
|
+
caps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
121
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
122
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
123
|
+
framerate: z.ZodOptional<z.ZodString>;
|
|
124
|
+
}, z.core.$strip>>>;
|
|
125
|
+
}, z.core.$strip>>;
|
|
126
|
+
}, z.core.$strip>;
|
|
127
|
+
export type ListDevicesResult = z.infer<typeof listDevicesResultSchema>;
|
|
128
|
+
export declare const eventTopicSchema: z.ZodEnum<{
|
|
129
|
+
error: "error";
|
|
130
|
+
bitrate: "bitrate";
|
|
131
|
+
status: "status";
|
|
132
|
+
switch: "switch";
|
|
133
|
+
device: "device";
|
|
134
|
+
"srt-stats": "srt-stats";
|
|
135
|
+
preview: "preview";
|
|
136
|
+
}>;
|
|
137
|
+
export type EventTopic = z.infer<typeof eventTopicSchema>;
|
|
138
|
+
export declare const subscribeEventsParamsSchema: z.ZodObject<{
|
|
139
|
+
topics: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
140
|
+
error: "error";
|
|
141
|
+
bitrate: "bitrate";
|
|
142
|
+
status: "status";
|
|
143
|
+
switch: "switch";
|
|
144
|
+
device: "device";
|
|
145
|
+
"srt-stats": "srt-stats";
|
|
146
|
+
preview: "preview";
|
|
147
|
+
}>>>;
|
|
148
|
+
}, z.core.$strip>;
|
|
149
|
+
export type SubscribeEventsParams = z.infer<typeof subscribeEventsParamsSchema>;
|
|
150
|
+
export declare const subscribeEventsResultSchema: z.ZodObject<{
|
|
151
|
+
subscribed: z.ZodArray<z.ZodEnum<{
|
|
152
|
+
error: "error";
|
|
153
|
+
bitrate: "bitrate";
|
|
154
|
+
status: "status";
|
|
155
|
+
switch: "switch";
|
|
156
|
+
device: "device";
|
|
157
|
+
"srt-stats": "srt-stats";
|
|
158
|
+
preview: "preview";
|
|
159
|
+
}>>;
|
|
160
|
+
}, z.core.$strip>;
|
|
161
|
+
export type SubscribeEventsResult = z.infer<typeof subscribeEventsResultSchema>;
|
|
162
|
+
export declare const previewSessionParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
163
|
+
action: z.ZodLiteral<"start">;
|
|
164
|
+
tier: z.ZodEnum<{
|
|
165
|
+
webcodecs: "webcodecs";
|
|
166
|
+
webrtc: "webrtc";
|
|
167
|
+
}>;
|
|
168
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
169
|
+
action: z.ZodLiteral<"stop">;
|
|
170
|
+
session_id: z.ZodString;
|
|
171
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
172
|
+
action: z.ZodLiteral<"signal">;
|
|
173
|
+
session_id: z.ZodString;
|
|
174
|
+
sdp: z.ZodOptional<z.ZodString>;
|
|
175
|
+
ice: z.ZodOptional<z.ZodUnknown>;
|
|
176
|
+
}, z.core.$strip>], "action">;
|
|
177
|
+
export type PreviewSessionParams = z.infer<typeof previewSessionParamsSchema>;
|
|
178
|
+
export declare const previewSessionResultSchema: z.ZodObject<{
|
|
179
|
+
session_id: z.ZodString;
|
|
180
|
+
tier: z.ZodEnum<{
|
|
181
|
+
webcodecs: "webcodecs";
|
|
182
|
+
webrtc: "webrtc";
|
|
183
|
+
}>;
|
|
184
|
+
transport: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
185
|
+
kind: z.ZodLiteral<"uds-binary">;
|
|
186
|
+
socket: z.ZodLiteral<"/run/cerastream/preview.sock">;
|
|
187
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
188
|
+
kind: z.ZodLiteral<"webrtc">;
|
|
189
|
+
sdp: z.ZodOptional<z.ZodString>;
|
|
190
|
+
}, z.core.$strip>], "kind">;
|
|
191
|
+
}, z.core.$strip>;
|
|
192
|
+
export type PreviewSessionResult = z.infer<typeof previewSessionResultSchema>;
|
|
193
|
+
/** The eight v1 control methods (the literal JSON-RPC `method` strings). */
|
|
194
|
+
export declare const V1_METHODS: readonly ["start", "stop", "reload-config", "set-bitrate", "switch-input", "list-devices", "subscribe-events", "preview-session"];
|
|
195
|
+
export type V1Method = (typeof V1_METHODS)[number];
|
|
196
|
+
/**
|
|
197
|
+
* method → { params, result } Zod schema pair. `hello` is the handshake; the
|
|
198
|
+
* eight in {@link V1_METHODS} are the v1 control surface. Tests assert every
|
|
199
|
+
* ADR-0002 message is represented here.
|
|
200
|
+
*/
|
|
201
|
+
export declare const requestSchemas: {
|
|
202
|
+
readonly hello: {
|
|
203
|
+
readonly params: z.ZodObject<{
|
|
204
|
+
protocol: z.ZodLiteral<"cerastream-ipc/1">;
|
|
205
|
+
client: z.ZodString;
|
|
206
|
+
}, z.core.$strip>;
|
|
207
|
+
readonly result: z.ZodObject<{
|
|
208
|
+
protocol: z.ZodLiteral<"cerastream-ipc/1">;
|
|
209
|
+
schema_version: z.ZodString;
|
|
210
|
+
engine_version: z.ZodString;
|
|
211
|
+
}, z.core.$strip>;
|
|
212
|
+
};
|
|
213
|
+
readonly start: {
|
|
214
|
+
readonly params: z.ZodObject<{
|
|
215
|
+
pipeline: z.ZodString;
|
|
216
|
+
srt: z.ZodObject<{
|
|
217
|
+
host: z.ZodString;
|
|
218
|
+
port: z.ZodNumber;
|
|
219
|
+
streamid: z.ZodOptional<z.ZodString>;
|
|
220
|
+
latency_ms: z.ZodNumber;
|
|
221
|
+
reduced_packet_size: z.ZodOptional<z.ZodBoolean>;
|
|
222
|
+
}, z.core.$strip>;
|
|
223
|
+
bitrate: z.ZodObject<{
|
|
224
|
+
min_bitrate: z.ZodNumber;
|
|
225
|
+
max_bitrate: z.ZodNumber;
|
|
226
|
+
balancer: z.ZodDefault<z.ZodEnum<{
|
|
227
|
+
adaptive: "adaptive";
|
|
228
|
+
fixed: "fixed";
|
|
229
|
+
aimd: "aimd";
|
|
230
|
+
}>>;
|
|
231
|
+
}, z.core.$strip>;
|
|
232
|
+
input_id: z.ZodOptional<z.ZodString>;
|
|
233
|
+
}, z.core.$strip>;
|
|
234
|
+
readonly result: z.ZodObject<{
|
|
235
|
+
session_id: z.ZodString;
|
|
236
|
+
state: z.ZodEnum<{
|
|
237
|
+
idle: "idle";
|
|
238
|
+
starting: "starting";
|
|
239
|
+
streaming: "streaming";
|
|
240
|
+
stopping: "stopping";
|
|
241
|
+
}>;
|
|
242
|
+
}, z.core.$strip>;
|
|
243
|
+
};
|
|
244
|
+
readonly stop: {
|
|
245
|
+
readonly params: z.ZodOptional<z.ZodObject<{
|
|
246
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
247
|
+
}, z.core.$strip>>;
|
|
248
|
+
readonly result: z.ZodObject<{
|
|
249
|
+
state: z.ZodEnum<{
|
|
250
|
+
idle: "idle";
|
|
251
|
+
starting: "starting";
|
|
252
|
+
streaming: "streaming";
|
|
253
|
+
stopping: "stopping";
|
|
254
|
+
}>;
|
|
255
|
+
}, z.core.$strip>;
|
|
256
|
+
};
|
|
257
|
+
readonly "reload-config": {
|
|
258
|
+
readonly params: z.ZodObject<{
|
|
259
|
+
bitrate: z.ZodOptional<z.ZodObject<{
|
|
260
|
+
min_bitrate: z.ZodOptional<z.ZodNumber>;
|
|
261
|
+
max_bitrate: z.ZodOptional<z.ZodNumber>;
|
|
262
|
+
balancer: z.ZodOptional<z.ZodEnum<{
|
|
263
|
+
adaptive: "adaptive";
|
|
264
|
+
fixed: "fixed";
|
|
265
|
+
aimd: "aimd";
|
|
266
|
+
}>>;
|
|
267
|
+
}, z.core.$strip>>;
|
|
268
|
+
srt: z.ZodOptional<z.ZodObject<{
|
|
269
|
+
latency_ms: z.ZodOptional<z.ZodNumber>;
|
|
270
|
+
}, z.core.$strip>>;
|
|
271
|
+
}, z.core.$strip>;
|
|
272
|
+
readonly result: z.ZodObject<{
|
|
273
|
+
applied: z.ZodObject<{
|
|
274
|
+
bitrate: z.ZodOptional<z.ZodObject<{
|
|
275
|
+
min_bitrate: z.ZodOptional<z.ZodNumber>;
|
|
276
|
+
max_bitrate: z.ZodOptional<z.ZodNumber>;
|
|
277
|
+
balancer: z.ZodOptional<z.ZodEnum<{
|
|
278
|
+
adaptive: "adaptive";
|
|
279
|
+
fixed: "fixed";
|
|
280
|
+
aimd: "aimd";
|
|
281
|
+
}>>;
|
|
282
|
+
}, z.core.$strip>>;
|
|
283
|
+
srt: z.ZodOptional<z.ZodObject<{
|
|
284
|
+
latency_ms: z.ZodOptional<z.ZodNumber>;
|
|
285
|
+
}, z.core.$strip>>;
|
|
286
|
+
}, z.core.$strip>;
|
|
287
|
+
}, z.core.$strip>;
|
|
288
|
+
};
|
|
289
|
+
readonly "set-bitrate": {
|
|
290
|
+
readonly params: z.ZodObject<{
|
|
291
|
+
max_bitrate: z.ZodNumber;
|
|
292
|
+
}, z.core.$strip>;
|
|
293
|
+
readonly result: z.ZodObject<{
|
|
294
|
+
applied: z.ZodObject<{
|
|
295
|
+
max_bitrate: z.ZodNumber;
|
|
296
|
+
}, z.core.$strip>;
|
|
297
|
+
}, z.core.$strip>;
|
|
298
|
+
};
|
|
299
|
+
readonly "switch-input": {
|
|
300
|
+
readonly params: z.ZodObject<{
|
|
301
|
+
input_id: z.ZodString;
|
|
302
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
303
|
+
manual: "manual";
|
|
304
|
+
auto: "auto";
|
|
305
|
+
}>>;
|
|
306
|
+
}, z.core.$strip>;
|
|
307
|
+
readonly result: z.ZodObject<{
|
|
308
|
+
active_input: z.ZodString;
|
|
309
|
+
mode: z.ZodEnum<{
|
|
310
|
+
manual: "manual";
|
|
311
|
+
auto: "auto";
|
|
312
|
+
}>;
|
|
313
|
+
}, z.core.$strip>;
|
|
314
|
+
};
|
|
315
|
+
readonly "list-devices": {
|
|
316
|
+
readonly params: z.ZodOptional<z.ZodObject<{
|
|
317
|
+
media_class: z.ZodOptional<z.ZodEnum<{
|
|
318
|
+
video: "video";
|
|
319
|
+
audio: "audio";
|
|
320
|
+
}>>;
|
|
321
|
+
}, z.core.$strip>>;
|
|
322
|
+
readonly result: z.ZodObject<{
|
|
323
|
+
devices: z.ZodArray<z.ZodObject<{
|
|
324
|
+
input_id: z.ZodString;
|
|
325
|
+
device_path: z.ZodString;
|
|
326
|
+
display_name: z.ZodString;
|
|
327
|
+
media_class: z.ZodEnum<{
|
|
328
|
+
video: "video";
|
|
329
|
+
audio: "audio";
|
|
330
|
+
}>;
|
|
331
|
+
caps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
332
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
333
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
334
|
+
framerate: z.ZodOptional<z.ZodString>;
|
|
335
|
+
}, z.core.$strip>>>;
|
|
336
|
+
}, z.core.$strip>>;
|
|
337
|
+
}, z.core.$strip>;
|
|
338
|
+
};
|
|
339
|
+
readonly "subscribe-events": {
|
|
340
|
+
readonly params: z.ZodObject<{
|
|
341
|
+
topics: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
342
|
+
error: "error";
|
|
343
|
+
bitrate: "bitrate";
|
|
344
|
+
status: "status";
|
|
345
|
+
switch: "switch";
|
|
346
|
+
device: "device";
|
|
347
|
+
"srt-stats": "srt-stats";
|
|
348
|
+
preview: "preview";
|
|
349
|
+
}>>>;
|
|
350
|
+
}, z.core.$strip>;
|
|
351
|
+
readonly result: z.ZodObject<{
|
|
352
|
+
subscribed: z.ZodArray<z.ZodEnum<{
|
|
353
|
+
error: "error";
|
|
354
|
+
bitrate: "bitrate";
|
|
355
|
+
status: "status";
|
|
356
|
+
switch: "switch";
|
|
357
|
+
device: "device";
|
|
358
|
+
"srt-stats": "srt-stats";
|
|
359
|
+
preview: "preview";
|
|
360
|
+
}>>;
|
|
361
|
+
}, z.core.$strip>;
|
|
362
|
+
};
|
|
363
|
+
readonly "preview-session": {
|
|
364
|
+
readonly params: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
365
|
+
action: z.ZodLiteral<"start">;
|
|
366
|
+
tier: z.ZodEnum<{
|
|
367
|
+
webcodecs: "webcodecs";
|
|
368
|
+
webrtc: "webrtc";
|
|
369
|
+
}>;
|
|
370
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
371
|
+
action: z.ZodLiteral<"stop">;
|
|
372
|
+
session_id: z.ZodString;
|
|
373
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
374
|
+
action: z.ZodLiteral<"signal">;
|
|
375
|
+
session_id: z.ZodString;
|
|
376
|
+
sdp: z.ZodOptional<z.ZodString>;
|
|
377
|
+
ice: z.ZodOptional<z.ZodUnknown>;
|
|
378
|
+
}, z.core.$strip>], "action">;
|
|
379
|
+
readonly result: z.ZodObject<{
|
|
380
|
+
session_id: z.ZodString;
|
|
381
|
+
tier: z.ZodEnum<{
|
|
382
|
+
webcodecs: "webcodecs";
|
|
383
|
+
webrtc: "webrtc";
|
|
384
|
+
}>;
|
|
385
|
+
transport: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
386
|
+
kind: z.ZodLiteral<"uds-binary">;
|
|
387
|
+
socket: z.ZodLiteral<"/run/cerastream/preview.sock">;
|
|
388
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
389
|
+
kind: z.ZodLiteral<"webrtc">;
|
|
390
|
+
sdp: z.ZodOptional<z.ZodString>;
|
|
391
|
+
}, z.core.$strip>], "kind">;
|
|
392
|
+
}, z.core.$strip>;
|
|
393
|
+
};
|
|
394
|
+
};
|
package/dist/messages.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { helloParamsSchema, helloResultSchema, } from "./envelope.js";
|
|
3
|
+
import { balancerAlgorithmSchema, captureDeviceSchema, cerastreamConfigSchema, inputModeSchema, mediaClassSchema, previewTierSchema, streamStateSchema, } from "./types.js";
|
|
4
|
+
// The eight v1 control methods (schema.md "v1 messages"). Each is matched
|
|
5
|
+
// byte-for-byte to schema.md: the JSON shape on the wire is the contract.
|
|
6
|
+
// ---- 1. start ----
|
|
7
|
+
// `start` params ARE the unified engine config, so the wire shape and the
|
|
8
|
+
// persisted profile can never drift (see types.cerastreamConfigSchema).
|
|
9
|
+
export const startParamsSchema = cerastreamConfigSchema;
|
|
10
|
+
export const startResultSchema = z.object({
|
|
11
|
+
session_id: z.string(),
|
|
12
|
+
state: streamStateSchema, // "starting" | "streaming"
|
|
13
|
+
});
|
|
14
|
+
// ---- 2. stop ----
|
|
15
|
+
export const stopParamsSchema = z
|
|
16
|
+
.object({
|
|
17
|
+
reason: z.string().optional(),
|
|
18
|
+
})
|
|
19
|
+
.optional();
|
|
20
|
+
export const stopResultSchema = z.object({
|
|
21
|
+
state: streamStateSchema, // "idle"
|
|
22
|
+
});
|
|
23
|
+
// ---- 3. reload-config (replaces SIGHUP) ----
|
|
24
|
+
export const reloadConfigParamsSchema = z.object({
|
|
25
|
+
bitrate: z
|
|
26
|
+
.object({
|
|
27
|
+
min_bitrate: z.number().int().min(1).optional(),
|
|
28
|
+
max_bitrate: z.number().int().min(1).optional(),
|
|
29
|
+
balancer: balancerAlgorithmSchema.optional(),
|
|
30
|
+
})
|
|
31
|
+
.optional(),
|
|
32
|
+
srt: z
|
|
33
|
+
.object({
|
|
34
|
+
latency_ms: z.number().int().min(100).max(10_000).optional(),
|
|
35
|
+
})
|
|
36
|
+
.optional(),
|
|
37
|
+
});
|
|
38
|
+
export const reloadConfigResultSchema = z.object({
|
|
39
|
+
applied: reloadConfigParamsSchema, // post-clamp values actually applied
|
|
40
|
+
});
|
|
41
|
+
// ---- 4. set-bitrate ----
|
|
42
|
+
export const setBitrateParamsSchema = z.object({
|
|
43
|
+
max_bitrate: z.number().int().min(1), // kbps
|
|
44
|
+
});
|
|
45
|
+
export const setBitrateResultSchema = z.object({
|
|
46
|
+
applied: z.object({ max_bitrate: z.number().int() }),
|
|
47
|
+
});
|
|
48
|
+
// ---- 5. switch-input ----
|
|
49
|
+
export const switchInputParamsSchema = z.object({
|
|
50
|
+
input_id: z.string(), // device/input identifier from list-devices
|
|
51
|
+
mode: inputModeSchema.default("manual"),
|
|
52
|
+
});
|
|
53
|
+
export const switchInputResultSchema = z.object({
|
|
54
|
+
active_input: z.string(),
|
|
55
|
+
mode: inputModeSchema,
|
|
56
|
+
});
|
|
57
|
+
// ---- 6. list-devices ----
|
|
58
|
+
export const listDevicesParamsSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
media_class: mediaClassSchema.optional(),
|
|
61
|
+
})
|
|
62
|
+
.optional();
|
|
63
|
+
export const listDevicesResultSchema = z.object({
|
|
64
|
+
devices: z.array(captureDeviceSchema),
|
|
65
|
+
});
|
|
66
|
+
// ---- 7. subscribe-events ----
|
|
67
|
+
export const eventTopicSchema = z.enum([
|
|
68
|
+
"status",
|
|
69
|
+
"switch",
|
|
70
|
+
"device",
|
|
71
|
+
"bitrate",
|
|
72
|
+
"srt-stats",
|
|
73
|
+
"error",
|
|
74
|
+
"preview",
|
|
75
|
+
]);
|
|
76
|
+
export const subscribeEventsParamsSchema = z.object({
|
|
77
|
+
topics: z.array(eventTopicSchema).optional(), // default: all topics
|
|
78
|
+
});
|
|
79
|
+
export const subscribeEventsResultSchema = z.object({
|
|
80
|
+
subscribed: z.array(eventTopicSchema),
|
|
81
|
+
});
|
|
82
|
+
// ---- 8. preview-session ----
|
|
83
|
+
export const previewSessionParamsSchema = z.discriminatedUnion("action", [
|
|
84
|
+
z.object({
|
|
85
|
+
action: z.literal("start"),
|
|
86
|
+
tier: previewTierSchema,
|
|
87
|
+
}),
|
|
88
|
+
z.object({ action: z.literal("stop"), session_id: z.string() }),
|
|
89
|
+
z.object({
|
|
90
|
+
action: z.literal("signal"), // webrtc only
|
|
91
|
+
session_id: z.string(),
|
|
92
|
+
sdp: z.string().optional(),
|
|
93
|
+
ice: z.unknown().optional(),
|
|
94
|
+
}),
|
|
95
|
+
]);
|
|
96
|
+
export const previewSessionResultSchema = z.object({
|
|
97
|
+
session_id: z.string(),
|
|
98
|
+
tier: previewTierSchema,
|
|
99
|
+
transport: z.discriminatedUnion("kind", [
|
|
100
|
+
z.object({
|
|
101
|
+
kind: z.literal("uds-binary"),
|
|
102
|
+
socket: z.literal("/run/cerastream/preview.sock"),
|
|
103
|
+
}),
|
|
104
|
+
z.object({ kind: z.literal("webrtc"), sdp: z.string().optional() }),
|
|
105
|
+
]),
|
|
106
|
+
});
|
|
107
|
+
// ---- method registry (count-assertion source of truth) ----
|
|
108
|
+
/** The eight v1 control methods (the literal JSON-RPC `method` strings). */
|
|
109
|
+
export const V1_METHODS = [
|
|
110
|
+
"start",
|
|
111
|
+
"stop",
|
|
112
|
+
"reload-config",
|
|
113
|
+
"set-bitrate",
|
|
114
|
+
"switch-input",
|
|
115
|
+
"list-devices",
|
|
116
|
+
"subscribe-events",
|
|
117
|
+
"preview-session",
|
|
118
|
+
];
|
|
119
|
+
/**
|
|
120
|
+
* method → { params, result } Zod schema pair. `hello` is the handshake; the
|
|
121
|
+
* eight in {@link V1_METHODS} are the v1 control surface. Tests assert every
|
|
122
|
+
* ADR-0002 message is represented here.
|
|
123
|
+
*/
|
|
124
|
+
export const requestSchemas = {
|
|
125
|
+
hello: { params: helloParamsSchema, result: helloResultSchema },
|
|
126
|
+
start: { params: startParamsSchema, result: startResultSchema },
|
|
127
|
+
stop: { params: stopParamsSchema, result: stopResultSchema },
|
|
128
|
+
"reload-config": {
|
|
129
|
+
params: reloadConfigParamsSchema,
|
|
130
|
+
result: reloadConfigResultSchema,
|
|
131
|
+
},
|
|
132
|
+
"set-bitrate": {
|
|
133
|
+
params: setBitrateParamsSchema,
|
|
134
|
+
result: setBitrateResultSchema,
|
|
135
|
+
},
|
|
136
|
+
"switch-input": {
|
|
137
|
+
params: switchInputParamsSchema,
|
|
138
|
+
result: switchInputResultSchema,
|
|
139
|
+
},
|
|
140
|
+
"list-devices": {
|
|
141
|
+
params: listDevicesParamsSchema,
|
|
142
|
+
result: listDevicesResultSchema,
|
|
143
|
+
},
|
|
144
|
+
"subscribe-events": {
|
|
145
|
+
params: subscribeEventsParamsSchema,
|
|
146
|
+
result: subscribeEventsResultSchema,
|
|
147
|
+
},
|
|
148
|
+
"preview-session": {
|
|
149
|
+
params: previewSessionParamsSchema,
|
|
150
|
+
result: previewSessionResultSchema,
|
|
151
|
+
},
|
|
152
|
+
};
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CONTROL_SOCKET_NAME, DEFAULT_IPC_DIR, PREVIEW_SOCKET_NAME } from "./constants.js";
|
|
2
|
+
/** Resolve the IPC runtime dir: explicit override → {@link IPC_DIR_ENV} → default. */
|
|
3
|
+
export declare function resolveIpcDir(override?: string): string;
|
|
4
|
+
/** Resolve the control-plane socket path within the (possibly overridden) IPC dir. */
|
|
5
|
+
export declare function controlSocketPath(dir?: string): string;
|
|
6
|
+
/** Resolve the binary preview socket path within the (possibly overridden) IPC dir. */
|
|
7
|
+
export declare function previewSocketPath(dir?: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the cerastream engine executable path. Resolution order: an explicit
|
|
10
|
+
* file path → a directory containing the binary → `which cerastream` →
|
|
11
|
+
* `/usr/bin/cerastream` → the bare name (let PATH decide).
|
|
12
|
+
*/
|
|
13
|
+
export declare function getCerastreamExec(execPath?: string): string;
|
|
14
|
+
export { DEFAULT_IPC_DIR, CONTROL_SOCKET_NAME, PREVIEW_SOCKET_NAME };
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync, statSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { CERASTREAM_BIN, CONTROL_SOCKET_NAME, DEFAULT_IPC_DIR, IPC_DIR_ENV, PREVIEW_SOCKET_NAME, } from "./constants.js";
|
|
5
|
+
// Socket-path + engine-exec helpers (ADR-0002 §3). They resolve the runtime IPC
|
|
6
|
+
// dir from the CERASTREAM_IPC_DIR override (then the explicit arg), defaulting to
|
|
7
|
+
// /run/cerastream. cerastream is a systemd-owned service (ADR-0005) — CeraUI
|
|
8
|
+
// connects to these sockets, it never spawns the engine, so getCerastreamExec
|
|
9
|
+
// exists only for parity/tooling.
|
|
10
|
+
/** Resolve the IPC runtime dir: explicit override → {@link IPC_DIR_ENV} → default. */
|
|
11
|
+
export function resolveIpcDir(override) {
|
|
12
|
+
if (override)
|
|
13
|
+
return override;
|
|
14
|
+
const fromEnv = process.env[IPC_DIR_ENV];
|
|
15
|
+
return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_IPC_DIR;
|
|
16
|
+
}
|
|
17
|
+
/** Resolve the control-plane socket path within the (possibly overridden) IPC dir. */
|
|
18
|
+
export function controlSocketPath(dir) {
|
|
19
|
+
return join(resolveIpcDir(dir), CONTROL_SOCKET_NAME);
|
|
20
|
+
}
|
|
21
|
+
/** Resolve the binary preview socket path within the (possibly overridden) IPC dir. */
|
|
22
|
+
export function previewSocketPath(dir) {
|
|
23
|
+
return join(resolveIpcDir(dir), PREVIEW_SOCKET_NAME);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the cerastream engine executable path. Resolution order: an explicit
|
|
27
|
+
* file path → a directory containing the binary → `which cerastream` →
|
|
28
|
+
* `/usr/bin/cerastream` → the bare name (let PATH decide).
|
|
29
|
+
*/
|
|
30
|
+
export function getCerastreamExec(execPath) {
|
|
31
|
+
if (execPath) {
|
|
32
|
+
if (isFile(execPath))
|
|
33
|
+
return execPath;
|
|
34
|
+
const inDir = join(execPath, CERASTREAM_BIN);
|
|
35
|
+
if (isFile(inDir))
|
|
36
|
+
return inDir;
|
|
37
|
+
return execPath.endsWith(CERASTREAM_BIN)
|
|
38
|
+
? execPath
|
|
39
|
+
: join(execPath, CERASTREAM_BIN);
|
|
40
|
+
}
|
|
41
|
+
const onPath = findInPath(CERASTREAM_BIN);
|
|
42
|
+
if (onPath)
|
|
43
|
+
return onPath;
|
|
44
|
+
const systemPath = `/usr/bin/${CERASTREAM_BIN}`;
|
|
45
|
+
if (existsSync(systemPath))
|
|
46
|
+
return systemPath;
|
|
47
|
+
return CERASTREAM_BIN;
|
|
48
|
+
}
|
|
49
|
+
function isFile(p) {
|
|
50
|
+
try {
|
|
51
|
+
return statSync(p).isFile();
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function findInPath(name) {
|
|
58
|
+
try {
|
|
59
|
+
const out = execSync(`command -v ${name}`, {
|
|
60
|
+
encoding: "utf-8",
|
|
61
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
62
|
+
}).trim();
|
|
63
|
+
const first = out.split("\n")[0]?.trim();
|
|
64
|
+
if (first && existsSync(first))
|
|
65
|
+
return first;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// not found on PATH
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
export { DEFAULT_IPC_DIR, CONTROL_SOCKET_NAME, PREVIEW_SOCKET_NAME };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Lifecycle + data callbacks the client installs on a {@link LineSocket}. */
|
|
2
|
+
export interface LineSocketHandlers {
|
|
3
|
+
/** One decoded NDJSON line (newline stripped). */
|
|
4
|
+
onLine(line: string): void;
|
|
5
|
+
/** The socket closed. `err` is set for an error/framing close, absent for EOF. */
|
|
6
|
+
onClose(err?: Error): void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A single Unix-socket connection that frames bytes into NDJSON lines. Construct,
|
|
10
|
+
* `open()` (rejects if the socket can't be reached), `send()` lines, `close()`
|
|
11
|
+
* when done. Not reusable across reconnects — the client makes a new one.
|
|
12
|
+
*/
|
|
13
|
+
export declare class LineSocket {
|
|
14
|
+
private readonly socketPath;
|
|
15
|
+
private socket;
|
|
16
|
+
private buffer;
|
|
17
|
+
private bufferedBytes;
|
|
18
|
+
private handlers;
|
|
19
|
+
private closed;
|
|
20
|
+
constructor(socketPath: string);
|
|
21
|
+
/** Connect to the socket and start framing. Rejects on a connect failure. */
|
|
22
|
+
open(handlers: LineSocketHandlers): Promise<void>;
|
|
23
|
+
/** Write one NDJSON line (the trailing newline is added here). */
|
|
24
|
+
send(line: string): void;
|
|
25
|
+
/** Close the connection. Idempotent; does not fire {@link LineSocketHandlers.onClose}. */
|
|
26
|
+
close(): void;
|
|
27
|
+
private onData;
|
|
28
|
+
private fail;
|
|
29
|
+
private fireClose;
|
|
30
|
+
}
|