@ceralive/cerastream 2026.7.5 → 2026.7.6

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/dist/events.d.ts CHANGED
@@ -20,6 +20,37 @@ export declare const activeEncodeSchema: z.ZodObject<{
20
20
  pipeline_playing: z.ZodOptional<z.ZodBoolean>;
21
21
  }, z.core.$strip>;
22
22
  export type ActiveEncode = z.infer<typeof activeEncodeSchema>;
23
+ /**
24
+ * What this session's PREVIEW branch is actually encoding with (additive),
25
+ * reported on the `status` event as `preview_encoder_realized`. A separate
26
+ * realized fact from {@link activeEncodeSchema}, which describes the EGRESS
27
+ * encode — the two are different graph branches and are independently absent.
28
+ *
29
+ * Present only while a session has a preview branch spliced into its graph (the
30
+ * branch exists for the life of the session even while its valve is closed).
31
+ * ABSENT means "no preview branch, or a legacy emitter" — which is NOT
32
+ * `mode: "software"` (a branch exists and encodes in software) and NOT
33
+ * `preview.preview_hw_capability === false` (the board publishes no preview
34
+ * encoder at all). Those three states must never be defaulted into each other.
35
+ *
36
+ * `mode` is the ACTIVE mode. The REQUESTED mode is deliberately not an engine
37
+ * fact: it lives in CeraUI's persisted config.
38
+ */
39
+ export declare const previewEncoderRealizedSchema: z.ZodObject<{
40
+ selected_element: z.ZodOptional<z.ZodString>;
41
+ realized_element: z.ZodString;
42
+ mode: z.ZodEnum<{
43
+ software: "software";
44
+ hardware: "hardware";
45
+ }>;
46
+ fallback_reason: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
47
+ code: z.ZodLiteral<"factory-missing">;
48
+ }, z.core.$strip>, z.ZodObject<{
49
+ code: z.ZodLiteral<"property-failure">;
50
+ property: z.ZodString;
51
+ }, z.core.$strip>], "code">>;
52
+ }, z.core.$strip>;
53
+ export type PreviewEncoderRealized = z.infer<typeof previewEncoderRealizedSchema>;
23
54
  /**
24
55
  * `status` event — stream state change + heartbeat. The trailing fields are
25
56
  * additive: the `buffering*` / `spooled_bytes` / `data_headroom_bytes` /
@@ -28,7 +59,9 @@ export type ActiveEncode = z.infer<typeof activeEncodeSchema>;
28
59
  * `active_profile` (srt-receive-profiles) reports the profile/config the stream is
29
60
  * running under and is absent on a legacy emitter or a bare state-only heartbeat;
30
61
  * `active_encode` (0.4.0) reports the resolved runtime encode and is absent on a
31
- * legacy emitter or a bare state-only heartbeat.
62
+ * legacy emitter or a bare state-only heartbeat; `preview_encoder_realized`
63
+ * reports the PREVIEW branch's own encoder and is absent when the session has no
64
+ * preview branch.
32
65
  */
33
66
  export declare const statusEventSchema: z.ZodObject<{
34
67
  type: z.ZodLiteral<"status">;
@@ -59,6 +92,20 @@ export declare const statusEventSchema: z.ZodObject<{
59
92
  frames_emitted: z.ZodOptional<z.ZodNumber>;
60
93
  pipeline_playing: z.ZodOptional<z.ZodBoolean>;
61
94
  }, z.core.$strip>>;
95
+ preview_encoder_realized: z.ZodOptional<z.ZodObject<{
96
+ selected_element: z.ZodOptional<z.ZodString>;
97
+ realized_element: z.ZodString;
98
+ mode: z.ZodEnum<{
99
+ software: "software";
100
+ hardware: "hardware";
101
+ }>;
102
+ fallback_reason: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
103
+ code: z.ZodLiteral<"factory-missing">;
104
+ }, z.core.$strip>, z.ZodObject<{
105
+ code: z.ZodLiteral<"property-failure">;
106
+ property: z.ZodString;
107
+ }, z.core.$strip>], "code">>;
108
+ }, z.core.$strip>>;
62
109
  }, z.core.$strip>;
