@camstack/ui-library 1.2.234 → 1.2.236

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.
@@ -61,7 +61,9 @@ export declare function shouldUpgradeAfterProbe(mbps: number): boolean;
61
61
  export declare function resolveProbeOrigin(serverUrl: string | undefined, pageOrigin: string | undefined): string | null;
62
62
  /** Which offer composed the hints. A climb and a cold start read identically
63
63
  * in the hub's log; only the client knows which one it just sent. */
64
- export type AdaptiveOfferPhase = 'cold-start' | 'probe-climb' | 'renegotiate' | 'probe-refused';
64
+ export type AdaptiveOfferPhase = 'cold-start' | 'probe-climb' | 'renegotiate' | 'probe-refused'
65
+ /** The probe went to the session it was measured on; the hub answered (D733). */
66
+ | 'probe-in-session';
65
67
  /**
66
68
  * What the CLIENT sent for one adaptive decision. Deliberately not the hub's
67
69
  * verdict — the hub already logs its own pick, and a client line that repeated
@@ -80,6 +82,8 @@ export interface AdaptiveHintsReport {
80
82
  readonly prefersTier?: string;
81
83
  /** For `probe-refused`: the HTTP status the hub answered the probe with (401/429…). */
82
84
  readonly probeStatus?: number;
85
+ /** For `probe-in-session`: what the hub did with it — `outcome:tier:reason`. */
86
+ readonly probeAnswer?: string;
83
87
  }
84
88
  /**
85
89
  * Identity of a decision, for "log once per CHANGE, not per tick".
@@ -170,3 +174,31 @@ export interface DownlinkProbeStore {
170
174
  }
171
175
  /** App-wide probe cache + single-flight, one per origin. */
172
176
  export declare function createDownlinkProbe(deps: DownlinkProbeStoreDeps): DownlinkProbeStore;
177
+ /** The hub's answer to one session's probe — `webrtcSession.applyDownlinkProbe` (D733). */
178
+ export interface DownlinkProbeAnswer {
179
+ readonly outcome: 'switching' | 'held';
180
+ readonly tier: string | null;
181
+ readonly reason: string;
182
+ }
183
+ /** Host wiring for `webrtcSession.applyDownlinkProbe`, bound to the device. */
184
+ export type ApplyDownlinkProbe = (sessionId: string, downlinkMbps: number) => Promise<DownlinkProbeAnswer>;
185
+ /** What became of handing a probe to its session. */
186
+ export type ProbeHandoff = {
187
+ readonly kind: 'answered';
188
+ readonly answer: DownlinkProbeAnswer;
189
+ } | {
190
+ readonly kind: 'unsupported';
191
+ readonly why: 'no-wiring' | 'no-session' | 'call-failed';
192
+ };
193
+ /**
194
+ * Hand a probe to the session it was measured on (D733).
195
+ *
196
+ * The probe climb used to be a SECOND session: a make-before-break reconnect
197
+ * carrying `downlinkMbps`, so every adaptive live open cost two sessions. The
198
+ * hub now moves the open session to the probed rung itself. `answered` means
199
+ * the hub owns the climb, WHATEVER it answered — `held` included: a reconnect
200
+ * after a `held` would buy the second session for a rung the hub just refused.
201
+ * Only `unsupported` (no host wiring, no session id yet, or a hub that does not
202
+ * know the method) leaves the caller its legacy reconnect climb.
203
+ */
204
+ export declare function handProbeToSession(apply: ApplyDownlinkProbe | undefined, sessionId: string | null, downlinkMbps: number): Promise<ProbeHandoff>;
@@ -1,4 +1,5 @@
1
1
  import { PipelineAddonSchema, AgentAddonConfig, CameraStepOverridePatch } from '@camstack/types';
2
+ import { RootModelInfo } from './root-model-source';
2
3
  export type EditorMode = 'agent' | 'device';
