@ceralive/cerastream 2026.7.5 → 2026.8.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/dist/events.js CHANGED
@@ -1,6 +1,6 @@
1
- import { z } from "zod";
2
- import { processErrorCodeSchema, processErrorSourceSchema, } from "./errors.js";
3
- import { captureDeviceSchema, configChangePhaseSchema, inputModeSchema, mediaClassSchema, streamStateSchema, } from "./types.js";
1
+ import { z } from 'zod';
2
+ import { processErrorCodeSchema, processErrorSourceSchema } from './errors.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,10 +55,12 @@ 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
- type: z.literal("status"),
63
+ type: z.literal('status'),
40
64
  seq,
41
65
  state: streamStateSchema,
42
66
  streaming: z.boolean(),
@@ -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
@@ -54,7 +79,7 @@ export const statusEventSchema = z.object({
54
79
  * `"audio"`.
55
80
  */
56
81
  export const switchEventSchema = z.object({
57
- type: z.literal("switch"),
82
+ type: z.literal('switch'),
58
83
  seq,
59
84
  active_input: z.string(),
60
85
  mode: inputModeSchema,
@@ -63,21 +88,21 @@ export const switchEventSchema = z.object({
63
88
  });
64
89
  /** `device` event — a GstDeviceMonitor hotplug add/remove. */
65
90
  export const deviceEventSchema = z.object({
66
- type: z.literal("device"),
91
+ type: z.literal('device'),
67
92
  seq,
68
- change: z.enum(["added", "removed"]),
93
+ change: z.enum(['added', 'removed']),
69
94
  device: captureDeviceSchema,
70
95
  });
71
96
  /** `bitrate` event — the adaptive controller adjusted the encode bitrate. */
72
97
  export const bitrateEventSchema = z.object({
73
- type: z.literal("bitrate"),
98
+ type: z.literal('bitrate'),
74
99
  seq,
75
100
  current_bitrate: z.number().int(),
76
101
  max_bitrate: z.number().int(),
77
102
  });
78
103
  /** `srt-stats` event — periodic SRT transport telemetry. */
79
104
  export const srtStatsEventSchema = z.object({
80
- type: z.literal("srt-stats"),
105
+ type: z.literal('srt-stats'),
81
106
  seq,
82
107
  rtt_ms: z.number(),
83
108
  send_buffer: z.number().int(),
@@ -88,7 +113,7 @@ export const srtStatsEventSchema = z.object({
88
113
  * code; the engine reports facts and CeraUI decides what to surface.
89
114
  */
90
115
  export const runtimeErrorEventSchema = z.object({
91
- type: z.literal("error"),
116
+ type: z.literal('error'),
92
117
  seq,
93
118
  code: processErrorCodeSchema, // Tier 2 (errors.ts)
94
119
  source: processErrorSourceSchema,
@@ -97,7 +122,7 @@ export const runtimeErrorEventSchema = z.object({
97
122
  });
98
123
  /** `preview` event — a preview-session lifecycle/phase change. */
99
124
  export const previewEventSchema = z.object({
100
- type: z.literal("preview"),
125
+ type: z.literal('preview'),
101
126
  seq,
102
127
  session_id: z.string(),
103
128
  phase: z.string(),
@@ -113,12 +138,12 @@ export const previewEventSchema = z.object({
113
138
  * Independent of the preview-scoped `audio-level` WebSocket frame.
114
139
  */
115
140
  export const audioLevelEventSchema = z.object({
116
- type: z.literal("audio-level"),
141
+ type: z.literal('audio-level'),
117
142
  seq,
118
143
  source: z
119
144
  .object({
120
145
  identity: z.string().optional(), // reboot-stable device id (Todo 20 stable_id)
121
- owner: z.enum(["sidecar", "streaming"]),
146
+ owner: z.enum(['sidecar', 'streaming']),
122
147
  })
123
148
  .optional(),
124
149
  channels: z.number().int().nonnegative().optional(),
@@ -126,7 +151,7 @@ export const audioLevelEventSchema = z.object({
126
151
  peak_db: z.array(z.number()).optional(),
127
152
  floor_db: z.number().optional(),
128
153
  unavailable: z.literal(true).optional(),
129
- reason: z.enum(["device_busy", "no_device", "mode_none", "handoff"]).optional(),
154
+ reason: z.enum(['device_busy', 'no_device', 'mode_none', 'handoff']).optional(),
130
155
  });
131
156
  /**
132
157
  * `config-change` event — one phase of a `change-config` transaction (0.10.0,
@@ -137,14 +162,14 @@ export const audioLevelEventSchema = z.object({
137
162
  * actually advancing", never merely "PLAYING".
138
163
  */
139
164
  export const configChangeEventSchema = z.object({
140
- type: z.literal("config-change"),
165
+ type: z.literal('config-change'),
141
166
  seq,
142
167
  attempt_id: z.string(),
143
168
  phase: configChangePhaseSchema,
144
169
  reason: z.string().optional(), // absent on applying/applied; "teardown_timeout" marks the supervisor escalation
145
170
  });
146
171
  /** Discriminated union of every v1 event payload (the inner `params`). */
147
- export const eventParamsSchema = z.discriminatedUnion("type", [
172
+ export const eventParamsSchema = z.discriminatedUnion('type', [
148
173
  statusEventSchema,
149
174
  switchEventSchema,
150
175
  deviceEventSchema,
@@ -157,23 +182,23 @@ export const eventParamsSchema = z.discriminatedUnion("type", [
157
182
  ]);
158
183
  /** Full event envelope: { jsonrpc, method:"event", params } with typed params. */
159
184
  export const cerastreamEventSchema = z.object({
160
- jsonrpc: z.literal("2.0"),
161
- method: z.literal("event"),
185
+ jsonrpc: z.literal('2.0'),
186
+ method: z.literal('event'),
162
187
  params: eventParamsSchema,
163
188
  });
164
189
  /** The nine event topics (schema.md "Events" table) — count-assertion source.
165
190
  * `audio-level` (Todo 21) and `config-change` (Todo 9) are additive and appended
166
191
  * last, preserving the order of every prior topic. */
167
192
  export const EVENT_TOPICS = [
168
- "status",
169
- "switch",
170
- "device",
171
- "bitrate",
172
- "srt-stats",
173
- "error",
174
- "preview",
175
- "audio-level",
176
- "config-change",
193
+ 'status',
194
+ 'switch',
195
+ 'device',
196
+ 'bitrate',
197
+ 'srt-stats',
198
+ 'error',
199
+ 'preview',
200
+ 'audio-level',
201
+ 'config-change',
177
202
  ];
178
203
  /** topic → payload Zod schema. Tests assert every topic is represented here. */
179
204
  export const eventSchemas = {
@@ -181,9 +206,9 @@ export const eventSchemas = {
181
206
  switch: switchEventSchema,
182
207
  device: deviceEventSchema,
183
208
  bitrate: bitrateEventSchema,
184
- "srt-stats": srtStatsEventSchema,
209
+ 'srt-stats': srtStatsEventSchema,
185
210
  error: runtimeErrorEventSchema,
186
211
  preview: previewEventSchema,
187
- "audio-level": audioLevelEventSchema,
188
- "config-change": configChangeEventSchema,
212
+ 'audio-level': audioLevelEventSchema,
213
+ 'config-change': configChangeEventSchema,
189
214
  };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- export * from "./constants.js";
2
- export * from "./errors.js";
3
- export * from "./envelope.js";
4
- export * from "./types.js";
5
- export * from "./messages.js";
6
- export * from "./events.js";
7
- export * from "./paths.js";
8
- export * from "./config.js";
9
- export * from "./client.js";
1
+ export * from './client.js';
2
+ export * from './config.js';
3
+ export * from './constants.js';
4
+ export * from './envelope.js';
5
+ export * from './errors.js';
6
+ export * from './events.js';
7
+ export * from './messages.js';
8
+ export * from './paths.js';
9
+ export * from './types.js';
package/dist/index.js CHANGED
@@ -2,12 +2,12 @@
2
2
  // Rust streaming engine. The Zod schemas + types are the frozen public contract
3
3
  // (ADR-0002 / schema.md); the client drives that contract over a Bun-native
4
4
  // NDJSON/UDS transport (Task 31).
5
- export * from "./constants.js";
6
- export * from "./errors.js";
7
- export * from "./envelope.js";
8
- export * from "./types.js";
9
- export * from "./messages.js";
10
- export * from "./events.js";
11
- export * from "./paths.js";
12
- export * from "./config.js";
13
- export * from "./client.js";
5
+ export * from './client.js';
6
+ export * from './config.js';
7
+ export * from './constants.js';
8
+ export * from './envelope.js';
9
+ export * from './errors.js';
10
+ export * from './events.js';
11
+ export * from './messages.js';
12
+ export * from './paths.js';
13
+ export * from './types.js';