@camstack/addon-decoder-ffmpeg 1.2.1 → 1.2.3

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/index.js CHANGED
@@ -11031,7 +11031,8 @@ var PipelineStepInputSchema = lazy(() => object({
11031
11031
  modelId: string().optional(),
11032
11032
  enabled: boolean().default(true),
11033
11033
  children: array(PipelineStepInputSchema).optional(),
11034
- settings: record(string(), unknown()).optional()
11034
+ settings: record(string(), unknown()).optional(),
11035
+ jumpDeviceKey: string().optional()
11035
11036
  }));
11036
11037
  var ModelSubstitutionSchema = object({
11037
11038
  addonId: string(),
@@ -11337,8 +11338,24 @@ var NativeCropBboxSchema = object({
11337
11338
  });
11338
11339
  /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
11339
11340
  var NativeCropResultSchema = object({
11340
- /** Packed rgb (24-bit) pixels of the crop. */
11341
- bytes: _instanceof(Uint8Array),
11341
+ /**
11342
+ * Packed rgb (24-bit) pixels of the crop. Present on the DEFAULT (raw) path —
11343
+ * same-node (in-process / UDS) callers get zero-copy RGB and encode locally.
11344
+ * OMITTED when the caller requested `encodeJpeg` (the cross-node compressed
11345
+ * path below), where shipping raw RGB is both an invariant violation and, for
11346
+ * a native full frame (~26 MB at 4K), larger than Moleculer's 10 MB
11347
+ * `maxPacketSize` → the packet is dropped and the call 60s-times-out. That is
11348
+ * the cross-node native-media miss: `bytes` is replaced by `jpeg`.
11349
+ */
11350
+ bytes: _instanceof(Uint8Array).optional(),
11351
+ /**
11352
+ * Base64 JPEG of the crop — the COMPRESSED cross-node payload. The OWNING node
11353
+ * (which holds the native surface) encodes it in-process, so a native 4K frame
11354
+ * ships as ~0.5–2 MB (well under `maxPacketSize`) and NO raw pixels ever cross
11355
+ * a process boundary (CLAUDE.md invariant #21). Present ONLY when the request
11356
+ * set `encodeJpeg: true`; `bytes` is then absent.
11357
+ */
11358
+ jpeg: string().optional(),
11342
11359
  width: number().int().positive(),
11343
11360
  height: number().int().positive(),
11344
11361
  /**
@@ -11484,6 +11501,20 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
11484
11501
  hubHostnameOverride: string().optional()
11485
11502
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
11486
11503
  /**
11504
+ * One ENABLED inference device on the runner's node, as the step-tree
11505
+ * device-jump resolver sees it (phase 1). The orchestrator populates this
11506
+ * roster on the attach payload whenever the camera is elected onto a specific
11507
+ * `deviceKey` and the node has ≥2 enabled devices — it is the candidate set the
11508
+ * runner auto-jumps an enrichment step to when the elected device's format
11509
+ * cannot run that step's model. `weight`/`maxSessions` mirror the balancer's
11510
+ * per-device knobs so the auto choice is weighted-least-loaded.
11511
+ */
11512
+ var RunnerInferenceDeviceSchema = object({
11513
+ deviceKey: string(),
11514
+ weight: number().positive().default(1),
11515
+ maxSessions: number().int().positive().nullable().default(null)
11516
+ });
11517
+ /**
11487
11518
  * Camera assignment payload sent by `addon-pipeline-orchestrator` to a
11488
11519
  * specific runner instance via `attachCamera`. Carries everything the
11489
11520
  * runner needs to subscribe to the local broker and execute inference.
@@ -11601,7 +11632,16 @@ var RunnerCameraConfigSchema = object({
11601
11632
  * omitted ⇒ the runner's default device. The engine itself stays node-local —
11602
11633
  * this only selects WHICH device pool of that node runs the session.
11603
11634
  */
11604
- deviceKey: string().optional()
11635
+ deviceKey: string().optional(),
11636
+ /**
11637
+ * Step-tree device-jump roster (phase 1): the node's ENABLED inference
11638
+ * devices, populated by the orchestrator ONLY when `deviceKey` is set and the
11639
+ * node has ≥2 enabled devices. The runner uses it to AUTO-jump an enrichment
11640
+ * step whose model has no build for the elected device's format onto another
11641
+ * enabled device of the SAME node (weighted-least-loaded). Absent/single-entry
11642
+ * ⇒ no jump possible; the step runs on `deviceKey`.
11643
+ */
11644
+ inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
11605
11645
  });
11606
11646
  motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
11607
11647
  /**
@@ -11657,7 +11697,18 @@ var RunnerLocalMetricsSchema = object({
11657
11697
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
11658
11698
  handle: FrameHandleSchema,
11659
11699
  bbox: NativeCropBboxSchema,
11660
- maxWidth: number().int().positive().optional()
11700
+ maxWidth: number().int().positive().optional(),
11701
+ /**
11702
+ * When `true`, the runner encodes the resolved crop to JPEG ON THE
11703
+ * OWNING NODE and returns it in `jpeg` (base64) INSTEAD of raw `bytes`.
11704
+ * Callers set this for CROSS-NODE fetches (`handle.nodeId` is a remote
11705
+ * agent) so the compressed payload fits Moleculer's `maxPacketSize` and
11706
+ * no raw pixels cross the process boundary. Same-node callers omit it
11707
+ * and keep the zero-copy raw `bytes` path. Additive + optional: a
11708
+ * pre-encode runner (version skew) ignores it and returns `bytes`, so
11709
+ * the caller falls back to encoding locally.
11710
+ */
11711
+ encodeJpeg: boolean().optional()
11661
11712
  }), NativeCropResultSchema.nullable()), method(object({
11662
11713
  deviceId: number(),
11663
11714
  frameHandle: FrameHandleSchema.optional(),
@@ -16585,7 +16636,8 @@ var MediaFileKindEnum = _enum([
16585
16636
  "faceCrop",
16586
16637
  "plateCrop",
16587
16638
  "keyFrame",
16588
- "keyFrameSmall"
16639
+ "keyFrameSmall",
16640
+ "thumbnailSmall"
16589
16641
  ]);
16590
16642
  var MediaFileSchema = object({
16591
16643
  key: string(),
@@ -16916,7 +16968,16 @@ var PipelineTemplateSchema = object({
16916
16968
  });
16917
16969
  var DeviceStepConfigSchema = object({
16918
16970
  modelId: string().optional(),
16919
- settings: record(string(), unknown()).optional()
16971
+ settings: record(string(), unknown()).optional(),
16972
+ /**
16973
+ * Step-tree device jump (same-node, phase 1) — OPTIONAL manual override.
16974
+ * When set, this step runs on the named enabled device of the SAME node
16975
+ * (`<backend>:<device>`) instead of the camera's elected device, bypassing
16976
+ * the runtime AUTO-jump. The orchestrator rejects a `jumpDeviceKey` pointing
16977
+ * at a disabled/absent device on that node at save time. Absent ⇒ the runner
16978
+ * auto-jumps only when the effective device's format cannot run the step.
16979
+ */
16980
+ jumpDeviceKey: string().optional()
16920
16981
  });
16921
16982
  var AgentPipelineSettingsSchema = object({
16922
16983
  maxCameras: number().int().nonnegative().nullable().default(null),
package/dist/index.mjs CHANGED
@@ -11027,7 +11027,8 @@ var PipelineStepInputSchema = lazy(() => object({
11027
11027
  modelId: string().optional(),
11028
11028
  enabled: boolean().default(true),
11029
11029
  children: array(PipelineStepInputSchema).optional(),
11030
- settings: record(string(), unknown()).optional()
11030
+ settings: record(string(), unknown()).optional(),
11031
+ jumpDeviceKey: string().optional()
11031
11032
  }));
11032
11033
  var ModelSubstitutionSchema = object({
11033
11034
  addonId: string(),
@@ -11333,8 +11334,24 @@ var NativeCropBboxSchema = object({
11333
11334
  });
11334
11335
  /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
11335
11336
  var NativeCropResultSchema = object({
11336
- /** Packed rgb (24-bit) pixels of the crop. */
11337
- bytes: _instanceof(Uint8Array),
11337
+ /**
11338
+ * Packed rgb (24-bit) pixels of the crop. Present on the DEFAULT (raw) path —
11339
+ * same-node (in-process / UDS) callers get zero-copy RGB and encode locally.
11340
+ * OMITTED when the caller requested `encodeJpeg` (the cross-node compressed
11341
+ * path below), where shipping raw RGB is both an invariant violation and, for
11342
+ * a native full frame (~26 MB at 4K), larger than Moleculer's 10 MB
11343
+ * `maxPacketSize` → the packet is dropped and the call 60s-times-out. That is
11344
+ * the cross-node native-media miss: `bytes` is replaced by `jpeg`.
11345
+ */
11346
+ bytes: _instanceof(Uint8Array).optional(),
11347
+ /**
11348
+ * Base64 JPEG of the crop — the COMPRESSED cross-node payload. The OWNING node
11349
+ * (which holds the native surface) encodes it in-process, so a native 4K frame
11350
+ * ships as ~0.5–2 MB (well under `maxPacketSize`) and NO raw pixels ever cross
11351
+ * a process boundary (CLAUDE.md invariant #21). Present ONLY when the request
11352
+ * set `encodeJpeg: true`; `bytes` is then absent.
11353
+ */
11354
+ jpeg: string().optional(),
11338
11355
  width: number().int().positive(),
11339
11356
  height: number().int().positive(),
11340
11357
  /**
@@ -11480,6 +11497,20 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
11480
11497
  hubHostnameOverride: string().optional()
11481
11498
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
11482
11499
  /**
11500
+ * One ENABLED inference device on the runner's node, as the step-tree
11501
+ * device-jump resolver sees it (phase 1). The orchestrator populates this
11502
+ * roster on the attach payload whenever the camera is elected onto a specific
11503
+ * `deviceKey` and the node has ≥2 enabled devices — it is the candidate set the
11504
+ * runner auto-jumps an enrichment step to when the elected device's format
11505
+ * cannot run that step's model. `weight`/`maxSessions` mirror the balancer's
11506
+ * per-device knobs so the auto choice is weighted-least-loaded.
11507
+ */
11508
+ var RunnerInferenceDeviceSchema = object({
11509
+ deviceKey: string(),
11510
+ weight: number().positive().default(1),
11511
+ maxSessions: number().int().positive().nullable().default(null)
11512
+ });
11513
+ /**
11483
11514
  * Camera assignment payload sent by `addon-pipeline-orchestrator` to a
11484
11515
  * specific runner instance via `attachCamera`. Carries everything the
11485
11516
  * runner needs to subscribe to the local broker and execute inference.
@@ -11597,7 +11628,16 @@ var RunnerCameraConfigSchema = object({
11597
11628
  * omitted ⇒ the runner's default device. The engine itself stays node-local —
11598
11629
  * this only selects WHICH device pool of that node runs the session.
11599
11630
  */
11600
- deviceKey: string().optional()
11631
+ deviceKey: string().optional(),
11632
+ /**
11633
+ * Step-tree device-jump roster (phase 1): the node's ENABLED inference
11634
+ * devices, populated by the orchestrator ONLY when `deviceKey` is set and the
11635
+ * node has ≥2 enabled devices. The runner uses it to AUTO-jump an enrichment
11636
+ * step whose model has no build for the elected device's format onto another
11637
+ * enabled device of the SAME node (weighted-least-loaded). Absent/single-entry
11638
+ * ⇒ no jump possible; the step runs on `deviceKey`.
11639
+ */
11640
+ inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
11601
11641
  });
11602
11642
  motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
11603
11643
  /**
@@ -11653,7 +11693,18 @@ var RunnerLocalMetricsSchema = object({
11653
11693
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
11654
11694
  handle: FrameHandleSchema,
11655
11695
  bbox: NativeCropBboxSchema,
11656
- maxWidth: number().int().positive().optional()
11696
+ maxWidth: number().int().positive().optional(),
11697
+ /**
11698
+ * When `true`, the runner encodes the resolved crop to JPEG ON THE
11699
+ * OWNING NODE and returns it in `jpeg` (base64) INSTEAD of raw `bytes`.
11700
+ * Callers set this for CROSS-NODE fetches (`handle.nodeId` is a remote
11701
+ * agent) so the compressed payload fits Moleculer's `maxPacketSize` and
11702
+ * no raw pixels cross the process boundary. Same-node callers omit it
11703
+ * and keep the zero-copy raw `bytes` path. Additive + optional: a
11704
+ * pre-encode runner (version skew) ignores it and returns `bytes`, so
11705
+ * the caller falls back to encoding locally.
11706
+ */
11707
+ encodeJpeg: boolean().optional()
11657
11708
  }), NativeCropResultSchema.nullable()), method(object({
11658
11709
  deviceId: number(),
11659
11710
  frameHandle: FrameHandleSchema.optional(),
@@ -16581,7 +16632,8 @@ var MediaFileKindEnum = _enum([
16581
16632
  "faceCrop",
16582
16633
  "plateCrop",
16583
16634
  "keyFrame",
16584
- "keyFrameSmall"
16635
+ "keyFrameSmall",
16636
+ "thumbnailSmall"
16585
16637
  ]);
16586
16638
  var MediaFileSchema = object({
16587
16639
  key: string(),
@@ -16912,7 +16964,16 @@ var PipelineTemplateSchema = object({
16912
16964
  });
16913
16965
  var DeviceStepConfigSchema = object({
16914
16966
  modelId: string().optional(),
16915
- settings: record(string(), unknown()).optional()
16967
+ settings: record(string(), unknown()).optional(),
16968
+ /**
16969
+ * Step-tree device jump (same-node, phase 1) — OPTIONAL manual override.
16970
+ * When set, this step runs on the named enabled device of the SAME node
16971
+ * (`<backend>:<device>`) instead of the camera's elected device, bypassing
16972
+ * the runtime AUTO-jump. The orchestrator rejects a `jumpDeviceKey` pointing
16973
+ * at a disabled/absent device on that node at save time. Absent ⇒ the runner
16974
+ * auto-jumps only when the effective device's format cannot run the step.
16975
+ */
16976
+ jumpDeviceKey: string().optional()
16916
16977
  });
16917
16978
  var AgentPipelineSettingsSchema = object({
16918
16979
  maxCameras: number().int().nonnegative().nullable().default(null),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-decoder-ffmpeg",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Standalone ffmpeg-subprocess decoder fallback addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",