3
4
  export interface AgentStepEditorProps {
4
5
  readonly mode: EditorMode;
@@ -20,5 +21,10 @@ export interface AgentStepEditorProps {
20
21
  * draft, so opening + saving an un-pinned cell still leaves it inheriting.
21
22
  */
22
23
  readonly effectiveModelId?: string;
24
+ /**
25
+ * The ROOT detection model this column runs (D730). When it can supply the
26
+ * edited step, the editor offers "Use the root model"; absent ⇒ no offer.
27
+ */
28
+ readonly rootModel?: RootModelInfo;
23
29
  }
24
30
  export declare function AgentStepEditor(props: AgentStepEditorProps): import("react").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { CamProfile, WebrtcSessionDebug } from '@camstack/types';
3
3
  import { ReconnectAction } from './reconnect-schedule';
4
- import { AdaptiveHintsReport } from './adaptive-downlink';
4
+ import { AdaptiveHintsReport, ApplyDownlinkProbe } from './adaptive-downlink';
5
5
  import { ClientNetworkSample } from './client-network-sample';
6
6
  import { StreamDebugSample } from './stream-debug/webrtc-debug-stats.js';
7
7
  type WebkitPresentationMode = 'inline' | 'picture-in-picture' | 'fullscreen';
@@ -233,6 +233,14 @@ export interface CameraStreamPlayerProps {
233
233
  * the overlay shows its client half alone, saying so.
234
234
  */
235
235
  getSessionDebug?: (sessionId: string) => Promise<WebrtcSessionDebug>;
236
+ /**
237
+ * Hand the downlink probe to the session it was measured on
238
+ * (`webrtcSession.applyDownlinkProbe`, D733). The hub then moves THAT
239
+ * session to the probed rung — in place when it can — so a live open stays
240
+ * one session. Omit it (or talk to a hub that does not know the method) and
241
+ * the player keeps its legacy climb: a second, make-before-break session.
242
+ */
243
+ applyDownlinkProbe?: ApplyDownlinkProbe;
236
244
  /**
237
245
  * Re-offer signaling for an adaptive tier switch (client-offer mode).
238
246
  * Posts a fresh browser-built offer for an EXISTING `sessionId` against
@@ -303,4 +311,4 @@ export interface CameraStreamPlayerProps {
303
311
  */
304
312
  onVideoElement?: (el: HTMLVideoElement | null) => void;
305
313
  }
306
- export declare function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay, muted: initialMuted, showControls, showStats, onDebugStats, onPlaybackStats, onClientNetworkSample, probeAuthToken, onConnectTiming, className, onStateChange, onError, onReconnectAttempt, overlay, createSession, sendAnswer, handleOffer, getIceServers, addIceCandidate, getIceCandidates, closeSession, getSessionState, getSessionDebug, reoffer, posterUrl, hintsOverride, onAdaptiveHints, reconnectSignal, onControlChannel, onVideoElement, }: CameraStreamPlayerProps): import("react").JSX.Element;
314
+ export declare function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay, muted: initialMuted, showControls, showStats, onDebugStats, onPlaybackStats, onClientNetworkSample, probeAuthToken, onConnectTiming, className, onStateChange, onError, onReconnectAttempt, overlay, createSession, sendAnswer, handleOffer, getIceServers, addIceCandidate, getIceCandidates, closeSession, getSessionState, getSessionDebug, applyDownlinkProbe, reoffer, posterUrl, hintsOverride, onAdaptiveHints, reconnectSignal, onControlChannel, onVideoElement, }: CameraStreamPlayerProps): import("react").JSX.Element;
@@ -2,6 +2,8 @@ export { AddonGlobalSettingsForm } from './addon-global-settings-form';
2
2
  export type { AddonPageProps } from './addon-page-props';
3
3
  export type { AgentStepEditorProps, EditorMode } from './agent-step-editor';
4
4
  export { AgentStepEditor } from './agent-step-editor';
