@ceralive/cerastream 2026.7.3 → 2026.7.4
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 +3 -1
- package/dist/client.d.ts +15 -1
- package/dist/client.js +4 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/events.d.ts +68 -3
- package/dist/events.js +22 -3
- package/dist/messages.d.ts +49 -0
- package/dist/messages.js +42 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.js +14 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,12 +6,14 @@ engine's JSON-RPC 2.0 / NDJSON control plane over a Unix domain socket.
|
|
|
6
6
|
|
|
7
7
|
- JSON-RPC 2.0 envelope + `hello` handshake schemas
|
|
8
8
|
- The eight v1 control methods (Zod params + result schemas + inferred types)
|
|
9
|
-
- The
|
|
9
|
+
- The nine server-push event payloads (discriminated union)
|
|
10
10
|
- Two-tier error codes (RPC + runtime)
|
|
11
11
|
- A unified engine config schema (= `start` params)
|
|
12
12
|
- A `CerastreamClient` interface + `connect()` factory (UDS transport)
|
|
13
13
|
- Additive `client.getCapabilities()` discovery for platform, source, encoder, and
|
|
14
14
|
local preview availability
|
|
15
|
+
- Additive `client.changeConfig()` — reconfigure the live session (resolution,
|
|
16
|
+
framerate, codec, pipeline, source) as one transaction with typed rollback
|
|
15
17
|
|
|
16
18
|
The Zod schemas, types, and constants are the frozen wire contract; `connect()`
|
|
17
19
|
drives that contract over an NDJSON/UDS transport with no native dependencies.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type HelloResult } from "./envelope.js";
|
|
2
2
|
import { type EventParams } from "./events.js";
|
|
3
|
-
import { type GetCapabilitiesResult, type ListDevicesParams, type ListDevicesResult, type PreviewSessionParams, type PreviewSessionResult, type ReloadConfigParams, type ReloadConfigResult, type SetBitrateParams, type SetBitrateResult, type StartParams, type StartResult, type StopParams, type StopResult, type SubscribeEventsParams, type SubscribeEventsResult, type SwitchInputParams, type SwitchInputResult } from "./messages.js";
|
|
3
|
+
import { type ChangeConfigParams, type ChangeConfigResult, type GetCapabilitiesResult, type ListDevicesParams, type ListDevicesResult, type PreviewSessionParams, type PreviewSessionResult, type ReloadConfigParams, type ReloadConfigResult, type SetBitrateParams, type SetBitrateResult, type StartParams, type StartResult, type StopParams, type StopResult, type SubscribeEventsParams, type SubscribeEventsResult, type SwitchInputParams, type SwitchInputResult } from "./messages.js";
|
|
4
4
|
/** Options for {@link connect}. All optional — `connect({})` is valid. */
|
|
5
5
|
export interface ConnectOptions {
|
|
6
6
|
/** Control socket path override. Defaults to the resolved /run/cerastream/control.sock. */
|
|
@@ -82,6 +82,20 @@ export interface CerastreamClient {
|
|
|
82
82
|
* availability. This request intentionally sits outside the frozen v1 map.
|
|
83
83
|
*/
|
|
84
84
|
getCapabilities(): Promise<GetCapabilitiesResult>;
|
|
85
|
+
/**
|
|
86
|
+
* Reconfigure the LIVE session as one transaction (resolution, framerate,
|
|
87
|
+
* codec, pipeline, source). Also sits outside the frozen v1 map.
|
|
88
|
+
*
|
|
89
|
+
* Resolves for every phase the transaction reached — including
|
|
90
|
+
* `rollback_failed`, an honest terminal outcome. Callers must branch on
|
|
91
|
+
* `result.phase`, not on whether the promise settled. The engine's declared
|
|
92
|
+
* worst-case transaction bound is 65 000 ms, so size any caller-side deadline
|
|
93
|
+
* from that, not from the default per-request timeout.
|
|
94
|
+
* @param params A delta of the live config; absent field ⇒ keep live value.
|
|
95
|
+
* @throws {CerastreamRpcError} ONLY when the transaction never started (not
|
|
96
|
+
* streaming, a concurrent change, or an empty/invalid delta).
|
|
97
|
+
*/
|
|
98
|
+
changeConfig(params: ChangeConfigParams): Promise<ChangeConfigResult>;
|
|
85
99
|
/**
|
|
86
100
|
* Subscribe to the live event stream; `handler` fires for each pushed event.
|
|
87
101
|
* @param params The topics to subscribe to (absent ⇒ all topics).
|
package/dist/client.js
CHANGED
|
@@ -4,7 +4,7 @@ import { existsSync } from "node:fs";
|
|
|
4
4
|
import { CerastreamConnectionError, CerastreamRpcError, CerastreamTimeoutError, } from "./errors.js";
|
|
5
5
|
import { eventParamsSchema } from "./events.js";
|
|
6
6
|
import { controlSocketPath } from "./paths.js";
|
|
7
|
-
import { getCapabilitiesResultSchema, requestSchemas, } from "./messages.js";
|
|
7
|
+
import { changeConfigParamsSchema, changeConfigResultSchema, getCapabilitiesResultSchema, requestSchemas, } from "./messages.js";
|
|
8
8
|
import { LineSocket } from "./transport.js";
|
|
9
9
|
const DEFAULTS = {
|
|
10
10
|
requestTimeoutMs: 10_000,
|
|
@@ -82,6 +82,9 @@ class ClientImpl {
|
|
|
82
82
|
async getCapabilities() {
|
|
83
83
|
return getCapabilitiesResultSchema.parse(await this.rawRequest("get-capabilities", undefined));
|
|
84
84
|
}
|
|
85
|
+
async changeConfig(params) {
|
|
86
|
+
return changeConfigResultSchema.parse(await this.rawRequest("change-config", changeConfigParamsSchema.parse(params)));
|
|
87
|
+
}
|
|
85
88
|
previewSession(params) {
|
|
86
89
|
return this.call("preview-session", params);
|
|
87
90
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const PROTOCOL_VERSION: "cerastream-ipc/1";
|
|
|
8
8
|
* additive-only within protocol major `cerastream-ipc/1` (ADR-0002 §4); this value
|
|
9
9
|
* only moves when the wire schema itself does, in lockstep across both languages.
|
|
10
10
|
*/
|
|
11
|
-
export declare const SCHEMA_VERSION: "0.
|
|
11
|
+
export declare const SCHEMA_VERSION: "0.10.0";
|
|
12
12
|
/** Runtime dir holding both control + preview sockets. systemd `RuntimeDirectory=cerastream`. */
|
|
13
13
|
export declare const DEFAULT_IPC_DIR: "/run/cerastream";
|
|
14
14
|
/** Env override for the IPC dir (tests/dev). Defaults to {@link DEFAULT_IPC_DIR}. */
|
package/dist/constants.js
CHANGED
|
@@ -11,7 +11,7 @@ export const PROTOCOL_VERSION = "cerastream-ipc/1";
|
|
|
11
11
|
* additive-only within protocol major `cerastream-ipc/1` (ADR-0002 §4); this value
|
|
12
12
|
* only moves when the wire schema itself does, in lockstep across both languages.
|
|
13
13
|
*/
|
|
14
|
-
export const SCHEMA_VERSION = "0.
|
|
14
|
+
export const SCHEMA_VERSION = "0.10.0";
|
|
15
15
|
/** Runtime dir holding both control + preview sockets. systemd `RuntimeDirectory=cerastream`. */
|
|
16
16
|
export const DEFAULT_IPC_DIR = "/run/cerastream";
|
|
17
17
|
/** Env override for the IPC dir (tests/dev). Defaults to {@link DEFAULT_IPC_DIR}. */
|
package/dist/events.d.ts
CHANGED
|
@@ -124,6 +124,8 @@ export declare const deviceEventSchema: z.ZodObject<{
|
|
|
124
124
|
onboard: "onboard";
|
|
125
125
|
}>>;
|
|
126
126
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
127
|
+
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
128
|
+
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
127
129
|
}, z.core.$strip>;
|
|
128
130
|
}, z.core.$strip>;
|
|
129
131
|
/** Payload of a {@link deviceEventSchema} event. */
|
|
@@ -214,6 +216,28 @@ export declare const audioLevelEventSchema: z.ZodObject<{
|
|
|
214
216
|
}, z.core.$strip>;
|
|
215
217
|
/** Payload of a {@link audioLevelEventSchema} event. */
|
|
216
218
|
export type AudioLevelEvent = z.infer<typeof audioLevelEventSchema>;
|
|
219
|
+
/**
|
|
220
|
+
* `config-change` event — one phase of a `change-config` transaction (0.10.0,
|
|
221
|
+
* additive Todo 9). Exactly one `applying` at entry, then exactly ONE terminal
|
|
222
|
+
* phase for the same `attempt_id` (which the RPC result also echoes, so a caller
|
|
223
|
+
* that missed an event can still correlate). A terminal phase is published only
|
|
224
|
+
* after the outcome gate resolved, so `applied` means "PLAYING **and** frames
|
|
225
|
+
* actually advancing", never merely "PLAYING".
|
|
226
|
+
*/
|
|
227
|
+
export declare const configChangeEventSchema: z.ZodObject<{
|
|
228
|
+
type: z.ZodLiteral<"config-change">;
|
|
229
|
+
seq: z.ZodNumber;
|
|
230
|
+
attempt_id: z.ZodString;
|
|
231
|
+
phase: z.ZodEnum<{
|
|
232
|
+
applying: "applying";
|
|
233
|
+
applied: "applied";
|
|
234
|
+
reverted: "reverted";
|
|
235
|
+
rollback_failed: "rollback_failed";
|
|
236
|
+
}>;
|
|
237
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
238
|
+
}, z.core.$strip>;
|
|
239
|
+
/** Payload of a {@link configChangeEventSchema} event. */
|
|
240
|
+
export type ConfigChangeEvent = z.infer<typeof configChangeEventSchema>;
|
|
217
241
|
/** Discriminated union of every v1 event payload (the inner `params`). */
|
|
218
242
|
export declare const eventParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
219
243
|
type: z.ZodLiteral<"status">;
|
|
@@ -297,6 +321,8 @@ export declare const eventParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
297
321
|
onboard: "onboard";
|
|
298
322
|
}>>;
|
|
299
323
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
324
|
+
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
325
|
+
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
300
326
|
}, z.core.$strip>;
|
|
301
327
|
}, z.core.$strip>, z.ZodObject<{
|
|
302
328
|
type: z.ZodLiteral<"bitrate">;
|
|
@@ -352,6 +378,17 @@ export declare const eventParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
352
378
|
mode_none: "mode_none";
|
|
353
379
|
handoff: "handoff";
|
|
354
380
|
}>>;
|
|
381
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
382
|
+
type: z.ZodLiteral<"config-change">;
|
|
383
|
+
seq: z.ZodNumber;
|
|
384
|
+
attempt_id: z.ZodString;
|
|
385
|
+
phase: z.ZodEnum<{
|
|
386
|
+
applying: "applying";
|
|
387
|
+
applied: "applied";
|
|
388
|
+
reverted: "reverted";
|
|
389
|
+
rollback_failed: "rollback_failed";
|
|
390
|
+
}>;
|
|
391
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
355
392
|
}, z.core.$strip>], "type">;
|
|
356
393
|
export type EventParams = z.infer<typeof eventParamsSchema>;
|
|
357
394
|
/** Full event envelope: { jsonrpc, method:"event", params } with typed params. */
|
|
@@ -440,6 +477,8 @@ export declare const cerastreamEventSchema: z.ZodObject<{
|
|
|
440
477
|
onboard: "onboard";
|
|
441
478
|
}>>;
|
|
442
479
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
480
|
+
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
481
|
+
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
443
482
|
}, z.core.$strip>;
|
|
444
483
|
}, z.core.$strip>, z.ZodObject<{
|
|
445
484
|
type: z.ZodLiteral<"bitrate">;
|
|
@@ -495,12 +534,24 @@ export declare const cerastreamEventSchema: z.ZodObject<{
|
|
|
495
534
|
mode_none: "mode_none";
|
|
496
535
|
handoff: "handoff";
|
|
497
536
|
}>>;
|
|
537
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
538
|
+
type: z.ZodLiteral<"config-change">;
|
|
539
|
+
seq: z.ZodNumber;
|
|
540
|
+
attempt_id: z.ZodString;
|
|
541
|
+
phase: z.ZodEnum<{
|
|
542
|
+
applying: "applying";
|
|
543
|
+
applied: "applied";
|
|
544
|
+
reverted: "reverted";
|
|
545
|
+
rollback_failed: "rollback_failed";
|
|
546
|
+
}>;
|
|
547
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
498
548
|
}, z.core.$strip>], "type">;
|
|
499
549
|
}, z.core.$strip>;
|
|
500
550
|
export type CerastreamEvent = z.infer<typeof cerastreamEventSchema>;
|
|
501
|
-
/** The
|
|
502
|
-
* `audio-level`
|
|
503
|
-
|
|
551
|
+
/** The nine event topics (schema.md "Events" table) — count-assertion source.
|
|
552
|
+
* `audio-level` (Todo 21) and `config-change` (Todo 9) are additive and appended
|
|
553
|
+
* last, preserving the order of every prior topic. */
|
|
554
|
+
export declare const EVENT_TOPICS: readonly ["status", "switch", "device", "bitrate", "srt-stats", "error", "preview", "audio-level", "config-change"];
|
|
504
555
|
export type EventTopicName = (typeof EVENT_TOPICS)[number];
|
|
505
556
|
/** topic → payload Zod schema. Tests assert every topic is represented here. */
|
|
506
557
|
export declare const eventSchemas: {
|
|
@@ -588,6 +639,8 @@ export declare const eventSchemas: {
|
|
|
588
639
|
onboard: "onboard";
|
|
589
640
|
}>>;
|
|
590
641
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
642
|
+
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
643
|
+
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
591
644
|
}, z.core.$strip>;
|
|
592
645
|
}, z.core.$strip>;
|
|
593
646
|
readonly bitrate: z.ZodObject<{
|
|
@@ -649,4 +702,16 @@ export declare const eventSchemas: {
|
|
|
649
702
|
handoff: "handoff";
|
|
650
703
|
}>>;
|
|
651
704
|
}, z.core.$strip>;
|
|
705
|
+
readonly "config-change": z.ZodObject<{
|
|
706
|
+
type: z.ZodLiteral<"config-change">;
|
|
707
|
+
seq: z.ZodNumber;
|
|
708
|
+
attempt_id: z.ZodString;
|
|
709
|
+
phase: z.ZodEnum<{
|
|
710
|
+
applying: "applying";
|
|
711
|
+
applied: "applied";
|
|
712
|
+
reverted: "reverted";
|
|
713
|
+
rollback_failed: "rollback_failed";
|
|
714
|
+
}>;
|
|
715
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
716
|
+
}, z.core.$strip>;
|
|
652
717
|
};
|
package/dist/events.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { processErrorCodeSchema, processErrorSourceSchema, } from "./errors.js";
|
|
3
|
-
import { captureDeviceSchema, inputModeSchema, mediaClassSchema, streamStateSchema, } from "./types.js";
|
|
3
|
+
import { captureDeviceSchema, configChangePhaseSchema, inputModeSchema, mediaClassSchema, streamStateSchema, } from "./types.js";
|
|
4
4
|
// Server → client `event` notifications, delivered after `subscribe-events`
|
|
5
5
|
// (schema.md "Events"). Each event is the inner `params` of an rpcEventSchema:
|
|
6
6
|
// { type, seq, … }. `type` discriminates; `seq` is a per-type monotonic counter.
|
|
@@ -127,6 +127,21 @@ export const audioLevelEventSchema = z.object({
|
|
|
127
127
|
unavailable: z.literal(true).optional(),
|
|
128
128
|
reason: z.enum(["device_busy", "no_device", "mode_none", "handoff"]).optional(),
|
|
129
129
|
});
|
|
130
|
+
/**
|
|
131
|
+
* `config-change` event — one phase of a `change-config` transaction (0.10.0,
|
|
132
|
+
* additive Todo 9). Exactly one `applying` at entry, then exactly ONE terminal
|
|
133
|
+
* phase for the same `attempt_id` (which the RPC result also echoes, so a caller
|
|
134
|
+
* that missed an event can still correlate). A terminal phase is published only
|
|
135
|
+
* after the outcome gate resolved, so `applied` means "PLAYING **and** frames
|
|
136
|
+
* actually advancing", never merely "PLAYING".
|
|
137
|
+
*/
|
|
138
|
+
export const configChangeEventSchema = z.object({
|
|
139
|
+
type: z.literal("config-change"),
|
|
140
|
+
seq,
|
|
141
|
+
attempt_id: z.string(),
|
|
142
|
+
phase: configChangePhaseSchema,
|
|
143
|
+
reason: z.string().optional(), // absent on applying/applied; "teardown_timeout" marks the supervisor escalation
|
|
144
|
+
});
|
|
130
145
|
/** Discriminated union of every v1 event payload (the inner `params`). */
|
|
131
146
|
export const eventParamsSchema = z.discriminatedUnion("type", [
|
|
132
147
|
statusEventSchema,
|
|
@@ -137,6 +152,7 @@ export const eventParamsSchema = z.discriminatedUnion("type", [
|
|
|
137
152
|
runtimeErrorEventSchema,
|
|
138
153
|
previewEventSchema,
|
|
139
154
|
audioLevelEventSchema,
|
|
155
|
+
configChangeEventSchema,
|
|
140
156
|
]);
|
|
141
157
|
/** Full event envelope: { jsonrpc, method:"event", params } with typed params. */
|
|
142
158
|
export const cerastreamEventSchema = z.object({
|
|
@@ -144,8 +160,9 @@ export const cerastreamEventSchema = z.object({
|
|
|
144
160
|
method: z.literal("event"),
|
|
145
161
|
params: eventParamsSchema,
|
|
146
162
|
});
|
|
147
|
-
/** The
|
|
148
|
-
* `audio-level`
|
|
163
|
+
/** The nine event topics (schema.md "Events" table) — count-assertion source.
|
|
164
|
+
* `audio-level` (Todo 21) and `config-change` (Todo 9) are additive and appended
|
|
165
|
+
* last, preserving the order of every prior topic. */
|
|
149
166
|
export const EVENT_TOPICS = [
|
|
150
167
|
"status",
|
|
151
168
|
"switch",
|
|
@@ -155,6 +172,7 @@ export const EVENT_TOPICS = [
|
|
|
155
172
|
"error",
|
|
156
173
|
"preview",
|
|
157
174
|
"audio-level",
|
|
175
|
+
"config-change",
|
|
158
176
|
];
|
|
159
177
|
/** topic → payload Zod schema. Tests assert every topic is represented here. */
|
|
160
178
|
export const eventSchemas = {
|
|
@@ -166,4 +184,5 @@ export const eventSchemas = {
|
|
|
166
184
|
error: runtimeErrorEventSchema,
|
|
167
185
|
preview: previewEventSchema,
|
|
168
186
|
"audio-level": audioLevelEventSchema,
|
|
187
|
+
"config-change": configChangeEventSchema,
|
|
169
188
|
};
|
package/dist/messages.d.ts
CHANGED
|
@@ -83,6 +83,7 @@ export declare const reloadConfigParamsSchema: z.ZodObject<{
|
|
|
83
83
|
audio: z.ZodOptional<z.ZodObject<{
|
|
84
84
|
delay_ms: z.ZodOptional<z.ZodNumber>;
|
|
85
85
|
delay_ms_signed: z.ZodOptional<z.ZodNumber>;
|
|
86
|
+
meter_device: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
86
87
|
}, z.core.$strip>>;
|
|
87
88
|
}, z.core.$strip>;
|
|
88
89
|
export type ReloadConfigParams = z.infer<typeof reloadConfigParamsSchema>;
|
|
@@ -103,6 +104,7 @@ export declare const reloadConfigResultSchema: z.ZodObject<{
|
|
|
103
104
|
audio: z.ZodOptional<z.ZodObject<{
|
|
104
105
|
delay_ms: z.ZodOptional<z.ZodNumber>;
|
|
105
106
|
delay_ms_signed: z.ZodOptional<z.ZodNumber>;
|
|
107
|
+
meter_device: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
106
108
|
}, z.core.$strip>>;
|
|
107
109
|
}, z.core.$strip>;
|
|
108
110
|
bitrate_control: z.ZodOptional<z.ZodEnum<{
|
|
@@ -200,6 +202,8 @@ export declare const listDevicesResultSchema: z.ZodObject<{
|
|
|
200
202
|
onboard: "onboard";
|
|
201
203
|
}>>;
|
|
202
204
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
205
|
+
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
206
|
+
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
203
207
|
}, z.core.$strip>>;
|
|
204
208
|
}, z.core.$strip>;
|
|
205
209
|
export type ListDevicesResult = z.infer<typeof listDevicesResultSchema>;
|
|
@@ -212,6 +216,7 @@ export declare const eventTopicSchema: z.ZodEnum<{
|
|
|
212
216
|
"srt-stats": "srt-stats";
|
|
213
217
|
preview: "preview";
|
|
214
218
|
"audio-level": "audio-level";
|
|
219
|
+
"config-change": "config-change";
|
|
215
220
|
}>;
|
|
216
221
|
export type EventTopic = z.infer<typeof eventTopicSchema>;
|
|
217
222
|
export declare const subscribeEventsParamsSchema: z.ZodObject<{
|
|
@@ -224,6 +229,7 @@ export declare const subscribeEventsParamsSchema: z.ZodObject<{
|
|
|
224
229
|
"srt-stats": "srt-stats";
|
|
225
230
|
preview: "preview";
|
|
226
231
|
"audio-level": "audio-level";
|
|
232
|
+
"config-change": "config-change";
|
|
227
233
|
}>>>;
|
|
228
234
|
}, z.core.$strip>;
|
|
229
235
|
export type SubscribeEventsParams = z.infer<typeof subscribeEventsParamsSchema>;
|
|
@@ -237,6 +243,7 @@ export declare const subscribeEventsResultSchema: z.ZodObject<{
|
|
|
237
243
|
"srt-stats": "srt-stats";
|
|
238
244
|
preview: "preview";
|
|
239
245
|
"audio-level": "audio-level";
|
|
246
|
+
"config-change": "config-change";
|
|
240
247
|
}>>;
|
|
241
248
|
}, z.core.$strip>;
|
|
242
249
|
export type SubscribeEventsResult = z.infer<typeof subscribeEventsResultSchema>;
|
|
@@ -373,6 +380,42 @@ export declare const getCapabilitiesResultSchema: z.ZodObject<{
|
|
|
373
380
|
features: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
374
381
|
}, z.core.$strip>;
|
|
375
382
|
export type GetCapabilitiesResult = z.infer<typeof getCapabilitiesResultSchema>;
|
|
383
|
+
export declare const changeConfigParamsSchema: z.ZodObject<{
|
|
384
|
+
pipeline: z.ZodOptional<z.ZodString>;
|
|
385
|
+
resolution: z.ZodOptional<z.ZodString>;
|
|
386
|
+
framerate: z.ZodOptional<z.ZodNumber>;
|
|
387
|
+
codec: z.ZodOptional<z.ZodEnum<{
|
|
388
|
+
h264: "h264";
|
|
389
|
+
h265: "h265";
|
|
390
|
+
}>>;
|
|
391
|
+
input_id: z.ZodOptional<z.ZodString>;
|
|
392
|
+
}, z.core.$strip>;
|
|
393
|
+
export type ChangeConfigParams = z.infer<typeof changeConfigParamsSchema>;
|
|
394
|
+
export declare const changeConfigResultSchema: z.ZodObject<{
|
|
395
|
+
attempt_id: z.ZodString;
|
|
396
|
+
phase: z.ZodEnum<{
|
|
397
|
+
applying: "applying";
|
|
398
|
+
applied: "applied";
|
|
399
|
+
reverted: "reverted";
|
|
400
|
+
rollback_failed: "rollback_failed";
|
|
401
|
+
}>;
|
|
402
|
+
state: z.ZodEnum<{
|
|
403
|
+
idle: "idle";
|
|
404
|
+
starting: "starting";
|
|
405
|
+
streaming: "streaming";
|
|
406
|
+
stopping: "stopping";
|
|
407
|
+
}>;
|
|
408
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
409
|
+
}, z.core.$strip>;
|
|
410
|
+
export type ChangeConfigResult = z.infer<typeof changeConfigResultSchema>;
|
|
411
|
+
/**
|
|
412
|
+
* The `reason` a `rollback_failed` carries when a teardown deadline overran.
|
|
413
|
+
* A TERMINAL supervisor escalation, not an ordinary failure: the engine could not
|
|
414
|
+
* prove the old session released its capture devices within the bound, so it
|
|
415
|
+
* refuses to build a second session that would race it. Mirrors the Rust
|
|
416
|
+
* `REASON_TEARDOWN_TIMEOUT`; consumers render it distinctly.
|
|
417
|
+
*/
|
|
418
|
+
export declare const REASON_TEARDOWN_TIMEOUT: "teardown_timeout";
|
|
376
419
|
/** The eight v1 control methods (the literal JSON-RPC `method` strings). */
|
|
377
420
|
export declare const V1_METHODS: readonly ["start", "stop", "reload-config", "set-bitrate", "switch-input", "list-devices", "subscribe-events", "preview-session"];
|
|
378
421
|
export type V1Method = (typeof V1_METHODS)[number];
|
|
@@ -478,6 +521,7 @@ export declare const requestSchemas: {
|
|
|
478
521
|
audio: z.ZodOptional<z.ZodObject<{
|
|
479
522
|
delay_ms: z.ZodOptional<z.ZodNumber>;
|
|
480
523
|
delay_ms_signed: z.ZodOptional<z.ZodNumber>;
|
|
524
|
+
meter_device: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
481
525
|
}, z.core.$strip>>;
|
|
482
526
|
}, z.core.$strip>;
|
|
483
527
|
readonly result: z.ZodObject<{
|
|
@@ -497,6 +541,7 @@ export declare const requestSchemas: {
|
|
|
497
541
|
audio: z.ZodOptional<z.ZodObject<{
|
|
498
542
|
delay_ms: z.ZodOptional<z.ZodNumber>;
|
|
499
543
|
delay_ms_signed: z.ZodOptional<z.ZodNumber>;
|
|
544
|
+
meter_device: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
500
545
|
}, z.core.$strip>>;
|
|
501
546
|
}, z.core.$strip>;
|
|
502
547
|
bitrate_control: z.ZodOptional<z.ZodEnum<{
|
|
@@ -578,6 +623,8 @@ export declare const requestSchemas: {
|
|
|
578
623
|
onboard: "onboard";
|
|
579
624
|
}>>;
|
|
580
625
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
626
|
+
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
627
|
+
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
581
628
|
}, z.core.$strip>>;
|
|
582
629
|
}, z.core.$strip>;
|
|
583
630
|
};
|
|
@@ -592,6 +639,7 @@ export declare const requestSchemas: {
|
|
|
592
639
|
"srt-stats": "srt-stats";
|
|
593
640
|
preview: "preview";
|
|
594
641
|
"audio-level": "audio-level";
|
|
642
|
+
"config-change": "config-change";
|
|
595
643
|
}>>>;
|
|
596
644
|
}, z.core.$strip>;
|
|
597
645
|
readonly result: z.ZodObject<{
|
|
@@ -604,6 +652,7 @@ export declare const requestSchemas: {
|
|
|
604
652
|
"srt-stats": "srt-stats";
|
|
605
653
|
preview: "preview";
|
|
606
654
|
"audio-level": "audio-level";
|
|
655
|
+
"config-change": "config-change";
|
|
607
656
|
}>>;
|
|
608
657
|
}, z.core.$strip>;
|
|
609
658
|
};
|
package/dist/messages.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { AUDIO_DELAY_MAX_MS } from "./constants.js";
|
|
3
3
|
import { helloParamsSchema, helloResultSchema, } from "./envelope.js";
|
|
4
|
-
import { balancerAlgorithmSchema, bitrateControlSchema, captureDeviceSchema, cerastreamConfigSchema, inputModeSchema, mediaClassSchema, previewTierSchema, streamStateSchema, } from "./types.js";
|
|
4
|
+
import { balancerAlgorithmSchema, bitrateControlSchema, captureDeviceSchema, cerastreamConfigSchema, configChangePhaseSchema, inputModeSchema, mediaClassSchema, previewTierSchema, streamStateSchema, videoCodecSchema, } from "./types.js";
|
|
5
5
|
// The eight v1 control methods (schema.md "v1 messages"). Each is matched
|
|
6
6
|
// byte-for-byte to schema.md: the JSON shape on the wire is the contract.
|
|
7
7
|
// ---- 1. start ----
|
|
@@ -39,6 +39,10 @@ export const reloadConfigParamsSchema = z.object({
|
|
|
39
39
|
.object({
|
|
40
40
|
delay_ms: z.number().int().min(0).max(AUDIO_DELAY_MAX_MS).optional(), // legacy unsigned; kept for 0.3.0 callers
|
|
41
41
|
delay_ms_signed: z.number().int().optional(), // signed sibling; clamped at apply, so unbounded
|
|
42
|
+
// additive (0.9.0): idle-meter card preference — absent leaves it unchanged,
|
|
43
|
+
// `null` restores the engine's auto-pick, `hw:CARD=…` prefers that card
|
|
44
|
+
// (a preference, not a pin: a card that never delivers is still demoted)
|
|
45
|
+
meter_device: z.string().nullable().optional(),
|
|
42
46
|
})
|
|
43
47
|
.optional(),
|
|
44
48
|
});
|
|
@@ -100,6 +104,7 @@ export const eventTopicSchema = z.enum([
|
|
|
100
104
|
"error",
|
|
101
105
|
"preview",
|
|
102
106
|
"audio-level",
|
|
107
|
+
"config-change",
|
|
103
108
|
]);
|
|
104
109
|
export const subscribeEventsParamsSchema = z.object({
|
|
105
110
|
topics: z.array(eventTopicSchema).optional(), // default: all topics
|
|
@@ -188,6 +193,42 @@ export const getCapabilitiesResultSchema = z.object({
|
|
|
188
193
|
network_embedded_audio: z.boolean().optional(), // engine routes network-ingest embedded audio to the mux
|
|
189
194
|
features: z.array(z.string()).optional(), // named engine features (e.g. "video-passthrough") for fail-closed negotiation
|
|
190
195
|
});
|
|
196
|
+
// ---- 10. change-config (0.10.0, additive) ----
|
|
197
|
+
// Deliberately absent from V1_METHODS / requestSchemas, like get-capabilities and
|
|
198
|
+
// switch-audio, so the frozen eight-method contract count stays eight. Params are
|
|
199
|
+
// a DELTA of startParamsSchema: absent ⇒ keep the live value. An empty delta is
|
|
200
|
+
// refused with `cerastream.params.invalid` — a no-op that restarted the pipeline
|
|
201
|
+
// would be the worst possible outcome. `input_id` rides the transaction, so a
|
|
202
|
+
// source change renegotiates caps instead of going through `switch-input`.
|
|
203
|
+
export const changeConfigParamsSchema = z
|
|
204
|
+
.object({
|
|
205
|
+
pipeline: z.string().optional(),
|
|
206
|
+
resolution: z.string().optional(), // "WxH" pixels, e.g. "3840x2160"
|
|
207
|
+
framerate: z.number().optional(),
|
|
208
|
+
codec: videoCodecSchema.optional(),
|
|
209
|
+
input_id: z.string().optional(),
|
|
210
|
+
})
|
|
211
|
+
.refine((delta) => Object.keys(delta).length > 0, {
|
|
212
|
+
message: "change-config delta must carry at least one field",
|
|
213
|
+
});
|
|
214
|
+
// `Ok` for every phase the transaction actually reached — INCLUDING
|
|
215
|
+
// `rollback_failed`, an honest terminal outcome rather than an RPC fault. A
|
|
216
|
+
// Tier-1 error means the transaction never started, so a caller can tell
|
|
217
|
+
// "nothing happened" from "something happened and here is what".
|
|
218
|
+
export const changeConfigResultSchema = z.object({
|
|
219
|
+
attempt_id: z.string(), // correlates with every config-change event of the attempt
|
|
220
|
+
phase: configChangePhaseSchema, // the TERMINAL phase reached
|
|
221
|
+
state: streamStateSchema, // streaming for applied/reverted, idle for rollback_failed
|
|
222
|
+
reason: z.string().optional(), // machine-stable cause on a non-applied phase
|
|
223
|
+
});
|
|
224
|
+
/**
|
|
225
|
+
* The `reason` a `rollback_failed` carries when a teardown deadline overran.
|
|
226
|
+
* A TERMINAL supervisor escalation, not an ordinary failure: the engine could not
|
|
227
|
+
* prove the old session released its capture devices within the bound, so it
|
|
228
|
+
* refuses to build a second session that would race it. Mirrors the Rust
|
|
229
|
+
* `REASON_TEARDOWN_TIMEOUT`; consumers render it distinctly.
|
|
230
|
+
*/
|
|
231
|
+
export const REASON_TEARDOWN_TIMEOUT = "teardown_timeout";
|
|
191
232
|
// ---- method registry (count-assertion source of truth) ----
|
|
192
233
|
/** The eight v1 control methods (the literal JSON-RPC `method` strings). */
|
|
193
234
|
export const V1_METHODS = [
|
package/dist/types.d.ts
CHANGED
|
@@ -61,6 +61,13 @@ export declare const deviceTransportSchema: z.ZodEnum<{
|
|
|
61
61
|
onboard: "onboard";
|
|
62
62
|
}>;
|
|
63
63
|
export type DeviceTransport = z.infer<typeof deviceTransportSchema>;
|
|
64
|
+
export declare const configChangePhaseSchema: z.ZodEnum<{
|
|
65
|
+
applying: "applying";
|
|
66
|
+
applied: "applied";
|
|
67
|
+
reverted: "reverted";
|
|
68
|
+
rollback_failed: "rollback_failed";
|
|
69
|
+
}>;
|
|
70
|
+
export type ConfigChangePhase = z.infer<typeof configChangePhaseSchema>;
|
|
64
71
|
/** SRT transport config. Mirrors schema.md `start.srt` exactly. */
|
|
65
72
|
export declare const srtConfigSchema: z.ZodObject<{
|
|
66
73
|
host: z.ZodString;
|
|
@@ -206,6 +213,8 @@ export declare const captureDeviceSchema: z.ZodObject<{
|
|
|
206
213
|
onboard: "onboard";
|
|
207
214
|
}>>;
|
|
208
215
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
216
|
+
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
217
|
+
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
209
218
|
}, z.core.$strip>;
|
|
210
219
|
export type CaptureDevice = z.infer<typeof captureDeviceSchema>;
|
|
211
220
|
export declare const srtStatsSchema: z.ZodObject<{
|
package/dist/types.js
CHANGED
|
@@ -52,6 +52,18 @@ export const deviceTransportSchema = z.enum([
|
|
|
52
52
|
"bluetooth",
|
|
53
53
|
"onboard",
|
|
54
54
|
]);
|
|
55
|
+
// Phase of one `change-config` transaction (0.10.0, additive). `applying` is
|
|
56
|
+
// published once at entry, then exactly ONE terminal phase for the same
|
|
57
|
+
// attempt_id: `applied` (the new config satisfied the outcome gate),
|
|
58
|
+
// `reverted` (it did not and the single known-good rollback attempt did), or
|
|
59
|
+
// `rollback_failed` (no rollback was possible, or the one attempt also failed —
|
|
60
|
+
// the engine is idle, which is the truthful terminal state).
|
|
61
|
+
export const configChangePhaseSchema = z.enum([
|
|
62
|
+
"applying",
|
|
63
|
+
"applied",
|
|
64
|
+
"reverted",
|
|
65
|
+
"rollback_failed",
|
|
66
|
+
]);
|
|
55
67
|
// ---- config sub-schemas (canonical; reused by `start` + the unified config) ----
|
|
56
68
|
/** SRT transport config. Mirrors schema.md `start.srt` exactly. */
|
|
57
69
|
export const srtConfigSchema = z.object({
|
|
@@ -143,6 +155,8 @@ export const captureDeviceSchema = z.object({
|
|
|
143
155
|
product_name: z.string().optional(), // additive (Todo 20): real product name, deduped with a #N suffix when shared; absent ⇒ use display_name
|
|
144
156
|
transport: deviceTransportSchema.optional(), // additive (Todo 20): how the device is attached; absent on legacy producers
|
|
145
157
|
stable_id: z.string().optional(), // additive (Todo 20): reboot-stable hardware identity, distinct from input_id/device_path
|
|
158
|
+
physical_group_id: z.string().optional(), // additive (0.10.0, ADR-0008): `usb:<topology-token>` shared by one physical device's rows; absent on non-USB + legacy producers, and an absent group NEVER matches
|
|
159
|
+
hardware_serial: z.string().optional(), // additive (0.10.0, ADR-0008): USB serial, DIAGNOSTIC ONLY — vendors ship placeholder serials, so never match/group/select on it
|
|
146
160
|
});
|
|
147
161
|
// ---- transport telemetry (srt-stats event payload) ----
|
|
148
162
|
export const srtStatsSchema = z.object({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ceralive/cerastream",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.4",
|
|
4
4
|
"description": "Type-safe TypeScript schema + IPC client for the cerastream streaming engine (JSON-RPC 2.0 / NDJSON over a Unix domain socket).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|