@camstack/addon-pipeline 0.1.18 → 0.1.19
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/audio-analyzer/index.js +8 -3
- package/dist/audio-analyzer/index.js.map +1 -1
- package/dist/audio-analyzer/index.mjs +8 -3
- package/dist/audio-analyzer/index.mjs.map +1 -1
- package/dist/audio-codec-nodeav/index.js +1 -1
- package/dist/audio-codec-nodeav/index.mjs +1 -1
- package/dist/decoder-nodeav/index.js +1 -1
- package/dist/decoder-nodeav/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +23 -20
- package/dist/detection-pipeline/index.js.map +1 -1
- package/dist/detection-pipeline/index.mjs +23 -20
- package/dist/detection-pipeline/index.mjs.map +1 -1
- package/dist/{index-DLHaHm6u.js → index-BbPPvoCx.js} +414 -45
- package/dist/index-BbPPvoCx.js.map +1 -0
- package/dist/{index-asZs8U_s.mjs → index-Bmlkm0Fd.mjs} +414 -45
- package/dist/index-Bmlkm0Fd.mjs.map +1 -0
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +132 -14
- package/dist/pipeline-runner/index.js.map +1 -1
- package/dist/pipeline-runner/index.mjs +133 -15
- package/dist/pipeline-runner/index.mjs.map +1 -1
- package/dist/stream-broker/@mf-types.zip +0 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-NjF4kxzW.mjs +19 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BAv_5ISf.mjs +20 -0
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-DAssX3h0.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-BsB2G7oY.mjs} +2 -1
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-DFoJJhpt.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-xrRiPUpA.mjs} +1 -1
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-x7XMEeuJ.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-C0E2yCzO.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-3TxRVJ5L.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CupRlwqG.mjs} +6 -6
- package/dist/stream-broker/{client-CZXrddDR.mjs → client-NPZqorv9.mjs} +2 -2
- package/dist/stream-broker/{hostInit-De6APW25.mjs → hostInit-Bh4w7o5_.mjs} +12 -12
- package/dist/stream-broker/{index-C0BzaWmB.mjs → index-2Qp8vT3w.mjs} +1 -1
- package/dist/stream-broker/{index-CZNxa0ad.mjs → index-BBcZvb5t.mjs} +1 -1
- package/dist/stream-broker/index-CIJue-4t.mjs +37880 -0
- package/dist/stream-broker/{index-BvV3RVTZ.mjs → index-Cc6QBqMk.mjs} +2 -2
- package/dist/stream-broker/{index-cYW01SNH.mjs → index-D_1p2K9B.mjs} +1 -1
- package/dist/stream-broker/{index-CUXiTSWS.mjs → index-Dy2V7VOm.mjs} +3775 -3279
- package/dist/stream-broker/{index-KtR7Pp0O.mjs → index-mX3Kgiv1.mjs} +1 -1
- package/dist/stream-broker/index.js +1565 -280
- package/dist/stream-broker/index.js.map +1 -1
- package/dist/stream-broker/index.mjs +1567 -281
- package/dist/stream-broker/index.mjs.map +1 -1
- package/dist/stream-broker/{jsx-runtime-B_evVsXl.mjs → jsx-runtime-lb0mH5st.mjs} +1 -1
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/stream-broker/{schemas-ChN4Ih0h.mjs → schemas-ClCuS4qa.mjs} +151 -141
- package/package.json +1 -1
- package/dist/index-DLHaHm6u.js.map +0 -1
- package/dist/index-asZs8U_s.mjs.map +0 -1
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-d8PmLbO2.mjs +0 -19
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-B4l8Nb2y.mjs +0 -20
- package/dist/stream-broker/index-Kb4xa8FX.mjs +0 -36403
|
@@ -4778,6 +4778,16 @@ function record(keyType, valueType, params) {
|
|
|
4778
4778
|
...normalizeParams(params)
|
|
4779
4779
|
});
|
|
4780
4780
|
}
|
|
4781
|
+
function partialRecord(keyType, valueType, params) {
|
|
4782
|
+
const k = clone(keyType);
|
|
4783
|
+
k._zod.values = void 0;
|
|
4784
|
+
return new ZodRecord({
|
|
4785
|
+
type: "record",
|
|
4786
|
+
keyType: k,
|
|
4787
|
+
valueType,
|
|
4788
|
+
...normalizeParams(params)
|
|
4789
|
+
});
|
|
4790
|
+
}
|
|
4781
4791
|
const ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
|
|
4782
4792
|
$ZodEnum.init(inst, def);
|
|
4783
4793
|
ZodType.init(inst, def);
|
|
@@ -5054,6 +5064,37 @@ function _instanceof(cls, params = {}) {
|
|
|
5054
5064
|
};
|
|
5055
5065
|
return inst;
|
|
5056
5066
|
}
|
|
5067
|
+
const wiringProbeKindSchema = _enum(["singleton", "device", "widget"]);
|
|
5068
|
+
const wiringProbeResultSchema = object({
|
|
5069
|
+
capName: string(),
|
|
5070
|
+
kind: wiringProbeKindSchema,
|
|
5071
|
+
deviceId: number().optional(),
|
|
5072
|
+
reachable: boolean(),
|
|
5073
|
+
latencyMs: number(),
|
|
5074
|
+
error: string().optional()
|
|
5075
|
+
});
|
|
5076
|
+
const wiringAddonHealthSchema = object({
|
|
5077
|
+
addonId: string(),
|
|
5078
|
+
caps: array(wiringProbeResultSchema).readonly(),
|
|
5079
|
+
widgets: array(wiringProbeResultSchema).readonly()
|
|
5080
|
+
});
|
|
5081
|
+
const wiringNodeHealthSchema = object({
|
|
5082
|
+
nodeId: string(),
|
|
5083
|
+
addons: array(wiringAddonHealthSchema).readonly()
|
|
5084
|
+
});
|
|
5085
|
+
object({
|
|
5086
|
+
/** True only when every probed target is reachable. */
|
|
5087
|
+
ok: boolean(),
|
|
5088
|
+
/** True when at least one target is unreachable. */
|
|
5089
|
+
degraded: boolean(),
|
|
5090
|
+
checkedAt: string(),
|
|
5091
|
+
nodes: array(wiringNodeHealthSchema).readonly(),
|
|
5092
|
+
summary: object({
|
|
5093
|
+
total: number(),
|
|
5094
|
+
reachable: number(),
|
|
5095
|
+
unreachable: number()
|
|
5096
|
+
})
|
|
5097
|
+
});
|
|
5057
5098
|
const MODEL_FORMATS = ["onnx", "coreml", "openvino", "tflite", "pt"];
|
|
5058
5099
|
const WELL_KNOWN_TABS = [
|
|
5059
5100
|
{ id: "overview", label: "Overview", icon: "layout-dashboard", order: -10 },
|
|
@@ -6618,7 +6659,7 @@ const SpatialDetectionSchema = object({
|
|
|
6618
6659
|
bbox: BoundingBoxSchema
|
|
6619
6660
|
});
|
|
6620
6661
|
const AudioChunkInputSchema = object({
|
|
6621
|
-
data: _instanceof(
|
|
6662
|
+
data: _instanceof(Uint8Array),
|
|
6622
6663
|
sampleRate: number(),
|
|
6623
6664
|
channels: number(),
|
|
6624
6665
|
timestamp: number(),
|
|
@@ -7298,7 +7339,23 @@ const RunnerCameraConfigSchema = object({
|
|
|
7298
7339
|
* whenever its `zones` device-state slice changes, so the runner's
|
|
7299
7340
|
* copy stays in sync. Empty array → no zone filtering.
|
|
7300
7341
|
*/
|
|
7301
|
-
zones: array(ZoneSchema).readonly().default([])
|
|
7342
|
+
zones: array(ZoneSchema).readonly().default([]),
|
|
7343
|
+
/**
|
|
7344
|
+
* When true (default) and the camera's `motionSources` contains only
|
|
7345
|
+
* `'onboard'`, the runner dynamically opens the same WASM frame-diff
|
|
7346
|
+
* motion-frames subscription on each `MotionOnMotionChanged
|
|
7347
|
+
* source:'onboard'` event and tears it down after `motionCooldownMs`.
|
|
7348
|
+
* This causes `runMotionAnalysis` to emit `MotionZonesRaw` /
|
|
7349
|
+
* `MotionAnalysis` during active-motion windows without the
|
|
7350
|
+
* substream being held open continuously.
|
|
7351
|
+
*
|
|
7352
|
+
* Set to `false` to disable the dynamic analyzer for this camera
|
|
7353
|
+
* (e.g. very low-bandwidth links where the extra substream is
|
|
7354
|
+
* undesirable). Has no effect when `motionSources` already includes
|
|
7355
|
+
* `'analyzer'` — the analyzer runs continuously in that case and
|
|
7356
|
+
* this gate is bypassed.
|
|
7357
|
+
*/
|
|
7358
|
+
onboardMotionDrivesAnalyzer: boolean().default(true)
|
|
7302
7359
|
});
|
|
7303
7360
|
const RunnerLocalLoadSchema = object({
|
|
7304
7361
|
/** Moleculer node id of this runner instance. */
|
|
@@ -7438,22 +7495,68 @@ MotionTriggerStatusSchema.extend({
|
|
|
7438
7495
|
}) }
|
|
7439
7496
|
}
|
|
7440
7497
|
});
|
|
7498
|
+
const MaskPointSchema = object({
|
|
7499
|
+
x: number(),
|
|
7500
|
+
y: number()
|
|
7501
|
+
});
|
|
7502
|
+
const MaskRectShapeSchema = object({
|
|
7503
|
+
kind: literal("rect"),
|
|
7504
|
+
x: number(),
|
|
7505
|
+
y: number(),
|
|
7506
|
+
width: number(),
|
|
7507
|
+
height: number()
|
|
7508
|
+
});
|
|
7509
|
+
const MaskPolygonShapeSchema = object({
|
|
7510
|
+
kind: literal("polygon"),
|
|
7511
|
+
points: array(MaskPointSchema)
|
|
7512
|
+
});
|
|
7513
|
+
const MaskGridShapeSchema = object({
|
|
7514
|
+
kind: literal("grid"),
|
|
7515
|
+
gridWidth: number(),
|
|
7516
|
+
gridHeight: number(),
|
|
7517
|
+
cells: array(boolean())
|
|
7518
|
+
});
|
|
7519
|
+
const MaskLineShapeSchema = object({
|
|
7520
|
+
kind: literal("line"),
|
|
7521
|
+
points: array(MaskPointSchema)
|
|
7522
|
+
});
|
|
7523
|
+
discriminatedUnion("kind", [
|
|
7524
|
+
MaskRectShapeSchema,
|
|
7525
|
+
MaskPolygonShapeSchema,
|
|
7526
|
+
MaskGridShapeSchema,
|
|
7527
|
+
MaskLineShapeSchema
|
|
7528
|
+
]);
|
|
7529
|
+
const MaskShapeKindSchema = _enum(["rect", "polygon", "grid", "line"]);
|
|
7530
|
+
const MaskPolygonVerticesSchema = object({
|
|
7531
|
+
min: number(),
|
|
7532
|
+
max: number()
|
|
7533
|
+
});
|
|
7534
|
+
const MaskGridDimsSchema = object({
|
|
7535
|
+
width: number(),
|
|
7536
|
+
height: number()
|
|
7537
|
+
});
|
|
7538
|
+
const MotionZoneRegionSchema = object({
|
|
7539
|
+
id: number(),
|
|
7540
|
+
enabled: boolean(),
|
|
7541
|
+
shape: MaskGridShapeSchema
|
|
7542
|
+
});
|
|
7441
7543
|
object({
|
|
7442
7544
|
enabled: boolean(),
|
|
7443
7545
|
sensitivity: number(),
|
|
7444
|
-
/**
|
|
7445
|
-
|
|
7546
|
+
/** Grid region(s). Today exactly one `grid` shape. */
|
|
7547
|
+
regions: array(MotionZoneRegionSchema),
|
|
7446
7548
|
lastFetchedAt: number()
|
|
7447
7549
|
});
|
|
7448
7550
|
const MotionZoneOptionsSchema = object({
|
|
7449
|
-
|
|
7450
|
-
|
|
7551
|
+
maxRegions: number(),
|
|
7552
|
+
supportedShapes: array(MaskShapeKindSchema),
|
|
7553
|
+
grid: MaskGridDimsSchema,
|
|
7451
7554
|
sensitivity: object({ min: number(), max: number(), step: number() })
|
|
7452
7555
|
});
|
|
7453
7556
|
const MotionZonePatchSchema = object({
|
|
7454
7557
|
enabled: boolean().optional(),
|
|
7455
7558
|
sensitivity: number().optional(),
|
|
7456
|
-
|
|
7559
|
+
regions: array(MotionZoneRegionSchema).optional()
|
|
7457
7560
|
});
|
|
7458
7561
|
({
|
|
7459
7562
|
deviceTypes: [DeviceType.Camera],
|
|
@@ -7466,6 +7569,102 @@ const MotionZonePatchSchema = object({
|
|
|
7466
7569
|
)
|
|
7467
7570
|
}
|
|
7468
7571
|
});
|
|
7572
|
+
const NativeObjectClassEnum = _enum([
|
|
7573
|
+
"person",
|
|
7574
|
+
"vehicle",
|
|
7575
|
+
"animal",
|
|
7576
|
+
"face",
|
|
7577
|
+
"package",
|
|
7578
|
+
"other"
|
|
7579
|
+
]);
|
|
7580
|
+
const NativeDetectionSchema = object({
|
|
7581
|
+
class: NativeObjectClassEnum,
|
|
7582
|
+
timestamp: number(),
|
|
7583
|
+
/** Firmware-provided confidence [0..1]. Reolink pushes don't carry it → undefined. */
|
|
7584
|
+
confidence: number().min(0).max(1).optional()
|
|
7585
|
+
});
|
|
7586
|
+
const NativeObjectDetectionStatusSchema = object({
|
|
7587
|
+
/**
|
|
7588
|
+
* Last observed instance per class. Missing entries mean the class
|
|
7589
|
+
* is supported but nothing has been seen since the provider started.
|
|
7590
|
+
*
|
|
7591
|
+
* MUST be a partial record: providers seed an empty `{}` on cold-start
|
|
7592
|
+
* and write one class at a time as detections arrive. In Zod 4
|
|
7593
|
+
* `z.record(enum, …)` is EXHAUSTIVE (requires every enum key), so a
|
|
7594
|
+
* partial write throws "expected object, received undefined" for every
|
|
7595
|
+
* unseen class. `z.partialRecord` keeps the enum-key narrowing while
|
|
7596
|
+
* allowing the sparse shape the providers actually write.
|
|
7597
|
+
*/
|
|
7598
|
+
lastByClass: partialRecord(NativeObjectClassEnum, NativeDetectionSchema.nullable()),
|
|
7599
|
+
/** Classes the firmware is capable of detecting — enumerated at device register. */
|
|
7600
|
+
supportedClasses: array(NativeObjectClassEnum).readonly(),
|
|
7601
|
+
/**
|
|
7602
|
+
* Whether forwarding of onboard AI detections is enabled for this device.
|
|
7603
|
+
* Default true (on cold-start) — detections flow unconditionally before
|
|
7604
|
+
* the toggle is saved, so defaulting true preserves existing behaviour.
|
|
7605
|
+
*/
|
|
7606
|
+
enabled: boolean()
|
|
7607
|
+
});
|
|
7608
|
+
NativeObjectDetectionStatusSchema.extend({
|
|
7609
|
+
/** Required by createRuntimeStateBridge — epoch ms of last refresh. */
|
|
7610
|
+
lastFetchedAt: number()
|
|
7611
|
+
});
|
|
7612
|
+
({
|
|
7613
|
+
deviceTypes: [DeviceType.Camera],
|
|
7614
|
+
methods: {
|
|
7615
|
+
setEnabled: method(
|
|
7616
|
+
object({ deviceId: number(), enabled: boolean() }),
|
|
7617
|
+
_void(),
|
|
7618
|
+
{ kind: "mutation", auth: "admin" }
|
|
7619
|
+
)
|
|
7620
|
+
},
|
|
7621
|
+
events: {
|
|
7622
|
+
onDetected: { data: object({
|
|
7623
|
+
deviceId: number(),
|
|
7624
|
+
detection: NativeDetectionSchema
|
|
7625
|
+
}) }
|
|
7626
|
+
}
|
|
7627
|
+
});
|
|
7628
|
+
const PrivacyMaskShapeSchema = discriminatedUnion("kind", [
|
|
7629
|
+
MaskRectShapeSchema,
|
|
7630
|
+
MaskPolygonShapeSchema
|
|
7631
|
+
]);
|
|
7632
|
+
const PrivacyMaskRegionSchema = object({
|
|
7633
|
+
/** Slot id, 0-based. Stable across read/write. */
|
|
7634
|
+
id: number(),
|
|
7635
|
+
/** Whether this zone is active (blanked out by the camera). */
|
|
7636
|
+
enabled: boolean(),
|
|
7637
|
+
shape: PrivacyMaskShapeSchema
|
|
7638
|
+
});
|
|
7639
|
+
object({
|
|
7640
|
+
enabled: boolean(),
|
|
7641
|
+
/** Active zones (normalized 0..1). Length ≤ maxRegions. */
|
|
7642
|
+
regions: array(PrivacyMaskRegionSchema),
|
|
7643
|
+
lastFetchedAt: number()
|
|
7644
|
+
});
|
|
7645
|
+
const PrivacyMaskOptionsSchema = object({
|
|
7646
|
+
/** Maximum number of supported zones. */
|
|
7647
|
+
maxRegions: number(),
|
|
7648
|
+
/** Shape kinds this camera accepts — Reolink: ['rect']; Hikvision: ['rect','polygon']. */
|
|
7649
|
+
supportedShapes: array(MaskShapeKindSchema),
|
|
7650
|
+
/** Polygon vertex bounds when 'polygon' is supported (Hikvision: {min:4,max:4}). */
|
|
7651
|
+
polygonVertices: MaskPolygonVerticesSchema.optional()
|
|
7652
|
+
});
|
|
7653
|
+
const PrivacyMaskPatchSchema = object({
|
|
7654
|
+
enabled: boolean().optional(),
|
|
7655
|
+
regions: array(PrivacyMaskRegionSchema).optional()
|
|
7656
|
+
});
|
|
7657
|
+
({
|
|
7658
|
+
deviceTypes: [DeviceType.Camera],
|
|
7659
|
+
methods: {
|
|
7660
|
+
getOptions: method(object({ deviceId: number() }), PrivacyMaskOptionsSchema),
|
|
7661
|
+
setMask: method(
|
|
7662
|
+
object({ deviceId: number(), patch: PrivacyMaskPatchSchema }),
|
|
7663
|
+
_void(),
|
|
7664
|
+
{ kind: "mutation", auth: "admin" }
|
|
7665
|
+
)
|
|
7666
|
+
}
|
|
7667
|
+
});
|
|
7469
7668
|
const AutotrackTargetTypeSchema = string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
|
|
7470
7669
|
const PtzAutotrackSettingsSchema = object({
|
|
7471
7670
|
targetType: AutotrackTargetTypeSchema,
|
|
@@ -7984,7 +8183,8 @@ const SettingsUpdateResultSchema = object({
|
|
|
7984
8183
|
object({
|
|
7985
8184
|
addonId: string(),
|
|
7986
8185
|
nodeId: string().optional(),
|
|
7987
|
-
overlay: record(string(), unknown()).optional()
|
|
8186
|
+
overlay: record(string(), unknown()).optional(),
|
|
8187
|
+
cap: string().optional()
|
|
7988
8188
|
}),
|
|
7989
8189
|
SettingsSchemaWithValuesSchema.nullable()
|
|
7990
8190
|
),
|
|
@@ -8715,7 +8915,14 @@ const OauthIntegrationDescriptorSchema = object({
|
|
|
8715
8915
|
/** Allowed redirect_uri prefixes. /api/oauth2/authorize rejects any
|
|
8716
8916
|
* redirect_uri that does not start with one of these. Required —
|
|
8717
8917
|
* an empty list means the integration can never complete linking. */
|
|
8718
|
-
allowedRedirectPrefixes: array(string()).min(1)
|
|
8918
|
+
allowedRedirectPrefixes: array(string()).min(1),
|
|
8919
|
+
/** Optional public origin (no trailing slash) that this integration's
|
|
8920
|
+
* issued codes/tokens should carry as the `hubUrl` claim — typically the
|
|
8921
|
+
* operator-selected external-access endpoint resolved by the addon. When
|
|
8922
|
+
* present, /api/oauth2/authorize bakes THIS into the code instead of the
|
|
8923
|
+
* hub-global `publicHubUrl()`, so a forked exporter addon (which can't set
|
|
8924
|
+
* the hub's env) drives the claim that its cloud Lambda routes back on. */
|
|
8925
|
+
hubUrl: string().optional()
|
|
8719
8926
|
});
|
|
8720
8927
|
({
|
|
8721
8928
|
methods: {
|
|
@@ -9365,7 +9572,20 @@ const webrtcSessionCapability = {
|
|
|
9365
9572
|
object({
|
|
9366
9573
|
deviceId: number().int().nonnegative(),
|
|
9367
9574
|
target: WebrtcStreamTargetSchema,
|
|
9368
|
-
hints: webrtcClientHintsSchema.optional()
|
|
9575
|
+
hints: webrtcClientHintsSchema.optional(),
|
|
9576
|
+
/**
|
|
9577
|
+
* SERVER-INJECTED — NOT a client hint. The hub layer that holds
|
|
9578
|
+
* the tRPC request context (and therefore the client IP) sets
|
|
9579
|
+
* this to `true` when the viewer's source IP is non-LAN
|
|
9580
|
+
* (4G/CGNAT/internet). The broker then forces TURN-relay-only
|
|
9581
|
+
* ICE for the session so a CGNAT client (which can only offer a
|
|
9582
|
+
* relay candidate) gets a clean relay↔relay media path instead
|
|
9583
|
+
* of werift nominating a dead host/hairpin-srflx pair. LAN
|
|
9584
|
+
* clients leave this absent/false and keep the low-latency
|
|
9585
|
+
* direct (host/srflx) path. Clients MUST NOT send this — the
|
|
9586
|
+
* server overwrites it from the request context.
|
|
9587
|
+
*/
|
|
9588
|
+
relayOnly: boolean().optional()
|
|
9369
9589
|
}),
|
|
9370
9590
|
object({ sessionId: string(), sdpOffer: string() }),
|
|
9371
9591
|
{ kind: "mutation" }
|
|
@@ -9388,7 +9608,22 @@ const webrtcSessionCapability = {
|
|
|
9388
9608
|
deviceId: number().int().nonnegative(),
|
|
9389
9609
|
target: WebrtcStreamTargetSchema.optional(),
|
|
9390
9610
|
sdpOffer: string(),
|
|
9391
|
-
sessionId: string().optional()
|
|
9611
|
+
sessionId: string().optional(),
|
|
9612
|
+
/**
|
|
9613
|
+
* Force TURN-relay-only ICE for this session. Two kinds of caller
|
|
9614
|
+
* set it:
|
|
9615
|
+
* - A cloud peer like Alexa's RTCSessionController (reachable
|
|
9616
|
+
* only via TURN, never our host/srflx behind NAT) passes
|
|
9617
|
+
* `true` from its own trusted addon context.
|
|
9618
|
+
* - The hub injects it for browser client-offer viewers from the
|
|
9619
|
+
* request's source IP (non-LAN ⇒ true), exactly as it does for
|
|
9620
|
+
* `createSession`.
|
|
9621
|
+
* A LAN/Tailscale browser doing client-offer passthrough leaves it
|
|
9622
|
+
* absent/false so a direct host pair carries full native quality.
|
|
9623
|
+
* Untrusted browser clients MUST NOT send it — the hub overwrites
|
|
9624
|
+
* it from the request context.
|
|
9625
|
+
*/
|
|
9626
|
+
relayOnly: boolean().optional()
|
|
9392
9627
|
}),
|
|
9393
9628
|
object({ sessionId: string(), sdpAnswer: string() }),
|
|
9394
9629
|
{ kind: "mutation" }
|
|
@@ -9402,6 +9637,46 @@ const webrtcSessionCapability = {
|
|
|
9402
9637
|
_void(),
|
|
9403
9638
|
{ kind: "mutation" }
|
|
9404
9639
|
),
|
|
9640
|
+
/**
|
|
9641
|
+
* Trickle ICE — add a remote (client) ICE candidate to a live session.
|
|
9642
|
+
* Lets the client send its SDP offer/answer IMMEDIATELY (before ICE
|
|
9643
|
+
* gathering finishes) and deliver candidates as they arrive, so the
|
|
9644
|
+
* connection establishes in ~0s instead of waiting for full gathering.
|
|
9645
|
+
* The dual of `getIceCandidates`. Mirrors Scrypted's signaling.
|
|
9646
|
+
*/
|
|
9647
|
+
addIceCandidate: method(
|
|
9648
|
+
object({
|
|
9649
|
+
deviceId: number().int().nonnegative(),
|
|
9650
|
+
sessionId: string(),
|
|
9651
|
+
candidate: string(),
|
|
9652
|
+
sdpMid: string().nullable().optional(),
|
|
9653
|
+
sdpMLineIndex: number().int().nullable().optional()
|
|
9654
|
+
}),
|
|
9655
|
+
_void(),
|
|
9656
|
+
{ kind: "mutation" }
|
|
9657
|
+
),
|
|
9658
|
+
/**
|
|
9659
|
+
* Trickle ICE — poll the server's gathered ICE candidates for a session.
|
|
9660
|
+
* The server answers immediately (no gathering wait) and the client polls
|
|
9661
|
+
* this to receive host/srflx/relay candidates as werift gathers them,
|
|
9662
|
+
* adding each to its PeerConnection. Returns all candidates gathered so
|
|
9663
|
+
* far; the client dedupes. `done` flips true once gathering completes.
|
|
9664
|
+
*/
|
|
9665
|
+
getIceCandidates: method(
|
|
9666
|
+
object({
|
|
9667
|
+
deviceId: number().int().nonnegative(),
|
|
9668
|
+
sessionId: string()
|
|
9669
|
+
}),
|
|
9670
|
+
object({
|
|
9671
|
+
candidates: array(object({
|
|
9672
|
+
candidate: string(),
|
|
9673
|
+
sdpMid: string().nullable(),
|
|
9674
|
+
sdpMLineIndex: number().int().nullable()
|
|
9675
|
+
})),
|
|
9676
|
+
done: boolean()
|
|
9677
|
+
}),
|
|
9678
|
+
{ kind: "query" }
|
|
9679
|
+
),
|
|
9405
9680
|
closeSession: method(
|
|
9406
9681
|
object({
|
|
9407
9682
|
deviceId: number().int().nonnegative(),
|
|
@@ -11102,6 +11377,9 @@ const detectionPipelineCapability = {
|
|
|
11102
11377
|
exposesDeviceSettings: true,
|
|
11103
11378
|
methods: {}
|
|
11104
11379
|
};
|
|
11380
|
+
({
|
|
11381
|
+
deviceTypes: [DeviceType.Camera]
|
|
11382
|
+
});
|
|
11105
11383
|
const TrackStateSchema = _enum(["new", "entered", "left", "moving", "idle"]);
|
|
11106
11384
|
const EventKindSchema = _enum(["motion", "object", "audio"]);
|
|
11107
11385
|
const TrackPositionSchema = object({
|
|
@@ -11929,36 +12207,28 @@ const IntercomStatusSchema = object({
|
|
|
11929
12207
|
}) }
|
|
11930
12208
|
}
|
|
11931
12209
|
});
|
|
11932
|
-
const
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
object({
|
|
11947
|
-
/**
|
|
11948
|
-
* Last observed instance per class. Undefined entries mean the class
|
|
11949
|
-
* is supported but nothing has been seen since the provider started.
|
|
11950
|
-
*/
|
|
11951
|
-
lastByClass: record(NativeObjectClassEnum, NativeDetectionSchema.nullable()),
|
|
11952
|
-
/** Classes the firmware is capable of detecting — enumerated at device register. */
|
|
11953
|
-
supportedClasses: array(NativeObjectClassEnum).readonly()
|
|
12210
|
+
const CamStreamDescriptorSchema = object({
|
|
12211
|
+
camStreamId: string().min(1),
|
|
12212
|
+
kind: CamStreamKindSchema,
|
|
12213
|
+
url: string().optional(),
|
|
12214
|
+
codec: string().optional(),
|
|
12215
|
+
resolution: CamStreamResolutionSchema.optional(),
|
|
12216
|
+
fps: number().positive().optional(),
|
|
12217
|
+
label: string().optional(),
|
|
12218
|
+
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
12219
|
+
deviceFeatures: array(string()).optional(),
|
|
12220
|
+
/** Eligible for automatic profile assignment. Absent = `true`. */
|
|
12221
|
+
autoEligible: boolean().optional(),
|
|
12222
|
+
/** Transport-specific opaque metadata (e.g. rfc4571 SDP). */
|
|
12223
|
+
metadata: record(string(), unknown()).optional()
|
|
11954
12224
|
});
|
|
11955
12225
|
({
|
|
11956
12226
|
deviceTypes: [DeviceType.Camera],
|
|
11957
|
-
|
|
11958
|
-
|
|
11959
|
-
deviceId: number(),
|
|
11960
|
-
|
|
11961
|
-
|
|
12227
|
+
methods: {
|
|
12228
|
+
getCatalog: method(
|
|
12229
|
+
object({ deviceId: number().int().nonnegative() }),
|
|
12230
|
+
array(CamStreamDescriptorSchema).readonly()
|
|
12231
|
+
)
|
|
11962
12232
|
}
|
|
11963
12233
|
});
|
|
11964
12234
|
const ModelFormatSchema = _enum(MODEL_FORMATS);
|
|
@@ -13166,7 +13436,8 @@ const PackageUpdateSchema = object({
|
|
|
13166
13436
|
currentVersion: string(),
|
|
13167
13437
|
latestVersion: string(),
|
|
13168
13438
|
category: _enum(["addon", "core"]),
|
|
13169
|
-
requiresRestart: boolean()
|
|
13439
|
+
requiresRestart: boolean(),
|
|
13440
|
+
isSystem: boolean()
|
|
13170
13441
|
});
|
|
13171
13442
|
const PackageVersionInfoSchema = object({
|
|
13172
13443
|
version: string(),
|
|
@@ -13199,6 +13470,42 @@ const UpdateFrameworkPackageResultSchema = object({
|
|
|
13199
13470
|
/** Ms-epoch the server scheduled its self-restart. */
|
|
13200
13471
|
restartingAt: number()
|
|
13201
13472
|
});
|
|
13473
|
+
const BulkUpdateItemStatusSchema = _enum([
|
|
13474
|
+
"queued",
|
|
13475
|
+
"updating",
|
|
13476
|
+
"done",
|
|
13477
|
+
"done-pending-restart",
|
|
13478
|
+
"failed"
|
|
13479
|
+
]);
|
|
13480
|
+
const BulkUpdateItemSchema = object({
|
|
13481
|
+
name: string(),
|
|
13482
|
+
isSystem: boolean(),
|
|
13483
|
+
fromVersion: string(),
|
|
13484
|
+
toVersion: string(),
|
|
13485
|
+
status: BulkUpdateItemStatusSchema,
|
|
13486
|
+
error: string().optional(),
|
|
13487
|
+
startedAtMs: number().optional(),
|
|
13488
|
+
completedAtMs: number().optional()
|
|
13489
|
+
});
|
|
13490
|
+
const BulkUpdatePhaseSchema = _enum([
|
|
13491
|
+
"regular",
|
|
13492
|
+
"system",
|
|
13493
|
+
"restarting",
|
|
13494
|
+
"finalizing"
|
|
13495
|
+
]);
|
|
13496
|
+
const BulkUpdateStateSchema = object({
|
|
13497
|
+
id: string(),
|
|
13498
|
+
nodeId: string(),
|
|
13499
|
+
startedAtMs: number(),
|
|
13500
|
+
completedAtMs: number().optional(),
|
|
13501
|
+
total: number(),
|
|
13502
|
+
completed: number(),
|
|
13503
|
+
failed: number(),
|
|
13504
|
+
current: string().nullable(),
|
|
13505
|
+
phase: BulkUpdatePhaseSchema,
|
|
13506
|
+
cancelled: boolean(),
|
|
13507
|
+
items: array(BulkUpdateItemSchema).readonly()
|
|
13508
|
+
});
|
|
13202
13509
|
const FrameworkPackageStatusSchema = object({
|
|
13203
13510
|
packageName: string(),
|
|
13204
13511
|
currentVersion: string(),
|
|
@@ -13336,7 +13643,7 @@ const CustomActionInputSchema = object({
|
|
|
13336
13643
|
getLastRestart: method(
|
|
13337
13644
|
_void(),
|
|
13338
13645
|
object({
|
|
13339
|
-
kind: _enum(["framework-update", "manual", "system"]),
|
|
13646
|
+
kind: _enum(["framework-update", "manual", "system", "framework-bulk-update"]),
|
|
13340
13647
|
packageName: string().optional(),
|
|
13341
13648
|
fromVersion: string().optional(),
|
|
13342
13649
|
toVersion: string().optional(),
|
|
@@ -13426,11 +13733,70 @@ const CustomActionInputSchema = object({
|
|
|
13426
13733
|
updateFrameworkPackage: method(
|
|
13427
13734
|
object({
|
|
13428
13735
|
packageName: string().min(1),
|
|
13429
|
-
version: string().optional()
|
|
13736
|
+
version: string().optional(),
|
|
13737
|
+
deferRestart: boolean().optional()
|
|
13430
13738
|
}),
|
|
13431
13739
|
UpdateFrameworkPackageResultSchema,
|
|
13432
13740
|
{ kind: "mutation", auth: "admin" }
|
|
13433
13741
|
),
|
|
13742
|
+
/**
|
|
13743
|
+
* Kicks off a server-side bulk update operation and returns the bulk
|
|
13744
|
+
* id immediately. The operation runs asynchronously; observe progress
|
|
13745
|
+
* via the `AddonsBulkUpdateProgress` event or `getBulkUpdateState`.
|
|
13746
|
+
* Items with `isSystem: true` use `deferRestart` — the hub restarts
|
|
13747
|
+
* ONCE at the end of the system phase, after all system packages are
|
|
13748
|
+
* installed.
|
|
13749
|
+
*
|
|
13750
|
+
* `items[].version` is REQUIRED — callers must pass the resolved
|
|
13751
|
+
* version from `listUpdates`. There is no `'latest'` default here
|
|
13752
|
+
* (unlike `updatePackage`) to guarantee deterministic bulk rolls.
|
|
13753
|
+
*/
|
|
13754
|
+
startBulkUpdate: method(
|
|
13755
|
+
object({
|
|
13756
|
+
nodeId: string(),
|
|
13757
|
+
items: array(object({
|
|
13758
|
+
name: string(),
|
|
13759
|
+
version: string(),
|
|
13760
|
+
isSystem: boolean()
|
|
13761
|
+
})).readonly()
|
|
13762
|
+
}),
|
|
13763
|
+
object({ id: string() }),
|
|
13764
|
+
{ kind: "mutation", auth: "admin" }
|
|
13765
|
+
),
|
|
13766
|
+
/**
|
|
13767
|
+
* Returns the current state of a bulk update by id.
|
|
13768
|
+
* Returns `null` if the id is unknown or has been auto-cleaned
|
|
13769
|
+
* (5 minutes after `completedAt` the record is evicted from memory).
|
|
13770
|
+
*/
|
|
13771
|
+
getBulkUpdateState: method(
|
|
13772
|
+
object({ id: string() }),
|
|
13773
|
+
BulkUpdateStateSchema.nullable(),
|
|
13774
|
+
{ auth: "admin" }
|
|
13775
|
+
),
|
|
13776
|
+
/**
|
|
13777
|
+
* Cancels an in-flight bulk update. The update loop exits after the
|
|
13778
|
+
* currently-processing item completes — cancellation is not
|
|
13779
|
+
* instantaneous. Has no effect once the `restarting` phase has been
|
|
13780
|
+
* entered (the hub is already shutting down at that point).
|
|
13781
|
+
* Returns `{ cancelled: false }` if the id is unknown, the operation
|
|
13782
|
+
* has already completed, or the `restarting` phase is active.
|
|
13783
|
+
*/
|
|
13784
|
+
cancelBulkUpdate: method(
|
|
13785
|
+
object({ id: string() }),
|
|
13786
|
+
object({ cancelled: boolean() }),
|
|
13787
|
+
{ kind: "mutation", auth: "admin" }
|
|
13788
|
+
),
|
|
13789
|
+
/**
|
|
13790
|
+
* Lists all currently active (non-completed) bulk updates.
|
|
13791
|
+
* If `nodeId` is provided, filters to only bulk updates targeting
|
|
13792
|
+
* that node. Useful for restoring an in-progress banner on a fresh
|
|
13793
|
+
* page load when the UI reconnects mid-operation.
|
|
13794
|
+
*/
|
|
13795
|
+
listActiveBulkUpdates: method(
|
|
13796
|
+
object({ nodeId: string().optional() }),
|
|
13797
|
+
array(BulkUpdateStateSchema).readonly(),
|
|
13798
|
+
{ auth: "admin" }
|
|
13799
|
+
),
|
|
13434
13800
|
getVersions: method(
|
|
13435
13801
|
object({ name: string() }),
|
|
13436
13802
|
array(PackageVersionInfoSchema).readonly()
|
|
@@ -13558,6 +13924,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13558
13924
|
EventCategory2["StreamBrokerOnCamStreamDemand"] = "stream-broker.onCamStreamDemand";
|
|
13559
13925
|
EventCategory2["StreamBrokerOnCamStreamIdle"] = "stream-broker.onCamStreamIdle";
|
|
13560
13926
|
EventCategory2["StreamBrokerOnRequestStreamSourceRefresh"] = "stream-broker.onRequestStreamSourceRefresh";
|
|
13927
|
+
EventCategory2["StreamParamsChanged"] = "stream-params.changed";
|
|
13561
13928
|
EventCategory2["DeviceStateChanged"] = "device.state-changed";
|
|
13562
13929
|
EventCategory2["BatteryOnStatusChanged"] = "battery.onStatusChanged";
|
|
13563
13930
|
EventCategory2["DoorbellOnPressed"] = "doorbell.onPressed";
|
|
@@ -13605,6 +13972,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13605
13972
|
EventCategory2["NetworkTunnelStarted"] = "network.tunnel.started";
|
|
13606
13973
|
EventCategory2["NetworkTunnelStopped"] = "network.tunnel.stopped";
|
|
13607
13974
|
EventCategory2["LocalNetworkChanged"] = "network.local.changed";
|
|
13975
|
+
EventCategory2["MeshNetworkChanged"] = "network.mesh.changed";
|
|
13608
13976
|
EventCategory2["BackupCompleted"] = "backup.completed";
|
|
13609
13977
|
EventCategory2["BackupRestored"] = "backup.restored";
|
|
13610
13978
|
EventCategory2["NotificationDispatched"] = "notification.dispatched";
|
|
@@ -13615,6 +13983,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13615
13983
|
EventCategory2["DeviceAwake"] = "device.awake";
|
|
13616
13984
|
EventCategory2["DeviceSleeping"] = "device.sleeping";
|
|
13617
13985
|
EventCategory2["RetentionCleanup"] = "retention.cleanup";
|
|
13986
|
+
EventCategory2["AddonsBulkUpdateProgress"] = "addons.bulk-update-progress";
|
|
13618
13987
|
return EventCategory2;
|
|
13619
13988
|
})(EventCategory || {});
|
|
13620
13989
|
function createEvent(category, source, data) {
|
|
@@ -13764,7 +14133,7 @@ class BaseAddon {
|
|
|
13764
14133
|
}
|
|
13765
14134
|
// ── Settings schemas (override to provide UI) ─────────────────────────
|
|
13766
14135
|
/** Override to provide global-level settings UI schema. */
|
|
13767
|
-
globalSettingsSchema() {
|
|
14136
|
+
globalSettingsSchema(_cap) {
|
|
13768
14137
|
return null;
|
|
13769
14138
|
}
|
|
13770
14139
|
/** Override to provide device-level settings UI schema. */
|
|
@@ -13778,8 +14147,8 @@ class BaseAddon {
|
|
|
13778
14147
|
// blob and every addon used exactly one of them; the distinction was
|
|
13779
14148
|
// never semantically load-bearing. `global` won because it was the
|
|
13780
14149
|
// widely-used one and the name reads naturally (per-node addon config).
|
|
13781
|
-
async getGlobalSettings(overlay) {
|
|
13782
|
-
const schema = this.globalSettingsSchema();
|
|
14150
|
+
async getGlobalSettings(overlay, cap) {
|
|
14151
|
+
const schema = this.globalSettingsSchema(cap);
|
|
13783
14152
|
if (!schema) return { sections: [] };
|
|
13784
14153
|
const raw = await this._ctx?.settings?.readAddonStore() ?? {};
|
|
13785
14154
|
return hydrateSchema(schema, overlay ? { ...raw, ...overlay } : raw);
|
|
@@ -14311,4 +14680,4 @@ export {
|
|
|
14311
14680
|
DEFAULT_AUDIO_ANALYZER_CONFIG as y,
|
|
14312
14681
|
AUDIO_BACKEND_CHOICES as z
|
|
14313
14682
|
};
|
|
14314
|
-
//# sourceMappingURL=index-
|
|
14683
|
+
//# sourceMappingURL=index-Bmlkm0Fd.mjs.map
|