63
110
  /** Payload of a {@link statusEventSchema} event. */
64
111
  export type StatusEvent = z.infer<typeof statusEventSchema>;
@@ -289,6 +336,20 @@ export declare const eventParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
289
336
  frames_emitted: z.ZodOptional<z.ZodNumber>;
290
337
  pipeline_playing: z.ZodOptional<z.ZodBoolean>;
291
338
  }, z.core.$strip>>;
339
+ preview_encoder_realized: z.ZodOptional<z.ZodObject<{
340
+ selected_element: z.ZodOptional<z.ZodString>;
341
+ realized_element: z.ZodString;
342
+ mode: z.ZodEnum<{
343
+ software: "software";
344
+ hardware: "hardware";
345
+ }>;
346
+ fallback_reason: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
347
+ code: z.ZodLiteral<"factory-missing">;
348
+ }, z.core.$strip>, z.ZodObject<{
349
+ code: z.ZodLiteral<"property-failure">;
350
+ property: z.ZodString;
351
+ }, z.core.$strip>], "code">>;
352
+ }, z.core.$strip>>;
292
353
  }, z.core.$strip>, z.ZodObject<{
293
354
  type: z.ZodLiteral<"switch">;
294
355
  seq: z.ZodNumber;
@@ -466,6 +527,20 @@ export declare const cerastreamEventSchema: z.ZodObject<{
466
527
  frames_emitted: z.ZodOptional<z.ZodNumber>;
467
528
  pipeline_playing: z.ZodOptional<z.ZodBoolean>;
468
529
  }, z.core.$strip>>;
530
+ preview_encoder_realized: z.ZodOptional<z.ZodObject<{
531
+ selected_element: z.ZodOptional<z.ZodString>;
532
+ realized_element: z.ZodString;
533
+ mode: z.ZodEnum<{
534
+ software: "software";
535
+ hardware: "hardware";
536
+ }>;
537
+ fallback_reason: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
538
+ code: z.ZodLiteral<"factory-missing">;
539
+ }, z.core.$strip>, z.ZodObject<{
540
+ code: z.ZodLiteral<"property-failure">;
541
+ property: z.ZodString;
542
+ }, z.core.$strip>], "code">>;
543
+ }, z.core.$strip>>;
469
544
  }, z.core.$strip>, z.ZodObject<{
470
545
  type: z.ZodLiteral<"switch">;
471
546
  seq: z.ZodNumber;
@@ -647,6 +722,20 @@ export declare const eventSchemas: {
647
722
  frames_emitted: z.ZodOptional<z.ZodNumber>;
648
723
  pipeline_playing: z.ZodOptional<z.ZodBoolean>;
649
724
  }, z.core.$strip>>;
725
+ preview_encoder_realized: z.ZodOptional<z.ZodObject<{
726
+ selected_element: z.ZodOptional<z.ZodString>;
727
+ realized_element: z.ZodString;
728
+ mode: z.ZodEnum<{
729
+ software: "software";
730
+ hardware: "hardware";
731
+ }>;
732
+ fallback_reason: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
733
+ code: z.ZodLiteral<"factory-missing">;
734
+ }, z.core.$strip>, z.ZodObject<{
735
+ code: z.ZodLiteral<"property-failure">;
736
+ property: z.ZodString;
737
+ }, z.core.$strip>], "code">>;
738
+ }, z.core.$strip>>;
650
739
  }, z.core.$strip>;
651
740
  readonly switch: z.ZodObject<{
652
741
  type: z.ZodLiteral<"switch">;
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, configChangePhaseSchema, inputModeSchema, mediaClassSchema, streamStateSchema, } from "./types.js";
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:
6
6
  // { type, seq, … }. `type` discriminates; `seq` is a per-type monotonic counter.
