@ceralive/cerastream 2026.8.0 → 2026.9.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 +1 -0
- package/dist/client.js +1 -1
- package/dist/constants.d.ts +15 -2
- package/dist/constants.js +20 -2
- package/dist/errors.d.ts +20 -1
- package/dist/errors.js +20 -1
- package/dist/events.d.ts +24 -0
- package/dist/events.js +3 -1
- package/dist/messages.d.ts +2 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ engine's JSON-RPC 2.0 / NDJSON control plane over a Unix domain socket.
|
|
|
8
8
|
- The eight v1 control methods (Zod params + result schemas + inferred types)
|
|
9
9
|
- The nine server-push event payloads (discriminated union)
|
|
10
10
|
- Two-tier error codes (RPC + runtime)
|
|
11
|
+
- Typed capture-probe causes retained on runtime events and rejected-start exceptions
|
|
11
12
|
- A unified engine config schema (= `start` params)
|
|
12
13
|
- A `CerastreamClient` interface + `connect()` factory (UDS transport)
|
|
13
14
|
- Additive `client.getCapabilities()` discovery for platform, source, encoder, and
|
package/dist/client.js
CHANGED
|
@@ -183,7 +183,7 @@ class ClientImpl {
|
|
|
183
183
|
if (!parsed.success)
|
|
184
184
|
return;
|
|
185
185
|
const { id, error } = parsed.data;
|
|
186
|
-
const rpcErr = new CerastreamRpcError(error.code, error.message, error.data?.code, id);
|
|
186
|
+
const rpcErr = new CerastreamRpcError(error.code, error.message, error.data?.code, id, error.data);
|
|
187
187
|
if (id == null)
|
|
188
188
|
return; // parse error with null id — no request to settle.
|
|
189
189
|
const pending = this.pending.get(id);
|
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.12.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}. */
|
|
@@ -56,14 +56,27 @@ export declare const SUPPORTED_PROFILES: readonly ['balanced', 'low-latency', 'r
|
|
|
56
56
|
* set or any preset's meaning changes. Mirrors the Rust `PROFILE_CATALOG_VERSION`.
|
|
57
57
|
*/
|
|
58
58
|
export declare const PROFILE_CATALOG_VERSION: '1.0.0';
|
|
59
|
+
/**
|
|
60
|
+
* PipeWire-backed audio capture: the engine addresses capture nodes by
|
|
61
|
+
* `node.name`/`object.serial`, so a source with no ALSA card — a Bluetooth
|
|
62
|
+
* microphone is the first one — is selectable as an ordinary node. Unlike the
|
|
63
|
+
* other tokens this one describes the engine's RUNNING configuration, so an
|
|
64
|
+
* engine configured for ALSA omits it even though this catalog lists it. Mirrors
|
|
65
|
+
* the Rust `PIPEWIRE_CAPTURE_FEATURE`.
|
|
66
|
+
*/
|
|
67
|
+
export declare const PIPEWIRE_CAPTURE_FEATURE: 'pipewire-capture';
|
|
59
68
|
/**
|
|
60
69
|
* Named engine features `get-capabilities` advertises in `features`. This is the
|
|
61
70
|
* fail-closed negotiation contract: CeraUI sends a new out-of-schema field ONLY
|
|
62
71
|
* when its feature is listed, so an engine that predates a feature (and silently
|
|
63
72
|
* ignores the field) never applies a semantic the caller assumed. Mirrors the
|
|
64
73
|
* Rust `ENGINE_FEATURES`.
|
|
74
|
+
*
|
|
75
|
+
* This is the full CATALOG. Gate on the token in the engine's own `features`
|
|
76
|
+
* array, never on membership here — a configuration-dependent token is filtered
|
|
77
|
+
* out of the response the engine actually sends.
|
|
65
78
|
*/
|
|
66
|
-
export declare const ENGINE_FEATURES: readonly ['video-passthrough', 'input-mode', 'audio-pcm-spec'];
|
|
79
|
+
export declare const ENGINE_FEATURES: readonly ['video-passthrough', 'input-mode', 'audio-pcm-spec', "pipewire-capture"];
|
|
67
80
|
/** Engine binary name (systemd-owned; CeraUI never spawns it — ADR-0005). */
|
|
68
81
|
export declare const CERASTREAM_BIN: 'cerastream';
|
|
69
82
|
export declare const DEFAULT_MIN_BITRATE = 300;
|
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.12.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}. */
|
|
@@ -65,14 +65,32 @@ export const SUPPORTED_PROFILES = [
|
|
|
65
65
|
* set or any preset's meaning changes. Mirrors the Rust `PROFILE_CATALOG_VERSION`.
|
|
66
66
|
*/
|
|
67
67
|
export const PROFILE_CATALOG_VERSION = '1.0.0';
|
|
68
|
+
/**
|
|
69
|
+
* PipeWire-backed audio capture: the engine addresses capture nodes by
|
|
70
|
+
* `node.name`/`object.serial`, so a source with no ALSA card — a Bluetooth
|
|
71
|
+
* microphone is the first one — is selectable as an ordinary node. Unlike the
|
|
72
|
+
* other tokens this one describes the engine's RUNNING configuration, so an
|
|
73
|
+
* engine configured for ALSA omits it even though this catalog lists it. Mirrors
|
|
74
|
+
* the Rust `PIPEWIRE_CAPTURE_FEATURE`.
|
|
75
|
+
*/
|
|
76
|
+
export const PIPEWIRE_CAPTURE_FEATURE = 'pipewire-capture';
|
|
68
77
|
/**
|
|
69
78
|
* Named engine features `get-capabilities` advertises in `features`. This is the
|
|
70
79
|
* fail-closed negotiation contract: CeraUI sends a new out-of-schema field ONLY
|
|
71
80
|
* when its feature is listed, so an engine that predates a feature (and silently
|
|
72
81
|
* ignores the field) never applies a semantic the caller assumed. Mirrors the
|
|
73
82
|
* Rust `ENGINE_FEATURES`.
|
|
83
|
+
*
|
|
84
|
+
* This is the full CATALOG. Gate on the token in the engine's own `features`
|
|
85
|
+
* array, never on membership here — a configuration-dependent token is filtered
|
|
86
|
+
* out of the response the engine actually sends.
|
|
74
87
|
*/
|
|
75
|
-
export const ENGINE_FEATURES = [
|
|
88
|
+
export const ENGINE_FEATURES = [
|
|
89
|
+
'video-passthrough',
|
|
90
|
+
'input-mode',
|
|
91
|
+
'audio-pcm-spec',
|
|
92
|
+
PIPEWIRE_CAPTURE_FEATURE,
|
|
93
|
+
];
|
|
76
94
|
/** Engine binary name (systemd-owned; CeraUI never spawns it — ADR-0005). */
|
|
77
95
|
export const CERASTREAM_BIN = 'cerastream';
|
|
78
96
|
// ---- config defaults (mirror ceracoder, the engine being replaced) ----
|
package/dist/errors.d.ts
CHANGED
|
@@ -20,7 +20,11 @@ export declare class CerastreamRpcError extends Error {
|
|
|
20
20
|
readonly dataCode: string | undefined;
|
|
21
21
|
/** The request id this error answered, when present. */
|
|
22
22
|
readonly requestId: number | string | null;
|
|
23
|
-
|
|
23
|
+
/** Full JSON-RPC `error.data` object, retained for additive typed detail. */
|
|
24
|
+
readonly data?: unknown;
|
|
25
|
+
constructor(code: number, message: string, dataCode: string | undefined, requestId: number | string | null, data?: unknown);
|
|
26
|
+
/** Typed capture-probe failures carried by a rejected stream start. */
|
|
27
|
+
captureCauses(): readonly CaptureCauseEntry[];
|
|
24
28
|
}
|
|
25
29
|
/**
|
|
26
30
|
* Machine-readable classification of a {@link CerastreamConnectionError}, stable
|
|
@@ -91,6 +95,21 @@ export declare const processErrorCodeSchema: z.ZodEnum<{
|
|
|
91
95
|
srtla_no_connections: "srtla_no_connections";
|
|
92
96
|
}>;
|
|
93
97
|
export type ProcessErrorCode = z.infer<typeof processErrorCodeSchema>;
|
|
98
|
+
export declare const captureCauseSchema: z.ZodEnum<{
|
|
99
|
+
device_busy: "device_busy";
|
|
100
|
+
negotiation_failed: "negotiation_failed";
|
|
101
|
+
no_signal: "no_signal";
|
|
102
|
+
}>;
|
|
103
|
+
export type CaptureCause = z.infer<typeof captureCauseSchema>;
|
|
104
|
+
export declare const captureCauseEntrySchema: z.ZodObject<{
|
|
105
|
+
device: z.ZodString;
|
|
106
|
+
cause: z.ZodEnum<{
|
|
107
|
+
device_busy: "device_busy";
|
|
108
|
+
negotiation_failed: "negotiation_failed";
|
|
109
|
+
no_signal: "no_signal";
|
|
110
|
+
}>;
|
|
111
|
+
}, z.core.$strip>;
|
|
112
|
+
export type CaptureCauseEntry = z.infer<typeof captureCauseEntrySchema>;
|
|
94
113
|
/**
|
|
95
114
|
* Why a capture device became `capture_unrecoverable` — the `reason` field of the
|
|
96
115
|
* `error` event. Mirrors the Rust `CaptureUnrecoverableReason`.
|
package/dist/errors.js
CHANGED
|
@@ -23,12 +23,21 @@ export class CerastreamRpcError extends Error {
|
|
|
23
23
|
dataCode;
|
|
24
24
|
/** The request id this error answered, when present. */
|
|
25
25
|
requestId;
|
|
26
|
-
|
|
26
|
+
/** Full JSON-RPC `error.data` object, retained for additive typed detail. */
|
|
27
|
+
data;
|
|
28
|
+
constructor(code, message, dataCode, requestId, data) {
|
|
27
29
|
super(message);
|
|
28
30
|
this.name = 'CerastreamRpcError';
|
|
29
31
|
this.code = code;
|
|
30
32
|
this.dataCode = dataCode;
|
|
31
33
|
this.requestId = requestId;
|
|
34
|
+
if (data !== undefined)
|
|
35
|
+
this.data = data;
|
|
36
|
+
}
|
|
37
|
+
/** Typed capture-probe failures carried by a rejected stream start. */
|
|
38
|
+
captureCauses() {
|
|
39
|
+
const parsed = rpcCaptureDataSchema.safeParse(this.data);
|
|
40
|
+
return parsed.success ? parsed.data.capture_causes : [];
|
|
32
41
|
}
|
|
33
42
|
}
|
|
34
43
|
/**
|
|
@@ -129,6 +138,16 @@ export const processErrorCodeSchema = z.enum([
|
|
|
129
138
|
// would be lying. Always carries a captureUnrecoverableReasonSchema `reason`.
|
|
130
139
|
'capture_unrecoverable',
|
|
131
140
|
]);
|
|
141
|
+
export const captureCauseSchema = z.enum(['negotiation_failed', 'no_signal', 'device_busy']);
|
|
142
|
+
export const captureCauseEntrySchema = z.object({
|
|
143
|
+
device: z.string(),
|
|
144
|
+
cause: captureCauseSchema,
|
|
145
|
+
});
|
|
146
|
+
const rpcCaptureDataSchema = z
|
|
147
|
+
.object({
|
|
148
|
+
capture_causes: z.array(captureCauseEntrySchema),
|
|
149
|
+
})
|
|
150
|
+
.passthrough();
|
|
132
151
|
/**
|
|
133
152
|
* Why a capture device became `capture_unrecoverable` — the `reason` field of the
|
|
134
153
|
* `error` event. Mirrors the Rust `CaptureUnrecoverableReason`.
|
package/dist/events.d.ts
CHANGED
|
@@ -192,6 +192,7 @@ export declare const deviceEventSchema: z.ZodObject<{
|
|
|
192
192
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
193
193
|
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
194
194
|
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
195
|
+
device_address: z.ZodOptional<z.ZodString>;
|
|
195
196
|
}, z.core.$strip>;
|
|
196
197
|
}, z.core.$strip>;
|
|
197
198
|
/** Payload of a {@link deviceEventSchema} event. */
|
|
@@ -238,6 +239,11 @@ export declare const runtimeErrorEventSchema: z.ZodObject<{
|
|
|
238
239
|
}>;
|
|
239
240
|
reason: z.ZodOptional<z.ZodString>;
|
|
240
241
|
selected: z.ZodOptional<z.ZodBoolean>;
|
|
242
|
+
capture_cause: z.ZodOptional<z.ZodEnum<{
|
|
243
|
+
device_busy: "device_busy";
|
|
244
|
+
negotiation_failed: "negotiation_failed";
|
|
245
|
+
no_signal: "no_signal";
|
|
246
|
+
}>>;
|
|
241
247
|
}, z.core.$strip>;
|
|
242
248
|
/** Payload of a {@link runtimeErrorEventSchema} event. */
|
|
243
249
|
export type RuntimeErrorEvent = z.infer<typeof runtimeErrorEventSchema>;
|
|
@@ -424,6 +430,7 @@ export declare const eventParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
424
430
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
425
431
|
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
426
432
|
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
433
|
+
device_address: z.ZodOptional<z.ZodString>;
|
|
427
434
|
}, z.core.$strip>;
|
|
428
435
|
}, z.core.$strip>, z.ZodObject<{
|
|
429
436
|
type: z.ZodLiteral<"bitrate">;
|
|
@@ -455,6 +462,11 @@ export declare const eventParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
455
462
|
}>;
|
|
456
463
|
reason: z.ZodOptional<z.ZodString>;
|
|
457
464
|
selected: z.ZodOptional<z.ZodBoolean>;
|
|
465
|
+
capture_cause: z.ZodOptional<z.ZodEnum<{
|
|
466
|
+
device_busy: "device_busy";
|
|
467
|
+
negotiation_failed: "negotiation_failed";
|
|
468
|
+
no_signal: "no_signal";
|
|
469
|
+
}>>;
|
|
458
470
|
}, z.core.$strip>, z.ZodObject<{
|
|
459
471
|
type: z.ZodLiteral<"preview">;
|
|
460
472
|
seq: z.ZodNumber;
|
|
@@ -615,6 +627,7 @@ export declare const cerastreamEventSchema: z.ZodObject<{
|
|
|
615
627
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
616
628
|
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
617
629
|
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
630
|
+
device_address: z.ZodOptional<z.ZodString>;
|
|
618
631
|
}, z.core.$strip>;
|
|
619
632
|
}, z.core.$strip>, z.ZodObject<{
|
|
620
633
|
type: z.ZodLiteral<"bitrate">;
|
|
@@ -646,6 +659,11 @@ export declare const cerastreamEventSchema: z.ZodObject<{
|
|
|
646
659
|
}>;
|
|
647
660
|
reason: z.ZodOptional<z.ZodString>;
|
|
648
661
|
selected: z.ZodOptional<z.ZodBoolean>;
|
|
662
|
+
capture_cause: z.ZodOptional<z.ZodEnum<{
|
|
663
|
+
device_busy: "device_busy";
|
|
664
|
+
negotiation_failed: "negotiation_failed";
|
|
665
|
+
no_signal: "no_signal";
|
|
666
|
+
}>>;
|
|
649
667
|
}, z.core.$strip>, z.ZodObject<{
|
|
650
668
|
type: z.ZodLiteral<"preview">;
|
|
651
669
|
seq: z.ZodNumber;
|
|
@@ -812,6 +830,7 @@ export declare const eventSchemas: {
|
|
|
812
830
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
813
831
|
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
814
832
|
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
833
|
+
device_address: z.ZodOptional<z.ZodString>;
|
|
815
834
|
}, z.core.$strip>;
|
|
816
835
|
}, z.core.$strip>;
|
|
817
836
|
readonly bitrate: z.ZodObject<{
|
|
@@ -846,6 +865,11 @@ export declare const eventSchemas: {
|
|
|
846
865
|
}>;
|
|
847
866
|
reason: z.ZodOptional<z.ZodString>;
|
|
848
867
|
selected: z.ZodOptional<z.ZodBoolean>;
|
|
868
|
+
capture_cause: z.ZodOptional<z.ZodEnum<{
|
|
869
|
+
device_busy: "device_busy";
|
|
870
|
+
negotiation_failed: "negotiation_failed";
|
|
871
|
+
no_signal: "no_signal";
|
|
872
|
+
}>>;
|
|
849
873
|
}, z.core.$strip>;
|
|
850
874
|
readonly preview: z.ZodObject<{
|
|
851
875
|
type: z.ZodLiteral<"preview">;
|
package/dist/events.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { processErrorCodeSchema, processErrorSourceSchema } from './errors.js';
|
|
2
|
+
import { captureCauseSchema, processErrorCodeSchema, processErrorSourceSchema } from './errors.js';
|
|
3
3
|
import { captureDeviceSchema, configChangePhaseSchema, inputModeSchema, mediaClassSchema, previewEncodeFallbackSchema, previewEncodeModeSchema, 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:
|
|
@@ -119,6 +119,8 @@ export const runtimeErrorEventSchema = z.object({
|
|
|
119
119
|
source: processErrorSourceSchema,
|
|
120
120
|
reason: z.string().optional(), // structured replacement for the stderr <reason>
|
|
121
121
|
selected: z.boolean().optional(), // additive (0.11.0): the degraded input is the operator's OWN selection, so the stream will not move itself and only they can pick another — a materially different operator response than a degraded non-selected input, and one to branch on rather than string-match. Absent ⇒ false
|
|
122
|
+
// The code stays capture_video_error because older consumers reject unknown code values.
|
|
123
|
+
capture_cause: captureCauseSchema.optional(),
|
|
122
124
|
});
|
|
123
125
|
/** `preview` event — a preview-session lifecycle/phase change. */
|
|
124
126
|
export const previewEventSchema = z.object({
|
package/dist/messages.d.ts
CHANGED
|
@@ -241,6 +241,7 @@ export declare const listDevicesResultSchema: z.ZodObject<{
|
|
|
241
241
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
242
242
|
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
243
243
|
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
244
|
+
device_address: z.ZodOptional<z.ZodString>;
|
|
244
245
|
}, z.core.$strip>>;
|
|
245
246
|
}, z.core.$strip>;
|
|
246
247
|
export type ListDevicesResult = z.infer<typeof listDevicesResultSchema>;
|
|
@@ -711,6 +712,7 @@ export declare const requestSchemas: {
|
|
|
711
712
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
712
713
|
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
713
714
|
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
715
|
+
device_address: z.ZodOptional<z.ZodString>;
|
|
714
716
|
}, z.core.$strip>>;
|
|
715
717
|
}, z.core.$strip>;
|
|
716
718
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -276,6 +276,7 @@ export declare const captureDeviceSchema: z.ZodObject<{
|
|
|
276
276
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
277
277
|
physical_group_id: z.ZodOptional<z.ZodString>;
|
|
278
278
|
hardware_serial: z.ZodOptional<z.ZodString>;
|
|
279
|
+
device_address: z.ZodOptional<z.ZodString>;
|
|
279
280
|
}, z.core.$strip>;
|
|
280
281
|
export type CaptureDevice = z.infer<typeof captureDeviceSchema>;
|
|
281
282
|
export declare const srtStatsSchema: z.ZodObject<{
|
package/dist/types.js
CHANGED
|
@@ -184,6 +184,7 @@ export const captureDeviceSchema = z.object({
|
|
|
184
184
|
stable_id: z.string().optional(), // additive (Todo 20): reboot-stable hardware identity, distinct from input_id/device_path
|
|
185
185
|
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
|
|
186
186
|
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
|
|
187
|
+
device_address: z.string().optional(), // additive: the address the node's provider advertises, carried verbatim; the engine attaches no meaning to it, so the consumer owning the address space is the one that matches on it. Absent unless a provider published one
|
|
187
188
|
});
|
|
188
189
|
// ---- transport telemetry (srt-stats event payload) ----
|
|
189
190
|
export const srtStatsSchema = z.object({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ceralive/cerastream",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.9.0",
|
|
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",
|