5
+ export type { RootModelInfo } from './root-model-source';
6
+ export { rootSourceState } from './root-model-source';
5
7
  export * from './app-shell';
6
8
  export type { AudioClassification, AudioClassificationListProps } from './audio-classification-list';
7
9
  export { AudioClassificationList } from './audio-classification-list';
@@ -14,7 +16,7 @@ export { BatteryBadge } from './battery-badge';
14
16
  export type { NetworkLinkBadgeProps, NetworkLinkStatusLike } from './network-link-badge';
15
17
  export { NetworkLinkBadge } from './network-link-badge';
16
18
  export * from './breadcrumb';
17
- export type { AdaptiveHintsReport, AdaptiveOfferPhase, } from './adaptive-downlink';
19
+ export type { AdaptiveHintsReport, AdaptiveOfferPhase, ApplyDownlinkProbe, DownlinkProbeAnswer, } from './adaptive-downlink';
18
20
  export type { CameraStreamPlayerProps, ClientOfferResult, ClientStreamHints, PlayerConnectionState, PlayerWebrtcTarget, SessionSignalingState, SignalingResult, } from './camera-stream-player';
19
21
  export { CameraStreamPlayer } from './camera-stream-player';
20
22
  export { StreamDebugOverlay } from './stream-debug/stream-debug-overlay';