@@ -25,6 +25,28 @@ export const activeEncodeSchema = z.object({
25
25
  frames_emitted: z.number().int().nonnegative().optional(), // 0.7.0: monotonic egress-buffer counter; advances across status heartbeats while frames flow
26
26
  pipeline_playing: z.boolean().optional(), // 0.7.0: pipeline is in GStreamer PLAYING (false during an in-process reconnect)
27
27
  });
28
+ /**
29
+ * What this session's PREVIEW branch is actually encoding with (additive),
30
+ * reported on the `status` event as `preview_encoder_realized`. A separate
31
+ * realized fact from {@link activeEncodeSchema}, which describes the EGRESS
32
+ * encode — the two are different graph branches and are independently absent.
33
+ *
34
+ * Present only while a session has a preview branch spliced into its graph (the
35
+ * branch exists for the life of the session even while its valve is closed).
36
+ * ABSENT means "no preview branch, or a legacy emitter" — which is NOT
37
+ * `mode: "software"` (a branch exists and encodes in software) and NOT
38
+ * `preview.preview_hw_capability === false` (the board publishes no preview
39
+ * encoder at all). Those three states must never be defaulted into each other.
40
+ *
41
+ * `mode` is the ACTIVE mode. The REQUESTED mode is deliberately not an engine
42
+ * fact: it lives in CeraUI's persisted config.
43
+ */
44
+ export const previewEncoderRealizedSchema = z.object({
45
+ selected_element: z.string().optional(), // the element the platform's HAL descriptor publishes; absent ⇒ this board publishes none
46
+ realized_element: z.string(), // the element actually built into the preview branch, e.g. "x264enc"/"mpph264enc"
47
+ mode: previewEncodeModeSchema, // the encoder family actually realized — never the request
48
+ fallback_reason: previewEncodeFallbackSchema.optional(), // why a hardware request is in software; absent is the normal case
49
+ });
28
50
  /**
29
51
  * `status` event — stream state change + heartbeat. The trailing fields are
30
52
  * additive: the `buffering*` / `spooled_bytes` / `data_headroom_bytes` /
@@ -33,7 +55,9 @@ export const activeEncodeSchema = z.object({
33
55
  * `active_profile` (srt-receive-profiles) reports the profile/config the stream is
34
56
  * running under and is absent on a legacy emitter or a bare state-only heartbeat;
35
57
  * `active_encode` (0.4.0) reports the resolved runtime encode and is absent on a
36
- * legacy emitter or a bare state-only heartbeat.
58
+ * legacy emitter or a bare state-only heartbeat; `preview_encoder_realized`
59
+ * reports the PREVIEW branch's own encoder and is absent when the session has no
60
+ * preview branch.
37
61
  */
