@ceralive/cerastream 2026.9.4 → 2026.9.5

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 CHANGED
@@ -9,6 +9,7 @@ engine's JSON-RPC 2.0 / NDJSON control plane over a Unix domain socket.
9
9
  - The nine server-push event payloads (discriminated union)
10
10
  - Two-tier error codes (RPC + runtime)
11
11
  - Typed capture-probe causes retained on runtime events and rejected-start exceptions
12
+ (including HDMI `unsupported-format`, `interlaced-unsupported`, `source-changed`)
12
13
  - Typed platform capture-converter reporting (`librga`, `v4l2-rga2`, or `none`)
13
14
  - Typed RK3588 composition config (secondary input, six PiP/PbP layouts, alpha),
14
15
  gated by the READY-trialled `composition` capability token
@@ -18,6 +19,9 @@ engine's JSON-RPC 2.0 / NDJSON control plane over a Unix domain socket.
18
19
  local preview availability
19
20
  - Per-codec encoder capability entries with format, resolution/framerate, and
20
21
  explicit 4K60 qualification-gate truth
22
+ - Additive `client.setEdidProfile()` — switch the HDMI-RX EDID between the named
23
+ `full` / `robust-4k60` profiles as one transaction: written, byte-verified,
24
+ persisted, then the device projection re-read only after the link settles
21
25
  - Additive `client.changeConfig()` — reconfigure the live session (resolution,
22
26
  framerate, codec, pipeline, source) as one transaction with typed rollback;
