@camstack/sdk 0.1.54 → 0.1.56

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.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { System, createSystem, raceFastestEndpoint } from "./system.js";
2
2
  export type { SystemConfig, UserInfo, SystemLiveEvent, SystemLiveEventListener } from "./system.js";
3
+ export type { DeviceInfo } from "@camstack/types";
3
4
  export type { BackendAppRouter } from "./backend-router.js";
4
5
  export type { BackendAppRouter as AppRouter } from "./backend-router.js";
5
6
  export type { BackendConnectionState } from "./types.js";
@@ -11,6 +12,4 @@ export type { TimelineEventSeverity, MotionFragmentType, DetectionEvent, MotionI
11
12
  export type { CameraSourceType, StreamMethod, PanTiltZoomCommand, PanTiltZoomCapabilities, CameraAccessorySwitchKind, CameraStatusEntry, CamerasStatusResult, } from "./camera.js";
12
13
  export { FEATURE_MATRIX, isFeatureAvailable, getSourceFeatures, getBackendRequiredFeatures, } from "./features.js";
13
14
  export type { FeatureId, PlatformId, SourceType, FeatureEntry, } from "./features.js";
14
- export { selectOptimalStream, getNextEvalInterval, } from "./adaptive-stream.js";
15
- export type { StreamConstraints, StreamAssignment, StreamSelectionRequest, StreamSelectionResponse, } from "./adaptive-stream.js";
16
15
  export type { StreamSourceEntry, NvrCamera, CameraAccessory, StreamInfo, NormalizedBoundingBox, DetectionData, EventSnapshotData, NvrEvent, RecordingSegment, MotionBucket, LiveDetection, LiveMotionData, LiveDetectionData, LiveAudioData, LiveMotionEvent, LiveDetectionEvent, LiveAudioEvent, LiveGenericEvent, LiveReviewEvent, LiveEvent, LiveEventType, VideoClipsQuery, NvrVideoClip, VideoClipsResult, VideoClipUrlResult, CameraDayData, CameraStatus, EventsQuery, MotionQuery, RecordingsQuery, NvrConfig, ProviderConfigs, } from "./nvr.js";
package/dist/index.js CHANGED
@@ -1124,6 +1124,31 @@ class System {
1124
1124
  const proxies = filters ? this.mirror.query(filters) : this.mirror.getAllDevices();
1125
1125
  return proxies.map((p) => this.attachBinding(p));
1126
1126
  }
1127
+ /**
1128
+ * Sync `DeviceInfo` snapshot (name, canonical type, online, …) for one device
1129
+ * from the warm-boot mirror — `null` if the mirror isn't booted or the device
1130
+ * is unknown. Unlike a `DeviceProxy` (cap accessors only), this carries the
1131
+ * display identity the UI needs to render a device on first paint.
1132
+ */
1133
+ getDeviceInfo(deviceId) {
1134
+ return this.mirror?.getDeviceInfo(deviceId) ?? null;
1135
+ }
1136
+ /**
1137
+ * The `DeviceInfo` snapshots for the current device set (the warm-boot cache),
1138
+ * honouring the same `filters` as {@link listDevices}. Lets a UI render a named
1139
+ * device list immediately without waiting for per-device lifecycle events.
1140
+ */
1141
+ listDeviceInfos(filters) {
1142
+ const mirror = this.mirror;
1143
+ if (!mirror) return [];
1144
+ const proxies = filters ? mirror.query(filters) : mirror.getAllDevices();
1145
+ const out = [];
1146
+ for (const p of proxies) {
1147
+ const info = mirror.getDeviceInfo(p.deviceId);
1148
+ if (info) out.push(info);
1149
+ }
1150
+ return out;
1151
+ }
1127
1152
  /**
1128
1153
  * Sync lookup by numeric id. `null` if the mirror has not been booted
1129
1154
  * or the device is unknown.
@@ -1237,12 +1262,8 @@ class System {
1237
1262
  get pipelineRunner() {
1238
1263
  return this._systemProxy.pipelineRunner;
1239
1264
  }
1240
- get platformProbe() {
1241
- return this._systemProxy.platformProbe;
1242
- }
1243
- get recordingEngine() {
1244
- return this._systemProxy.recordingEngine;
1245
- }
1265
+ // `platform-probe` is infra (addon-to-addon via `api.platformProbe`), not a
1266
+ // client-facing system cap — it isn't on SystemProxy, so no getter here.
1246
1267
  get settingsStore() {
1247
1268
  return this._systemProxy.settingsStore;
1248
1269
  }
@@ -1942,65 +1963,6 @@ function getSourceFeatures(source) {
1942
1963
  function getBackendRequiredFeatures() {
1943
1964
  return FEATURE_MATRIX.filter((f) => f.requiresBackend);
1944
1965
  }
1945
- function selectOptimalStream(streams, constraints, defaultTransport) {
1946
- if (streams.length === 0) return null;
1947
- const viewportPixels = constraints.viewportWidth * constraints.viewportHeight * (constraints.pixelRatio ?? 1);
1948
- const bw = constraints.bandwidthMbps ?? 100;
1949
- const loss = constraints.packetLoss ?? 0;
1950
- const rtt = constraints.rttMs ?? 50;
1951
- let targetTier = "high";
1952
- if (constraints.maxResolution === "low" || constraints.isCellular || bw < 1 || loss > 0.05) {
1953
- targetTier = "low";
1954
- } else if (constraints.maxResolution === "medium" || bw < 5 || viewportPixels < 5e5 || rtt > 200) {
1955
- targetTier = "medium";
1956
- } else if (constraints.maxResolution === "high" || viewportPixels > 2e6) {
1957
- targetTier = "high";
1958
- }
1959
- const PROFILE_TIER = {
1960
- main: "high",
1961
- sub: "medium",
1962
- ext: "low"
1963
- };
1964
- const preferTransport = defaultTransport ?? "native";
1965
- const scored = streams.map((s) => {
1966
- let score = 0;
1967
- const streamTier = PROFILE_TIER[s.profile] ?? "medium";
1968
- if (streamTier === targetTier) score += 100;
1969
- else if (targetTier === "high" && streamTier === "medium" || targetTier === "medium" && streamTier === "high" || targetTier === "medium" && streamTier === "low" || targetTier === "low" && streamTier === "medium") score += 50;
1970
- if (s.transport === preferTransport) score += 30;
1971
- else if (s.transport === "native") score += 20;
1972
- else if (s.transport === "rtsp") score += 15;
1973
- else if (s.transport === "rtmp") score += 10;
1974
- if (s.metadata?.width && s.metadata?.height) {
1975
- const streamPixels = s.metadata.width * s.metadata.height;
1976
- const ratio = streamPixels / Math.max(viewportPixels, 1);
1977
- if (ratio >= 0.8 && ratio <= 2) score += 25;
1978
- else if (ratio >= 0.5 && ratio <= 3) score += 15;
1979
- if (ratio > 4 && bw < 10) score -= 20;
1980
- }
1981
- if (s.metadata?.codec) {
1982
- if (bw < 5 && s.metadata.codec.includes("265")) score += 10;
1983
- if (bw >= 10 && s.metadata.codec.includes("264")) score += 5;
1984
- }
1985
- return { ...s, score, targetTier };
1986
- });
1987
- scored.sort((a, b) => b.score - a.score);
1988
- const best = scored[0];
1989
- return {
1990
- streamName: best.streamName,
1991
- profile: best.profile,
1992
- transport: best.transport,
1993
- label: best.label,
1994
- metadata: best.metadata,
1995
- reason: `${best.targetTier} quality → ${best.profile}/${best.transport} (score: ${best.score})`
1996
- };
1997
- }
1998
- function getNextEvalInterval(constraints, wasSwitch) {
1999
- if (wasSwitch) return 10;
2000
- if (constraints.isCellular) return 15;
2001
- if ((constraints.packetLoss ?? 0) > 0.02) return 15;
2002
- return 30;
2003
- }
2004
1966
  export {
2005
1967
  DEFAULT_ENABLED_CLASSES,
2006
1968
  DetectionClass,
@@ -2027,7 +1989,6 @@ export {
2027
1989
  getBackendRequiredFeatures,
2028
1990
  getCanonicalDeviceType,
2029
1991
  getClassesForTimelinePreset,
2030
- getNextEvalInterval,
2031
1992
  getParentClass,
2032
1993
  getParentDetectionClass,
2033
1994
  getSourceFeatures,
@@ -2048,7 +2009,6 @@ export {
2048
2009
  packageClasses,
2049
2010
  personClasses,
2050
2011
  raceFastestEndpoint,
2051
- selectOptimalStream,
2052
2012
  sensorLabelClasses,
2053
2013
  vehicleClasses
2054
2014
  };