38
62
  export const statusEventSchema = z.object({
39
63
  type: z.literal("status"),
@@ -47,6 +71,7 @@ export const statusEventSchema = z.object({
47
71
  data_headroom_bytes: z.number().int().nonnegative().optional(),
48
72
  disk_warning: z.boolean().optional(),
49
73
  active_encode: activeEncodeSchema.optional(),
74
+ preview_encoder_realized: previewEncoderRealizedSchema.optional(),
50
75
  });
51
76
  /**
52
77
  * `switch` event — active input changed (manual or failover). `media_class` is
@@ -95,6 +95,10 @@ export declare const reloadConfigParamsSchema: z.ZodObject<{
95
95
  delay_ms_signed: z.ZodOptional<z.ZodNumber>;
96
96
  meter_device: z.ZodOptional<z.ZodNullable<z.ZodString>>;
97
97
  }, z.core.$strip>>;
98
+ preview_encode: z.ZodOptional<z.ZodEnum<{
99
+ software: "software";
100
+ hardware: "hardware";
101
+ }>>;
98
102
  }, z.core.$strip>;
99
103
  export type ReloadConfigParams = z.infer<typeof reloadConfigParamsSchema>;
100
104
  export declare const reloadConfigResultSchema: z.ZodObject<{
@@ -116,6 +120,10 @@ export declare const reloadConfigResultSchema: z.ZodObject<{
116
120
  delay_ms_signed: z.ZodOptional<z.ZodNumber>;
117
121
  meter_device: z.ZodOptional<z.ZodNullable<z.ZodString>>;
118
122
  }, z.core.$strip>>;
123
+ preview_encode: z.ZodOptional<z.ZodEnum<{
124
+ software: "software";
125
+ hardware: "hardware";
126
+ }>>;
119
127
  }, z.core.$strip>;
120
128
  bitrate_control: z.ZodOptional<z.ZodEnum<{
121
129
  encoder: "encoder";
@@ -357,6 +365,7 @@ export declare const previewAvailabilitySchema: z.ZodObject<{
357
365
  enabled: z.ZodBoolean;
358
366
  port: z.ZodOptional<z.ZodNumber>;
359
367
  bound: z.ZodBoolean;
368
+ preview_hw_capability: z.ZodOptional<z.ZodBoolean>;
360
369
  }, z.core.$strip>;
361
370
  export type PreviewAvailability = z.infer<typeof previewAvailabilitySchema>;
362
371
  export declare const getCapabilitiesResultSchema: z.ZodObject<{
@@ -404,6 +413,7 @@ export declare const getCapabilitiesResultSchema: z.ZodObject<{
404
413
  enabled: z.ZodBoolean;
405
414
  port: z.ZodOptional<z.ZodNumber>;
406
415
  bound: z.ZodBoolean;
416
+ preview_hw_capability: z.ZodOptional<z.ZodBoolean>;
407
417
  }, z.core.$strip>>;
408
418
  network_embedded_audio: z.ZodOptional<z.ZodBoolean>;
409
419
  features: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -572,6 +582,10 @@ export declare const requestSchemas: {
572
582
  delay_ms_signed: z.ZodOptional<z.ZodNumber>;
573
583
  meter_device: z.ZodOptional<z.ZodNullable<z.ZodString>>;
574
584
  }, z.core.$strip>>;
585
+ preview_encode: z.ZodOptional<z.ZodEnum<{
586
+ software: "software";
587
+ hardware: "hardware";
588
+ }>>;
575
589
  }, z.core.$strip>;
576
590
  readonly result: z.ZodObject<{
577
591
  applied: z.ZodObject<{
@@ -592,6 +606,10 @@ export declare const requestSchemas: {
592
606
  delay_ms_signed: z.ZodOptional<z.ZodNumber>;
593
607
  meter_device: z.ZodOptional<z.ZodNullable<z.ZodString>>;
594
608
  }, z.core.$strip>>;
609
+ preview_encode: z.ZodOptional<z.ZodEnum<{
610
+ software: "software";
611
+ hardware: "hardware";
612
+ }>>;
595
613
  }, z.core.$strip>;
596
614
  bitrate_control: z.ZodOptional<z.ZodEnum<{
597
615
  encoder: "encoder";
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, captureDeviceKindSchema, captureDeviceSchema, cerastreamConfigSchema, configChangePhaseSchema, inputModeSchema, mediaClassSchema, previewTierSchema, streamStateSchema, videoCodecSchema, } from "./types.js";
4
+ import { balancerAlgorithmSchema, bitrateControlSchema, captureDeviceKindSchema, captureDeviceSchema, cerastreamConfigSchema, configChangePhaseSchema, inputModeSchema, mediaClassSchema, previewEncodeModeSchema, 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 ----
@@ -45,6 +45,12 @@ export const reloadConfigParamsSchema = z.object({
45
45
  meter_device: z.string().nullable().optional(),
46
46
  })
47
47
  .optional(),
48
+ // Absent leaves the engine's current preview-encoder selection unchanged. This
49
+ // belongs on `reload-config` rather than `change-config`: the preview encoder is
50
+ // fixed when a session graph is built, so it takes effect on the NEXT stream
51
+ // session, and routing it through the transactional method would restart a live
52
+ // stream to change a preview setting.
53
+ preview_encode: previewEncodeModeSchema.optional(),
48
54
  });
49
55
  export const reloadConfigResultSchema = z.object({
50
56
  applied: reloadConfigParamsSchema, // post-clamp values actually applied
@@ -179,6 +185,15 @@ export const previewAvailabilitySchema = z.object({
179
185
  enabled: z.boolean(),
180
186
  port: z.number().int().min(1).max(65535).optional(), // present when a listener is (or would be) bound
181
187
  bound: z.boolean(),
188
+ // Whether this PLATFORM publishes a hardware preview encoder at all — the fact
189
+ // that decides whether a hardware-preview toggle may be offered. It rides the
190
+ // capability fetch rather than stream status because a consumer reads
191
+ // capabilities while IDLE, which is exactly when the operator picks the setting.
192
+ // Three readings, none interchangeable: absent ⇒ legacy engine, capability
193
+ // UNKNOWN (never assume false); false ⇒ this board publishes none, hide the
194
+ // toggle; true ⇒ it does. Independent of whether any session is realizing it
195
+ // (`status.preview_encoder_realized`).
196
+ preview_hw_capability: z.boolean().optional(),
182
197
  });
183
198
  export const getCapabilitiesResultSchema = z.object({
184
199
  platform: platformCapsSchema,
package/dist/types.d.ts CHANGED
@@ -27,6 +27,18 @@ export declare const previewTierSchema: z.ZodEnum<{
27
27
  webrtc: "webrtc";
28
28
  }>;
29
29
  export type PreviewTier = z.infer<typeof previewTierSchema>;
30
+ export declare const previewEncodeModeSchema: z.ZodEnum<{
31
+ software: "software";
32
+ hardware: "hardware";
33
+ }>;
34
+ export type PreviewEncodeMode = z.infer<typeof previewEncodeModeSchema>;
35
+ export declare const previewEncodeFallbackSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
36
+ code: z.ZodLiteral<"factory-missing">;
37
+ }, z.core.$strip>, z.ZodObject<{
38
+ code: z.ZodLiteral<"property-failure">;
39
+ property: z.ZodString;
40
+ }, z.core.$strip>], "code">;
41
+ export type PreviewEncodeFallback = z.infer<typeof previewEncodeFallbackSchema>;
30
42
  export declare const videoCodecSchema: z.ZodEnum<{
31
43
  h264: "h264";
32
44
  h265: "h265";
package/dist/types.js CHANGED
@@ -14,6 +14,22 @@ export const inputModeSchema = z.enum(["manual", "auto"]);
14
14
  export const balancerAlgorithmSchema = z.enum(["adaptive", "fixed", "aimd"]);
15
15
  export const mediaClassSchema = z.enum(["video", "audio"]);
16
16
  export const previewTierSchema = z.enum(["webcodecs", "webrtc"]);
17
+ // Which encoder the LIVE preview branch uses. Set through `reload-config`
18
+ // (additive) and reported back as the ACTIVE mode on stream status. Applies to
19
+ // the NEXT stream session: the preview encoder is fixed when a session graph is
20
+ // built, so this never swaps an encoder mid-stream.
21
+ export const previewEncodeModeSchema = z.enum(["software", "hardware"]);
22
+ // Why a `hardware` preview request is encoding in software anyway — a tagged
23
+ // union so a consumer branches on `code` and still receives the detail a code
24
+ // carries. `property-failure` names the property the element refused, which is
25
+ // the difference between "hardware preview is broken" and "this image's encoder
26
+ // plugin does not take `rc-mode`". ABSENT is the normal case (software was
27
+ // chosen, hardware was delivered, or the board never offered the toggle) — there
28
+ // is deliberately no `{code:"none"}` sentinel.
29
+ export const previewEncodeFallbackSchema = z.discriminatedUnion("code", [
30
+ z.object({ code: z.literal("factory-missing") }),
31
+ z.object({ code: z.literal("property-failure"), property: z.string() }),
32
+ ]);
17
33
  // Requested egress video codec (0.4.0, additive). Absent ⇒ the engine picks its
18
34
  // platform default. Wire values are the codec id strings the encoder caps also
19
35
  // advertise ("h264"/"h265") — never an encoder element name.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceralive/cerastream",
3
- "version": "2026.7.5",
3
+ "version": "2026.7.6",
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",