23
27
  composition-only changes use live layout/alpha writes and secondary rebind
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 ChangeConfigParams, type ChangeConfigResult, type GetCapabilitiesResult, type ListDevicesParams, type ListDevicesResult, type PreviewSessionParams, type PreviewSessionResult, type ReloadConfigParams, type ReloadConfigResult, type RequestKeyframeResult, 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 RequestKeyframeResult, type SetBitrateParams, type SetBitrateResult, type SetEdidProfileParams, type SetEdidProfileResult, 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. */
@@ -65,6 +65,16 @@ export interface CerastreamClient {
65
65
  */
66
66
  setBitrate(params: SetBitrateParams): Promise<SetBitrateResult>;
67
67
  requestKeyframe(): Promise<RequestKeyframeResult>;
68
+ /**
69
+ * Switch the HDMI-RX EDID profile transactionally: write, byte-verify,
70
+ * persist, then re-read the device projection once the link has settled.
71
+ * @param params The profile to advertise.
72
+ * @returns The committed profile, the one it replaced, and the post-settle devices.
73
+ * @throws {CerastreamRpcError} `cerastream.params.invalid` prefixed
74
+ * `capture-active` while any capture leg is live — including when the driver
75
+ * itself refuses the write — and `hdmirx-unavailable` on a board with no receiver.
76
+ */
77
+ setEdidProfile(params: SetEdidProfileParams): Promise<SetEdidProfileResult>;
68
78
  /**
69
79
  * Switch the active capture source (manual) or hand selection to failover (auto).
70
80
  * @param params The target input id and switch mode.
package/dist/client.js CHANGED
@@ -3,7 +3,7 @@ import { CONTROL_SOCKET_PATH, PROTOCOL_VERSION } from './constants.js';
3
3
  import { helloResultSchema, rpcErrorSchema, rpcResponseSchema, } from './envelope.js';
4
4
  import { CerastreamConnectionError, CerastreamRpcError, CerastreamTimeoutError, } from './errors.js';
5
5
  import { eventParamsSchema } from './events.js';
6
- import { changeConfigParamsSchema, changeConfigResultSchema, getCapabilitiesResultSchema, requestKeyframeResultSchema, requestSchemas, } from './messages.js';
6
+ import { changeConfigParamsSchema, changeConfigResultSchema, getCapabilitiesResultSchema, requestKeyframeResultSchema, requestSchemas, setEdidProfileResultSchema, } from './messages.js';
7
7
  import { controlSocketPath } from './paths.js';
8
8
  import { LineSocket } from './transport.js';
9
9
  const DEFAULTS = {
@@ -73,6 +73,9 @@ class ClientImpl {
73
73
  async requestKeyframe() {
74
74
  return requestKeyframeResultSchema.parse(await this.rawRequest('request-keyframe', {}));
75
75
  }
76
+ async setEdidProfile(params) {
77
+ return setEdidProfileResultSchema.parse(await this.rawRequest('hdmirx.setEdidProfile', params));
78
+ }
76
79
  switchInput(params) {
77
80
  return this.call('switch-input', params);
78
81
  }
@@ -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.16.0';
11
+ export declare const SCHEMA_VERSION: '0.17.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.16.0';
14
+ export const SCHEMA_VERSION = '0.17.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/errors.d.ts CHANGED
@@ -99,11 +99,14 @@ export declare const captureCauseSchema: z.ZodEnum<{
99
99
  "composition-unsupported": "composition-unsupported";
100
100
  "decoder-unavailable": "decoder-unavailable";
101
101
  device_busy: "device_busy";
102
+ "interlaced-unsupported": "interlaced-unsupported";
102
103
  negotiation_failed: "negotiation_failed";
103
104
  no_signal: "no_signal";
104
105
  no_silicon_converter: "no_silicon_converter";
105
106
  "secondary-unavailable": "secondary-unavailable";
106
107
  "software-pixel-path-rejected": "software-pixel-path-rejected";
108
+ "source-changed": "source-changed";
109
+ "unsupported-format": "unsupported-format";
107
110
  }>;
108
111
  export type CaptureCause = z.infer<typeof captureCauseSchema>;
109
112
  export declare const captureCauseEntrySchema: z.ZodObject<{
@@ -112,11 +115,14 @@ export declare const captureCauseEntrySchema: z.ZodObject<{
112
115
  "composition-unsupported": "composition-unsupported";
113
116
  "decoder-unavailable": "decoder-unavailable";
114
117
  device_busy: "device_busy";
118
+ "interlaced-unsupported": "interlaced-unsupported";
115
119
  negotiation_failed: "negotiation_failed";
116
120
  no_signal: "no_signal";
117
121
  no_silicon_converter: "no_silicon_converter";
118
122
  "secondary-unavailable": "secondary-unavailable";
119
123
  "software-pixel-path-rejected": "software-pixel-path-rejected";
124
+ "source-changed": "source-changed";
125
+ "unsupported-format": "unsupported-format";
120
126
  }>;
121
127
  }, z.core.$strip>;
122
128
  export type CaptureCauseEntry = z.infer<typeof captureCauseEntrySchema>;
package/dist/errors.js CHANGED
@@ -147,6 +147,9 @@ export const captureCauseSchema = z.enum([
147
147
  'software-pixel-path-rejected',
148
148
  'composition-unsupported',
149
149
  'secondary-unavailable',
150
+ 'unsupported-format',
151
+ 'interlaced-unsupported',
152
+ 'source-changed',
150
153
  ]);
151
154
  export const captureCauseEntrySchema = z.object({
152
155
  device: z.string(),
package/dist/events.d.ts CHANGED
@@ -243,11 +243,14 @@ export declare const runtimeErrorEventSchema: z.ZodObject<{
243
243
  "composition-unsupported": "composition-unsupported";
244
244
  "decoder-unavailable": "decoder-unavailable";
245
245
  device_busy: "device_busy";
246
+ "interlaced-unsupported": "interlaced-unsupported";
246
247
  negotiation_failed: "negotiation_failed";
247
248
  no_signal: "no_signal";
248
249
  no_silicon_converter: "no_silicon_converter";
249
250
  "secondary-unavailable": "secondary-unavailable";
250
251
  "software-pixel-path-rejected": "software-pixel-path-rejected";
252
+ "source-changed": "source-changed";
253
+ "unsupported-format": "unsupported-format";
251
254
  }>>;
252
255
  }, z.core.$strip>;
253
256
  /** Payload of a {@link runtimeErrorEventSchema} event. */
@@ -471,11 +474,14 @@ export declare const eventParamsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
471
474
  "composition-unsupported": "composition-unsupported";
472
475
  "decoder-unavailable": "decoder-unavailable";
473
476
  device_busy: "device_busy";
477
+ "interlaced-unsupported": "interlaced-unsupported";
474
478
  negotiation_failed: "negotiation_failed";
475
479
  no_signal: "no_signal";
476
480
  no_silicon_converter: "no_silicon_converter";
477
481
  "secondary-unavailable": "secondary-unavailable";
478
482
  "software-pixel-path-rejected": "software-pixel-path-rejected";
483
+ "source-changed": "source-changed";
484
+ "unsupported-format": "unsupported-format";
479
485
  }>>;