@@ -88,12 +88,12 @@ export type CellState = {
88
88
  */
89
89
  readonly clusterWide?: boolean;
90
90
  /**
91
- * The root model that already fills this step here (D715) — the step is
92
- * skipped for every subject the detector names for it. Renders a
93
- * "filled by <model>" chip: an enabled cell that will mostly NOT run must
94
- * say so, or the operator reads its model as the one answering.
91
+ * The root model whose output IS this step's result here (D730) — the
92
+ * step's "Use the root model" flag is on and the root supplies it, so the
93
+ * step's own model does not run. Renders a "root" chip: an enabled cell
94
+ * whose model is not the one answering must say so.
95
95
  */
96
- readonly filledBy?: string;
96
+ readonly suppliedByRoot?: string;
97
97
  } | {
98
98
  readonly kind: 'disabled';
99
99
  readonly overridden?: boolean;
@@ -0,0 +1,19 @@
1
+ import { RootStepSupply, RootSupplyState } from '@camstack/types';
2
+ /** The root model the edited column runs, and what it can supply. */
3
+ export interface RootModelInfo {
4
+ readonly modelId: string;
5
+ readonly name: string;
6
+ readonly supplies: readonly RootStepSupply[];
7
+ }
8
+ /** The editor's view of the flag for one step, or `null` for a step no root can supply. */
9
+ export declare function rootSourceState(stepId: string, settings: Readonly<Record<string, unknown>> | undefined, rootModel: RootModelInfo | undefined): RootSupplyState | null;
10
+ /** The settings bag with the flag set — every other key untouched. */
11
+ export declare function withUseRootModel(settings: Readonly<Record<string, unknown>> | undefined, value: boolean): Readonly<Record<string, unknown>>;
12
+ export interface RootModelSourceControlProps {
13
+ readonly stepId: string;
14
+ readonly settings: Readonly<Record<string, unknown>> | undefined;
15
+ readonly rootModel: RootModelInfo | undefined;
16
+ readonly disabled?: boolean;
17
+ readonly onChange: (useRootModel: boolean) => void;
18
+ }
19
+ export declare function RootModelSourceControl({ stepId, settings, rootModel, disabled, onChange, }: RootModelSourceControlProps): import("react").JSX.Element | null;
@@ -1,5 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { CamProfile, WebrtcSessionDebug, StationaryOverlayBox } from '@camstack/types';
3
+ import { ApplyDownlinkProbe } from './adaptive-downlink';
3
4
  import { SignalingResult, ClientOfferResult, ClientStreamHints, SessionSignalingState } from './camera-stream-player';
4
5
  import { DeviceDetections } from '../hooks/use-device-detections';
5
6
  /**
@@ -75,6 +76,8 @@ export interface StreamPanelProps {
75
76
  * that silently omits half its answer is worse than one that admits it.
76
77
  */
77
78
  readonly getSessionDebug?: (sessionId: string) => Promise<WebrtcSessionDebug>;
79
+ /** Hand the downlink probe to the live session (D733) — one session per open. */
80
+ readonly applyDownlinkProbe?: ApplyDownlinkProbe;
78
81
  /**
79
82
  * When set, the panel switches to VOD mode: it renders an `HlsVideo`
80
83
  * over this master `.m3u8` URL INSTEAD of the live WebRTC player, and
@@ -209,4 +212,4 @@ export interface StreamPanelProps {
209
212
  readonly chromeless?: boolean;
210
213
  readonly className?: string;
211
214
  }
212
- export declare function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIceServers, addIceCandidate, getIceCandidates, closeSession, getSessionState, getSessionDebug, playbackUrl, playbackFormat, playbackAuthToken, onExitPlayback, posterUrl, streams, activeStreamId: controlledStreamId, onStreamChange, deviceName, phase, pipelineMetrics, detections, stationaryObjects, defaultShowDetections, defaultShowMotion, streamStats, autoPlay, showPlayStop, snapshotSrc, snapshotLoading, onRefreshSnapshot, showStreamStats, children, extraOverlay, ptzAvailable, ptzShown, ptzOverlay, onPtzToggle, intercomAvailable, intercomShown, onIntercomToggle, chromeless, className, }: StreamPanelProps): import("react").JSX.Element;
215
+ export declare function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIceServers, addIceCandidate, getIceCandidates, closeSession, getSessionState, getSessionDebug, applyDownlinkProbe, playbackUrl, playbackFormat, playbackAuthToken, onExitPlayback, posterUrl, streams, activeStreamId: controlledStreamId, onStreamChange, deviceName, phase, pipelineMetrics, detections, stationaryObjects, defaultShowDetections, defaultShowMotion, streamStats, autoPlay, showPlayStop, snapshotSrc, snapshotLoading, onRefreshSnapshot, showStreamStats, children, extraOverlay, ptzAvailable, ptzShown, ptzOverlay, onPtzToggle, intercomAvailable, intercomShown, onIntercomToggle, chromeless, className, }: StreamPanelProps): import("react").JSX.Element;
@@ -869,6 +869,16 @@ export declare const useLocalNetworkSetNotificationEndpoint: typeof trpc.localNe
869
869
  export declare const useLocalNetworkGetViewerEndpoints: typeof trpc.localNetwork.getViewerEndpoints.useQuery;
870
870
  /** Generated alias around `trpc.localNetwork.setViewerEndpoints.useMutation`. */
871
871
  export declare const useLocalNetworkSetViewerEndpoints: typeof trpc.localNetwork.setViewerEndpoints.useMutation;
872
+ /** Generated alias around `trpc.localNetwork.getAddresses.useQuery`. */
873
+ export declare const useLocalNetworkGetAddresses: typeof trpc.localNetwork.getAddresses.useQuery;
874
+ /** Generated alias around `trpc.localNetwork.addCustomAddress.useMutation`. */
875
+ export declare const useLocalNetworkAddCustomAddress: typeof trpc.localNetwork.addCustomAddress.useMutation;
876
+ /** Generated alias around `trpc.localNetwork.removeCustomAddress.useMutation`. */
877
+ export declare const useLocalNetworkRemoveCustomAddress: typeof trpc.localNetwork.removeCustomAddress.useMutation;
878
+ /** Generated alias around `trpc.localNetwork.setAddressRole.useMutation`. */
879
+ export declare const useLocalNetworkSetAddressRole: typeof trpc.localNetwork.setAddressRole.useMutation;
880
+ /** Generated alias around `trpc.localNetwork.getHubAddresses.useQuery`. */
881
+ export declare const useLocalNetworkGetHubAddresses: typeof trpc.localNetwork.getHubAddresses.useQuery;
872
882
  /** Generated alias around `trpc.localNetwork.getAllowedAddresses.useQuery`. */
873
883
  export declare const useLocalNetworkGetAllowedAddresses: typeof trpc.localNetwork.getAllowedAddresses.useQuery;
874
884
  /** Generated alias around `trpc.localNetwork.setAllowedAddresses.useMutation`. */
@@ -2197,6 +2207,8 @@ export declare const useWebrtcSessionCloseSession: typeof trpc.webrtcSession.clo
2197
2207
  export declare const useWebrtcSessionHasAdaptiveBitrate: typeof trpc.webrtcSession.hasAdaptiveBitrate.useQuery;
2198
2208
  /** Generated alias around `trpc.webrtcSession.getSessionState.useQuery`. */
2199
2209
  export declare const useWebrtcSessionGetSessionState: typeof trpc.webrtcSession.getSessionState.useQuery;
2210
+ /** Generated alias around `trpc.webrtcSession.applyDownlinkProbe.useMutation`. */
2211
+ export declare const useWebrtcSessionApplyDownlinkProbe: typeof trpc.webrtcSession.applyDownlinkProbe.useMutation;
2200
2212
  /** Generated alias around `trpc.webrtcSession.getSessionDebug.useQuery`. */
2201
2213
  export declare const useWebrtcSessionGetSessionDebug: typeof trpc.webrtcSession.getSessionDebug.useQuery;
2202
2214
  /** Generated alias around `trpc.zoneAnalytics.getCurrentSnapshot.useQuery`. */
@@ -1,6 +1,7 @@
1
1
  import { CamProfile, WebrtcSessionDebug } from '@camstack/types';
2
2
  import { StreamChoice } from '../composites/stream-panel';
3
3
  import { ClientStreamHints, SignalingResult, ClientOfferResult } from '../composites/camera-stream-player';
4
+ import { ApplyDownlinkProbe, DownlinkProbeAnswer } from '../composites/adaptive-downlink';
4
5
  /**
5
6
  * Discriminated WebRTC target — same shape as `WebrtcStreamTarget` on
6
7
  * the backend cap. The `profile` tier uses the canonical `CamProfile`
@@ -120,6 +121,16 @@ export interface UseDeviceWebrtcTrpc {
120
121
  deviceId: number;
121
122
  sessionId: string;
122
123
  }, WebrtcSessionDebug>;
124
+ /**
125
+ * Hand the viewer's downlink probe to ONE live session (D733). Optional:
126
+ * a hub built before it has no such route, and the player then keeps its
127
+ * legacy probe climb (a second session).
128
+ */
129
+ applyDownlinkProbe?: MutateFn<{
130
+ deviceId: number;
131
+ sessionId: string;
132
+ downlinkMbps: number;
133
+ }, DownlinkProbeAnswer>;
123
134
  };
124
135
  pipelineOrchestrator?: {
125
136
  getCameraMetrics: QueryFn<{
@@ -201,6 +212,12 @@ export interface DeviceWebrtcResult {
201
212
  * it and shows the message.
202
213
  */
203
214
  readonly getSessionDebug: (sessionId: string) => Promise<WebrtcSessionDebug>;
215
+ /**
216
+ * Hand the downlink probe to the session it was measured on (D733). Rejects
217
+ * when there is no device or the hub has no such method — the player reads
218
+ * a rejection as "unsupported" and falls back to its legacy climb.
219
+ */
220
+ readonly applyDownlinkProbe: ApplyDownlinkProbe;
204
221
  }
205
222
  /** Live signaling state for a session — the adaptive re-offer signal. */
206
223
  export interface SessionRenegotiationState {