480
486
  }, z.core.$strip>, z.ZodObject<{
481
487
  type: z.ZodLiteral<"preview">;
@@ -673,11 +679,14 @@ export declare const cerastreamEventSchema: z.ZodObject<{
673
679
  "composition-unsupported": "composition-unsupported";
674
680
  "decoder-unavailable": "decoder-unavailable";
675
681
  device_busy: "device_busy";
682
+ "interlaced-unsupported": "interlaced-unsupported";
676
683
  negotiation_failed: "negotiation_failed";
677
684
  no_signal: "no_signal";
678
685
  no_silicon_converter: "no_silicon_converter";
679
686
  "secondary-unavailable": "secondary-unavailable";
680
687
  "software-pixel-path-rejected": "software-pixel-path-rejected";
688
+ "source-changed": "source-changed";
689
+ "unsupported-format": "unsupported-format";
681
690
  }>>;
682
691
  }, z.core.$strip>, z.ZodObject<{
683
692
  type: z.ZodLiteral<"preview">;
@@ -884,11 +893,14 @@ export declare const eventSchemas: {
884
893
  "composition-unsupported": "composition-unsupported";
885
894
  "decoder-unavailable": "decoder-unavailable";
886
895
  device_busy: "device_busy";
896
+ "interlaced-unsupported": "interlaced-unsupported";
887
897
  negotiation_failed: "negotiation_failed";
888
898
  no_signal: "no_signal";
889
899
  no_silicon_converter: "no_silicon_converter";
890
900
  "secondary-unavailable": "secondary-unavailable";
891
901
  "software-pixel-path-rejected": "software-pixel-path-rejected";
902
+ "source-changed": "source-changed";
903
+ "unsupported-format": "unsupported-format";
892
904
  }>>;
893
905
  }, z.core.$strip>;
894
906
  readonly preview: z.ZodObject<{
@@ -179,6 +179,97 @@ export declare const requestKeyframeResultSchema: z.ZodObject<{
179
179
  applied: z.ZodLiteral<true>;
180
180
  }, z.core.$strip>;
181
181
  export type RequestKeyframeResult = z.infer<typeof requestKeyframeResultSchema>;
182
+ export declare const edidProfileSchema: z.ZodEnum<{
183
+ full: "full";
184
+ "robust-4k60": "robust-4k60";
185
+ }>;
186
+ export type EdidProfile = z.infer<typeof edidProfileSchema>;
187
+ export declare const setEdidProfileParamsSchema: z.ZodObject<{
188
+ profile: z.ZodEnum<{
189
+ full: "full";
190
+ "robust-4k60": "robust-4k60";
191
+ }>;
192
+ }, z.core.$strip>;
193
+ export type SetEdidProfileParams = z.infer<typeof setEdidProfileParamsSchema>;
194
+ export declare const edidSettleOutcomeSchema: z.ZodEnum<{
195
+ "no-signal": "no-signal";
196
+ relocked: "relocked";
197
+ unknown: "unknown";
198
+ }>;
199
+ export type EdidSettleOutcome = z.infer<typeof edidSettleOutcomeSchema>;
200
+ export declare const setEdidProfileResultSchema: z.ZodObject<{
201
+ profile: z.ZodEnum<{
202
+ full: "full";
203
+ "robust-4k60": "robust-4k60";
204
+ }>;
205
+ previous: z.ZodEnum<{
206
+ full: "full";
207
+ "robust-4k60": "robust-4k60";
208
+ }>;
209
+ applied: z.ZodLiteral<true>;
210
+ settle: z.ZodEnum<{
211
+ "no-signal": "no-signal";
212
+ relocked: "relocked";
213
+ unknown: "unknown";
214
+ }>;
215
+ devices: z.ZodArray<z.ZodObject<{
216
+ input_id: z.ZodString;
217
+ device_path: z.ZodString;
218
+ display_name: z.ZodString;
219
+ media_class: z.ZodEnum<{
220
+ audio: "audio";
221
+ video: "video";
222
+ }>;
223
+ caps: z.ZodOptional<z.ZodArray<z.ZodObject<{
224
+ width: z.ZodOptional<z.ZodNumber>;
225
+ height: z.ZodOptional<z.ZodNumber>;
226
+ framerate: z.ZodOptional<z.ZodString>;
227
+ media_type: z.ZodOptional<z.ZodString>;
228
+ }, z.core.$strip>>>;
229
+ kind: z.ZodOptional<z.ZodEnum<{
230
+ audio: "audio";
231
+ camlink: "camlink";
232
+ hdmi: "hdmi";
233
+ mjpeg: "mjpeg";
234
+ network: "network";
235
+ test: "test";
236
+ uvc_h264: "uvc_h264";
237
+ uvc_h265: "uvc_h265";
238
+ }>>;
239
+ modes: z.ZodOptional<z.ZodArray<z.ZodObject<{
240
+ media_type: z.ZodString;
241
+ pipeline_kind: z.ZodEnum<{
242
+ audio: "audio";
243
+ camlink: "camlink";
244
+ hdmi: "hdmi";
245
+ mjpeg: "mjpeg";
246
+ network: "network";
247
+ test: "test";
248
+ uvc_h264: "uvc_h264";
249
+ uvc_h265: "uvc_h265";
250
+ }>;
251
+ caps: z.ZodArray<z.ZodObject<{
252
+ width: z.ZodOptional<z.ZodNumber>;
253
+ height: z.ZodOptional<z.ZodNumber>;
254
+ framerate: z.ZodOptional<z.ZodString>;
255
+ media_type: z.ZodOptional<z.ZodString>;
256
+ }, z.core.$strip>>;
257
+ }, z.core.$strip>>>;
258
+ alsa_card_id: z.ZodOptional<z.ZodString>;
259
+ product_name: z.ZodOptional<z.ZodString>;
260
+ transport: z.ZodOptional<z.ZodEnum<{
261
+ bluetooth: "bluetooth";
262
+ hdmi: "hdmi";
263
+ onboard: "onboard";
264
+ usb: "usb";
265
+ }>>;
266
+ stable_id: z.ZodOptional<z.ZodString>;
267
+ physical_group_id: z.ZodOptional<z.ZodString>;
268
+ hardware_serial: z.ZodOptional<z.ZodString>;
269
+ device_address: z.ZodOptional<z.ZodString>;
270
+ }, z.core.$strip>>;
271
+ }, z.core.$strip>;
272
+ export type SetEdidProfileResult = z.infer<typeof setEdidProfileResultSchema>;
182
273
  export declare const switchInputParamsSchema: z.ZodObject<{
183
274
  input_id: z.ZodString;
184
275
  mode: z.ZodDefault<z.ZodEnum<{
package/dist/messages.js CHANGED
@@ -74,6 +74,23 @@ export const setBitrateResultSchema = z.object({
74
74
  });
75
75
  export const requestKeyframeParamsSchema = z.object({});
76
76
  export const requestKeyframeResultSchema = z.object({ applied: z.literal(true) });
77
+ // ---- 4b. hdmirx.setEdidProfile (additive, 0.17.0; not in V1_METHODS) ----
78
+ // The operator picks a named POLICY, never a blob: an EDID is a checksummed
79
+ // 256-byte structure whose contents the device owns.
80
+ export const edidProfileSchema = z.enum(['full', 'robust-4k60']);
81
+ export const setEdidProfileParamsSchema = z.object({ profile: edidProfileSchema });
82
+ // How the receiver settled before `devices` below was re-read, so a consumer can
83
+ // tell "relocked and here are its real modes" from "the link is dark".
84
+ export const edidSettleOutcomeSchema = z.enum(['relocked', 'no-signal', 'unknown']);
85
+ export const setEdidProfileResultSchema = z.object({
86
+ profile: edidProfileSchema,
87
+ previous: edidProfileSchema,
88
+ // Always true: a non-applied attempt is an RPC error, never this result.
89
+ applied: z.literal(true),
90
+ settle: edidSettleOutcomeSchema,
91
+ // The POST-SETTLE list-devices projection — never the pre-switch mode list.
92
+ devices: z.array(captureDeviceSchema),
93
+ });
77
94
  // ---- 5. switch-input ----
78
95
  export const switchInputParamsSchema = z.object({
79
96
  input_id: z.string(), // device/input identifier from list-devices
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceralive/cerastream",
3
- "version": "2026.9.4",
3
+ "version": "2026.9.5",
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",