@camstack/addon-post-analysis 0.1.19 → 0.2.0

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.
Files changed (101) hide show
  1. package/dist/dist-4mTLJ7BJ.mjs +20750 -0
  2. package/dist/dist-CS2K80so.js +20933 -0
  3. package/dist/embedding-encoder/index.js +977 -902
  4. package/dist/embedding-encoder/index.mjs +967 -860
  5. package/dist/enrichment-engine/index.js +834 -833
  6. package/dist/enrichment-engine/index.mjs +828 -832
  7. package/dist/pipeline-analytics/_stub.js +1680 -1397
  8. package/dist/pipeline-analytics/_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DOSUJ-U0.mjs +156 -0
  9. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DJvmVCso.mjs +26 -0
  10. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-B3Wx5J80.mjs +26 -0
  11. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.js-C0AuF9av.mjs +26 -0
  12. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-Bm-iyjmq.mjs +26 -0
  13. package/dist/pipeline-analytics/dist-CYZr2fwk.mjs +2726 -0
  14. package/dist/pipeline-analytics/hostInit-BazRS2O7.mjs +129 -0
  15. package/dist/pipeline-analytics/index.js +7133 -2558
  16. package/dist/pipeline-analytics/index.mjs +7124 -2557
  17. package/dist/pipeline-analytics/remoteEntry.js +134 -2973
  18. package/dist/pipeline-analytics/remoteEntry.ssr.js +33 -0
  19. package/dist/pipeline-analytics/virtualExposes-BgYzpJZG.mjs +27 -0
  20. package/dist/pipeline-analytics/virtual_mf-exposes-ssr___mfe_internal__addon_pipeline_analytics_widgets__remoteEntry_js-D7qgWCKX.mjs +10 -0
  21. package/dist/resolve-frame-5lMxmeI1.js +57 -0
  22. package/dist/resolve-frame-CT1T1tWy.mjs +44 -0
  23. package/package.json +26 -32
  24. package/dist/embedding-encoder/index.js.map +0 -1
  25. package/dist/embedding-encoder/index.mjs.map +0 -1
  26. package/dist/enrichment-engine/index.js.map +0 -1
  27. package/dist/enrichment-engine/index.mjs.map +0 -1
  28. package/dist/ffmpeg-config-DRONlBsj.mjs +0 -56
  29. package/dist/ffmpeg-config-DRONlBsj.mjs.map +0 -1
  30. package/dist/ffmpeg-config-uANz3sV5.js +0 -73
  31. package/dist/ffmpeg-config-uANz3sV5.js.map +0 -1
  32. package/dist/index-BFbwYH1P.js +0 -14343
  33. package/dist/index-BFbwYH1P.js.map +0 -1
  34. package/dist/index-BrTlzsrE.mjs +0 -14344
  35. package/dist/index-BrTlzsrE.mjs.map +0 -1
  36. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/AudioHistoryChart.d.ts +0 -4
  37. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/AudioMetricsPanel.d.ts +0 -10
  38. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/DetectionHistoryChart.d.ts +0 -4
  39. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/LiveStatsTab.d.ts +0 -5
  40. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/MotionHistoryChart.d.ts +0 -4
  41. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/OccupancyHistoryChart.d.ts +0 -4
  42. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/OccupancyPanel.d.ts +0 -10
  43. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/chart-utils.d.ts +0 -97
  44. package/dist/pipeline-analytics/@mf-types/compiled-types/pipeline-analytics/widgets/index.d.ts +0 -29
  45. package/dist/pipeline-analytics/@mf-types/widgets.d.ts +0 -2
  46. package/dist/pipeline-analytics/@mf-types.d.ts +0 -3
  47. package/dist/pipeline-analytics/@mf-types.zip +0 -0
  48. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.mjs-h5aXOPSA.mjs +0 -12
  49. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-NjF4kxzW.mjs +0 -19
  50. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-7HAAnpQu.mjs +0 -18
  51. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs-DoWbefqS.mjs +0 -104
  52. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_trpc_mf_1_client__loadShare__.mjs-52bfkwC8.mjs +0 -85
  53. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.mjs-CVrnrGED.mjs +0 -62
  54. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.mjs-BZTB2scQ.mjs +0 -88
  55. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-CJO5YKGV.mjs +0 -29
  56. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-BsyrX6NO.mjs +0 -36
  57. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_2_dom__loadShare__.mjs-Dp8hqYOB.mjs +0 -45
  58. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-B0h0AGOH.mjs +0 -6
  59. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_2_dom_mf_1_client__loadShare__.mjs-BZjEt71l.mjs +0 -34
  60. package/dist/pipeline-analytics/_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-kZBmgzMg.mjs +0 -156
  61. package/dist/pipeline-analytics/client-BlxIUpgf.mjs +0 -9836
  62. package/dist/pipeline-analytics/getErrorShape-BPSzUA7W-TlK8ipWe.mjs +0 -211
  63. package/dist/pipeline-analytics/hostInit-qBB1Thhi.mjs +0 -168
  64. package/dist/pipeline-analytics/index-BoL0rgZt.mjs +0 -435
  65. package/dist/pipeline-analytics/index-CR1aiZDH.mjs +0 -185
  66. package/dist/pipeline-analytics/index-CWkKuNLr.mjs +0 -232
  67. package/dist/pipeline-analytics/index-DlhiA9R0.mjs +0 -2603
  68. package/dist/pipeline-analytics/index-DtdgkNgf.mjs +0 -725
  69. package/dist/pipeline-analytics/index-Dw6Q30NI.mjs +0 -1655
  70. package/dist/pipeline-analytics/index-Dy2V7VOm.mjs +0 -14379
  71. package/dist/pipeline-analytics/index-i47purqY.mjs +0 -37880
  72. package/dist/pipeline-analytics/index-xncRG7-x.mjs +0 -2713
  73. package/dist/pipeline-analytics/index.js.map +0 -1
  74. package/dist/pipeline-analytics/index.mjs.map +0 -1
  75. package/dist/pipeline-analytics/jsx-runtime-Dlbl3gpr.mjs +0 -55
  76. package/dist/pipeline-analytics/schemas-ClCuS4qa.mjs +0 -3594
  77. package/dist/pipeline-analytics/virtualExposes-8FzWTdq3.mjs +0 -42
  78. package/dist/playlist-generator-EhPaB7Hn.js +0 -48
  79. package/dist/playlist-generator-EhPaB7Hn.js.map +0 -1
  80. package/dist/playlist-generator-VTkgn53O.mjs +0 -48
  81. package/dist/playlist-generator-VTkgn53O.mjs.map +0 -1
  82. package/dist/recording/index.js +0 -257
  83. package/dist/recording/index.js.map +0 -1
  84. package/dist/recording/index.mjs +0 -235
  85. package/dist/recording/index.mjs.map +0 -1
  86. package/dist/recording-coordinator-BoGr5moz.js +0 -1052
  87. package/dist/recording-coordinator-BoGr5moz.js.map +0 -1
  88. package/dist/recording-coordinator-CsYH9LqF.mjs +0 -1012
  89. package/dist/recording-coordinator-CsYH9LqF.mjs.map +0 -1
  90. package/dist/recording-db-gOgaoQh0.js +0 -348
  91. package/dist/recording-db-gOgaoQh0.js.map +0 -1
  92. package/dist/recording-db-lIkSMTLq.mjs +0 -348
  93. package/dist/recording-db-lIkSMTLq.mjs.map +0 -1
  94. package/dist/recording-service-facade-B9lG6OFn.mjs +0 -123
  95. package/dist/recording-service-facade-B9lG6OFn.mjs.map +0 -1
  96. package/dist/recording-service-facade-Do1PKlAL.js +0 -123
  97. package/dist/recording-service-facade-Do1PKlAL.js.map +0 -1
  98. package/dist/storage-estimator-CRpoQc9j.js +0 -72
  99. package/dist/storage-estimator-CRpoQc9j.js.map +0 -1
  100. package/dist/storage-estimator-DzD8gWJH.mjs +0 -72
  101. package/dist/storage-estimator-DzD8gWJH.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"recording-service-facade-Do1PKlAL.js","sources":["../src/recording/recording-service-facade.ts"],"sourcesContent":["/**\n * RecordingServiceFacade — implements the recording-engine capability\n * contract by delegating to the internal service classes.\n *\n * Introduced in session 6 Sprint D.2 to replace the broken hand-written\n * recording.router.ts which invoked non-existent methods via a generic\n * `call()` dispatcher. Each facade method delegates to the correct\n * internal service: RecordingCoordinator, RecordingDb, PlaylistGenerator,\n * or StorageEstimator.\n *\n * The facade is the capability provider registered via\n * `context.registerProvider('recording-engine', facade)` — the auto-\n * generated cap router dispatches typed tRPC procedures directly to\n * these methods with full Zod input/output validation.\n */\n\nimport type { RecordingCoordinator } from './recording/recording-coordinator.js'\nimport type { RecordingDb } from './recording/recording-db.js'\nimport type { PlaylistGenerator } from './recording/playlist-generator.js'\nimport type { StorageEstimator } from './recording/storage-estimator.js'\nimport type {\n RecordingPolicy,\n RecordingSegment,\n RecordingThumbnail,\n RecordingStorageConfig,\n StorageEstimate,\n DataCategory,\n} from './recording/types.js'\n\ninterface FacadeDeps {\n readonly coordinator: RecordingCoordinator\n readonly db: RecordingDb\n readonly playlistGenerator: PlaylistGenerator\n readonly storageEstimator: StorageEstimator\n}\n\nexport class RecordingServiceFacade {\n constructor(private readonly deps: FacadeDeps) {}\n\n // ── Status ────────────────────────────────────────────────────────\n\n getStatus(): { activeRecordings: number; totalSegments: number; totalSizeMB: number } {\n const { db, coordinator } = this.deps\n const activeRecordings = coordinator.getActiveCount()\n const { segmentCount: totalSegments, totalBytes } = db.getGlobalStorageUsage()\n return {\n activeRecordings,\n totalSegments,\n totalSizeMB: Math.round(totalBytes / (1024 * 1024)),\n }\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────────\n\n async enable(input: {\n deviceId: number\n policy: Omit<RecordingPolicy, 'deviceId'>\n storageOverrides?: readonly Omit<RecordingStorageConfig, 'deviceId'>[]\n ffmpegOverrides?: Record<string, unknown>\n }): Promise<void> {\n await this.deps.coordinator.enableRecording(input.deviceId, {\n policy: input.policy,\n storageOverrides: input.storageOverrides,\n ffmpegOverrides: input.ffmpegOverrides,\n })\n }\n\n async disable(input: { deviceId: number }): Promise<void> {\n await this.deps.coordinator.disableRecording(input.deviceId)\n }\n\n // ── Config ────────────────────────────────────────────────────────\n\n getConfig(input: { deviceId: number }): RecordingPolicy | null {\n return this.deps.db.getPolicy(input.deviceId)\n }\n\n async updateConfig(input: {\n deviceId: number\n policy: Omit<RecordingPolicy, 'deviceId'>\n ffmpegOverrides?: Record<string, unknown>\n }): Promise<void> {\n this.deps.db.upsertPolicy({ ...input.policy, deviceId: input.deviceId })\n // If the device is actively recording, restart with the new config\n if (this.deps.coordinator.isRecording(input.deviceId)) {\n await this.deps.coordinator.disableRecording(input.deviceId)\n await this.deps.coordinator.enableRecording(input.deviceId, {\n policy: input.policy,\n ffmpegOverrides: input.ffmpegOverrides,\n })\n }\n }\n\n // ── Playback ──────────────────────────────────────────────────────\n\n getPlaylist(input: {\n deviceId: number\n streamId: string\n startTime: number\n endTime: number\n live?: boolean\n }): string {\n return this.deps.playlistGenerator.generate(\n input.deviceId,\n input.streamId,\n input.startTime,\n input.endTime,\n { live: input.live },\n )\n }\n\n getThumbnail(input: {\n deviceId: number\n timestamp: number\n category?: string\n }): RecordingThumbnail | null {\n return this.deps.db.findNearestThumbnail(\n input.deviceId,\n input.timestamp,\n input.category ?? 'scrub',\n )\n }\n\n getSegments(input: {\n deviceId: number\n streamId: string\n startTime: number\n endTime: number\n }): readonly RecordingSegment[] {\n return this.deps.db.querySegments(\n input.deviceId,\n input.streamId,\n input.startTime,\n input.endTime,\n )\n }\n\n getAvailability(input: {\n deviceId: number\n startTime: number\n endTime: number\n }): readonly { startTime: number; endTime: number; streams: readonly string[] }[] {\n return this.deps.db.getAvailability(\n input.deviceId,\n input.startTime,\n input.endTime,\n )\n }\n\n // ── Storage ───────────────────────────────────────────────────────\n\n estimateStorage(input: {\n deviceId: number\n motionInput?: { avgEventsPerDay: number; avgDurationSec: number }\n }): StorageEstimate {\n return this.deps.storageEstimator.estimateForDevice(\n input.deviceId,\n input.motionInput,\n )\n }\n\n estimateGlobalStorage(): StorageEstimate {\n return this.deps.storageEstimator.estimateGlobal()\n }\n\n getStorageUsage(input: { deviceId: number; streamId: string }): {\n totalBytes: number\n segmentCount: number\n } {\n return this.deps.db.getStorageUsage(input.deviceId, input.streamId)\n }\n\n // ── Policy ────────────────────────────────────────────────────────\n\n setPolicy(input: {\n deviceId: number\n policy: Omit<RecordingPolicy, 'deviceId'>\n }): void {\n this.deps.db.upsertPolicy({ ...input.policy, deviceId: input.deviceId })\n }\n\n getPolicy(input: { deviceId: number }): RecordingPolicy | null {\n return this.deps.db.getPolicy(input.deviceId)\n }\n\n getPolicyStatus(input: { deviceId: number }): {\n deviceId: number\n enabled: boolean\n mode: RecordingPolicy['mode']\n activeStreams: number\n } | null {\n const policy = this.deps.db.getPolicy(input.deviceId)\n if (!policy) return null\n const activeStreams = this.deps.coordinator.isRecording(input.deviceId)\n ? policy.streams.length\n : 0\n return {\n deviceId: input.deviceId,\n enabled: policy.enabled,\n mode: policy.mode,\n activeStreams,\n }\n }\n\n // ── Retention ─────────────────────────────────────────────────────\n\n getRetentionConfig(input: {\n deviceId: number\n dataCategory: DataCategory\n }): RecordingStorageConfig | null {\n return this.deps.db.resolveStorageConfig(input.deviceId, input.dataCategory)\n }\n\n updateRetentionConfig(input: RecordingStorageConfig): void {\n this.deps.db.upsertStorageConfig(input)\n }\n\n // ── Motion ────────────────────────────────────────────────────────\n\n getMotionStats(input: {\n deviceId: number\n startTime: number\n endTime: number\n }): {\n totalEvents: number\n avgDurationSec: number\n avgEventsPerDay: number\n dutyCyclePercent: number\n } {\n return this.deps.db.getMotionStats(\n input.deviceId,\n input.startTime,\n input.endTime,\n )\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,72 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- class StorageEstimator {
4
- constructor(db, networkTracker) {
5
- this.db = db;
6
- this.networkTracker = networkTracker;
7
- }
8
- estimateForDevice(deviceId, motionInput) {
9
- const policy = this.db.getPolicy(deviceId);
10
- if (!policy) return { perStream: {}, thumbnails: { estimatedGb: 0 }, totalEstimatedGb: 0 };
11
- const stats = this.networkTracker.getDeviceStats(deviceId);
12
- const perStream = {};
13
- let totalGb = 0;
14
- const motionEstimate = motionInput ? {
15
- avgEventsPerDay: motionInput.avgEventsPerDay,
16
- avgDurationSec: motionInput.avgDurationSec,
17
- dutyCyclePercent: motionInput.avgEventsPerDay * motionInput.avgDurationSec / 86400 * 100
18
- } : void 0;
19
- for (const sp of policy.streams) {
20
- const category = `recording:${sp.streamId}`;
21
- const config = this.db.resolveStorageConfig(deviceId, category);
22
- const retentionDays = config?.retentionDays ?? null;
23
- const retentionGb = config?.retentionGb ?? null;
24
- const streamStats = stats?.streams[sp.streamId];
25
- const observedBitrate = streamStats?.observedBitrateKbps ?? 0;
26
- const bitrateKbps = observedBitrate > 0 ? observedBitrate : streamStats?.nominalBitrateKbps ?? 4e3;
27
- let estimatedGb = 0;
28
- if (retentionDays !== null) {
29
- const retentionSeconds = retentionDays * 86400;
30
- estimatedGb = bitrateKbps * retentionSeconds / 8 / 1024 / 1024 / 1024;
31
- }
32
- if (policy.mode === "motion" && motionEstimate) {
33
- estimatedGb = estimatedGb * motionEstimate.dutyCyclePercent / 100;
34
- }
35
- let estimatedDaysAtCapacity = null;
36
- if (retentionGb !== null && estimatedGb > retentionGb) {
37
- estimatedDaysAtCapacity = retentionDays !== null ? retentionDays * (retentionGb / estimatedGb) : null;
38
- estimatedGb = retentionGb;
39
- }
40
- perStream[sp.streamId] = { bitrateKbps, retentionDays, retentionGb, estimatedGb, estimatedDaysAtCapacity };
41
- totalGb += estimatedGb;
42
- }
43
- const thumbRetentionDays = policy.streams[0] ? this.db.resolveStorageConfig(deviceId, "thumbnail:scrub")?.retentionDays ?? 7 : 7;
44
- const thumbGb = 2 * 24 * thumbRetentionDays / 1024;
45
- totalGb += thumbGb;
46
- return { perStream, thumbnails: { estimatedGb: thumbGb }, totalEstimatedGb: totalGb, motionEstimate };
47
- }
48
- /**
49
- * Estimate global storage across all devices with active policies.
50
- * Sums per-device estimates. No motion weighting — uses continuous mode
51
- * for the global view.
52
- */
53
- estimateGlobal() {
54
- const allPolicies = this.db.getEnabledPolicies();
55
- let totalGb = 0;
56
- const perStream = {};
57
- let totalThumbGb = 0;
58
- for (const policy of allPolicies) {
59
- if (!policy.enabled) continue;
60
- const deviceEstimate = this.estimateForDevice(policy.deviceId);
61
- totalGb += deviceEstimate.totalEstimatedGb;
62
- totalThumbGb += deviceEstimate.thumbnails.estimatedGb;
63
- for (const [key, val] of Object.entries(deviceEstimate.perStream)) {
64
- const globalKey = `${policy.deviceId}/${key}`;
65
- perStream[globalKey] = val;
66
- }
67
- }
68
- return { perStream, thumbnails: { estimatedGb: totalThumbGb }, totalEstimatedGb: totalGb };
69
- }
70
- }
71
- exports.StorageEstimator = StorageEstimator;
72
- //# sourceMappingURL=storage-estimator-CRpoQc9j.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-estimator-CRpoQc9j.js","sources":["../src/recording/recording/storage-estimator.ts"],"sourcesContent":["import type { INetworkQualityTracker } from '@camstack/types'\nimport type { RecordingDb } from './recording-db.js'\nimport type { DataCategory, StorageEstimate, StreamEstimate } from './types.js'\n\ninterface MotionEstimateInput {\n readonly avgEventsPerDay: number\n readonly avgDurationSec: number\n}\n\nexport class StorageEstimator {\n constructor(\n private readonly db: RecordingDb,\n private readonly networkTracker: INetworkQualityTracker,\n ) {}\n\n estimateForDevice(deviceId: number, motionInput?: MotionEstimateInput): StorageEstimate {\n const policy = this.db.getPolicy(deviceId)\n if (!policy) return { perStream: {}, thumbnails: { estimatedGb: 0 }, totalEstimatedGb: 0 }\n\n const stats = this.networkTracker.getDeviceStats(deviceId)\n const perStream: Record<string, StreamEstimate> = {}\n let totalGb = 0\n\n const motionEstimate = motionInput ? {\n avgEventsPerDay: motionInput.avgEventsPerDay,\n avgDurationSec: motionInput.avgDurationSec,\n dutyCyclePercent: (motionInput.avgEventsPerDay * motionInput.avgDurationSec / 86400) * 100,\n } : undefined\n\n for (const sp of policy.streams) {\n const category = `recording:${sp.streamId}` as DataCategory\n const config = this.db.resolveStorageConfig(deviceId, category)\n const retentionDays = config?.retentionDays ?? null\n const retentionGb = config?.retentionGb ?? null\n\n const streamStats = stats?.streams[sp.streamId]\n const observedBitrate = streamStats?.observedBitrateKbps ?? 0\n const bitrateKbps = observedBitrate > 0\n ? observedBitrate\n : (streamStats?.nominalBitrateKbps ?? 4000)\n\n let estimatedGb = 0\n if (retentionDays !== null) {\n const retentionSeconds = retentionDays * 86400\n estimatedGb = (bitrateKbps * retentionSeconds) / 8 / 1024 / 1024 / 1024\n }\n\n if (policy.mode === 'motion' && motionEstimate) {\n estimatedGb = estimatedGb * motionEstimate.dutyCyclePercent / 100\n }\n\n let estimatedDaysAtCapacity: number | null = null\n if (retentionGb !== null && estimatedGb > retentionGb) {\n estimatedDaysAtCapacity = retentionDays !== null ? retentionDays * (retentionGb / estimatedGb) : null\n estimatedGb = retentionGb\n }\n\n perStream[sp.streamId] = { bitrateKbps, retentionDays, retentionGb, estimatedGb, estimatedDaysAtCapacity }\n totalGb += estimatedGb\n }\n\n const thumbRetentionDays = policy.streams[0]\n ? (this.db.resolveStorageConfig(deviceId, 'thumbnail:scrub')?.retentionDays ?? 7)\n : 7\n const thumbGb = (2 * 24 * thumbRetentionDays) / 1024\n totalGb += thumbGb\n\n return { perStream, thumbnails: { estimatedGb: thumbGb }, totalEstimatedGb: totalGb, motionEstimate }\n }\n\n /**\n * Estimate global storage across all devices with active policies.\n * Sums per-device estimates. No motion weighting — uses continuous mode\n * for the global view.\n */\n estimateGlobal(): StorageEstimate {\n const allPolicies = this.db.getEnabledPolicies()\n let totalGb = 0\n const perStream: Record<string, StreamEstimate> = {}\n let totalThumbGb = 0\n\n for (const policy of allPolicies) {\n if (!policy.enabled) continue\n const deviceEstimate = this.estimateForDevice(policy.deviceId)\n totalGb += deviceEstimate.totalEstimatedGb\n totalThumbGb += deviceEstimate.thumbnails.estimatedGb\n for (const [key, val] of Object.entries(deviceEstimate.perStream)) {\n const globalKey = `${policy.deviceId}/${key}`\n perStream[globalKey] = val\n }\n }\n\n return { perStream, thumbnails: { estimatedGb: totalThumbGb }, totalEstimatedGb: totalGb }\n }\n}\n"],"names":[],"mappings":";;AASO,MAAM,iBAAiB;AAAA,EAC5B,YACmB,IACA,gBACjB;AAFiB,SAAA,KAAA;AACA,SAAA,iBAAA;AAAA,EAChB;AAAA,EAEH,kBAAkB,UAAkB,aAAoD;AACtF,UAAM,SAAS,KAAK,GAAG,UAAU,QAAQ;AACzC,QAAI,CAAC,OAAQ,QAAO,EAAE,WAAW,CAAA,GAAI,YAAY,EAAE,aAAa,KAAK,kBAAkB,EAAA;AAEvF,UAAM,QAAQ,KAAK,eAAe,eAAe,QAAQ;AACzD,UAAM,YAA4C,CAAA;AAClD,QAAI,UAAU;AAEd,UAAM,iBAAiB,cAAc;AAAA,MACnC,iBAAiB,YAAY;AAAA,MAC7B,gBAAgB,YAAY;AAAA,MAC5B,kBAAmB,YAAY,kBAAkB,YAAY,iBAAiB,QAAS;AAAA,IAAA,IACrF;AAEJ,eAAW,MAAM,OAAO,SAAS;AAC/B,YAAM,WAAW,aAAa,GAAG,QAAQ;AACzC,YAAM,SAAS,KAAK,GAAG,qBAAqB,UAAU,QAAQ;AAC9D,YAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,YAAM,cAAc,QAAQ,eAAe;AAE3C,YAAM,cAAc,OAAO,QAAQ,GAAG,QAAQ;AAC9C,YAAM,kBAAkB,aAAa,uBAAuB;AAC5D,YAAM,cAAc,kBAAkB,IAClC,kBACC,aAAa,sBAAsB;AAExC,UAAI,cAAc;AAClB,UAAI,kBAAkB,MAAM;AAC1B,cAAM,mBAAmB,gBAAgB;AACzC,sBAAe,cAAc,mBAAoB,IAAI,OAAO,OAAO;AAAA,MACrE;AAEA,UAAI,OAAO,SAAS,YAAY,gBAAgB;AAC9C,sBAAc,cAAc,eAAe,mBAAmB;AAAA,MAChE;AAEA,UAAI,0BAAyC;AAC7C,UAAI,gBAAgB,QAAQ,cAAc,aAAa;AACrD,kCAA0B,kBAAkB,OAAO,iBAAiB,cAAc,eAAe;AACjG,sBAAc;AAAA,MAChB;AAEA,gBAAU,GAAG,QAAQ,IAAI,EAAE,aAAa,eAAe,aAAa,aAAa,wBAAA;AACjF,iBAAW;AAAA,IACb;AAEA,UAAM,qBAAqB,OAAO,QAAQ,CAAC,IACtC,KAAK,GAAG,qBAAqB,UAAU,iBAAiB,GAAG,iBAAiB,IAC7E;AACJ,UAAM,UAAW,IAAI,KAAK,qBAAsB;AAChD,eAAW;AAEX,WAAO,EAAE,WAAW,YAAY,EAAE,aAAa,WAAW,kBAAkB,SAAS,eAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAkC;AAChC,UAAM,cAAc,KAAK,GAAG,mBAAA;AAC5B,QAAI,UAAU;AACd,UAAM,YAA4C,CAAA;AAClD,QAAI,eAAe;AAEnB,eAAW,UAAU,aAAa;AAChC,UAAI,CAAC,OAAO,QAAS;AACrB,YAAM,iBAAiB,KAAK,kBAAkB,OAAO,QAAQ;AAC7D,iBAAW,eAAe;AAC1B,sBAAgB,eAAe,WAAW;AAC1C,iBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,eAAe,SAAS,GAAG;AACjE,cAAM,YAAY,GAAG,OAAO,QAAQ,IAAI,GAAG;AAC3C,kBAAU,SAAS,IAAI;AAAA,MACzB;AAAA,IACF;AAEA,WAAO,EAAE,WAAW,YAAY,EAAE,aAAa,aAAA,GAAgB,kBAAkB,QAAA;AAAA,EACnF;AACF;;"}
@@ -1,72 +0,0 @@
1
- class StorageEstimator {
2
- constructor(db, networkTracker) {
3
- this.db = db;
4
- this.networkTracker = networkTracker;
5
- }
6
- estimateForDevice(deviceId, motionInput) {
7
- const policy = this.db.getPolicy(deviceId);
8
- if (!policy) return { perStream: {}, thumbnails: { estimatedGb: 0 }, totalEstimatedGb: 0 };
9
- const stats = this.networkTracker.getDeviceStats(deviceId);
10
- const perStream = {};
11
- let totalGb = 0;
12
- const motionEstimate = motionInput ? {
13
- avgEventsPerDay: motionInput.avgEventsPerDay,
14
- avgDurationSec: motionInput.avgDurationSec,
15
- dutyCyclePercent: motionInput.avgEventsPerDay * motionInput.avgDurationSec / 86400 * 100
16
- } : void 0;
17
- for (const sp of policy.streams) {
18
- const category = `recording:${sp.streamId}`;
19
- const config = this.db.resolveStorageConfig(deviceId, category);
20
- const retentionDays = config?.retentionDays ?? null;
21
- const retentionGb = config?.retentionGb ?? null;
22
- const streamStats = stats?.streams[sp.streamId];
23
- const observedBitrate = streamStats?.observedBitrateKbps ?? 0;
24
- const bitrateKbps = observedBitrate > 0 ? observedBitrate : streamStats?.nominalBitrateKbps ?? 4e3;
25
- let estimatedGb = 0;
26
- if (retentionDays !== null) {
27
- const retentionSeconds = retentionDays * 86400;
28
- estimatedGb = bitrateKbps * retentionSeconds / 8 / 1024 / 1024 / 1024;
29
- }
30
- if (policy.mode === "motion" && motionEstimate) {
31
- estimatedGb = estimatedGb * motionEstimate.dutyCyclePercent / 100;
32
- }
33
- let estimatedDaysAtCapacity = null;
34
- if (retentionGb !== null && estimatedGb > retentionGb) {
35
- estimatedDaysAtCapacity = retentionDays !== null ? retentionDays * (retentionGb / estimatedGb) : null;
36
- estimatedGb = retentionGb;
37
- }
38
- perStream[sp.streamId] = { bitrateKbps, retentionDays, retentionGb, estimatedGb, estimatedDaysAtCapacity };
39
- totalGb += estimatedGb;
40
- }
41
- const thumbRetentionDays = policy.streams[0] ? this.db.resolveStorageConfig(deviceId, "thumbnail:scrub")?.retentionDays ?? 7 : 7;
42
- const thumbGb = 2 * 24 * thumbRetentionDays / 1024;
43
- totalGb += thumbGb;
44
- return { perStream, thumbnails: { estimatedGb: thumbGb }, totalEstimatedGb: totalGb, motionEstimate };
45
- }
46
- /**
47
- * Estimate global storage across all devices with active policies.
48
- * Sums per-device estimates. No motion weighting — uses continuous mode
49
- * for the global view.
50
- */
51
- estimateGlobal() {
52
- const allPolicies = this.db.getEnabledPolicies();
53
- let totalGb = 0;
54
- const perStream = {};
55
- let totalThumbGb = 0;
56
- for (const policy of allPolicies) {
57
- if (!policy.enabled) continue;
58
- const deviceEstimate = this.estimateForDevice(policy.deviceId);
59
- totalGb += deviceEstimate.totalEstimatedGb;
60
- totalThumbGb += deviceEstimate.thumbnails.estimatedGb;
61
- for (const [key, val] of Object.entries(deviceEstimate.perStream)) {
62
- const globalKey = `${policy.deviceId}/${key}`;
63
- perStream[globalKey] = val;
64
- }
65
- }
66
- return { perStream, thumbnails: { estimatedGb: totalThumbGb }, totalEstimatedGb: totalGb };
67
- }
68
- }
69
- export {
70
- StorageEstimator
71
- };
72
- //# sourceMappingURL=storage-estimator-DzD8gWJH.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-estimator-DzD8gWJH.mjs","sources":["../src/recording/recording/storage-estimator.ts"],"sourcesContent":["import type { INetworkQualityTracker } from '@camstack/types'\nimport type { RecordingDb } from './recording-db.js'\nimport type { DataCategory, StorageEstimate, StreamEstimate } from './types.js'\n\ninterface MotionEstimateInput {\n readonly avgEventsPerDay: number\n readonly avgDurationSec: number\n}\n\nexport class StorageEstimator {\n constructor(\n private readonly db: RecordingDb,\n private readonly networkTracker: INetworkQualityTracker,\n ) {}\n\n estimateForDevice(deviceId: number, motionInput?: MotionEstimateInput): StorageEstimate {\n const policy = this.db.getPolicy(deviceId)\n if (!policy) return { perStream: {}, thumbnails: { estimatedGb: 0 }, totalEstimatedGb: 0 }\n\n const stats = this.networkTracker.getDeviceStats(deviceId)\n const perStream: Record<string, StreamEstimate> = {}\n let totalGb = 0\n\n const motionEstimate = motionInput ? {\n avgEventsPerDay: motionInput.avgEventsPerDay,\n avgDurationSec: motionInput.avgDurationSec,\n dutyCyclePercent: (motionInput.avgEventsPerDay * motionInput.avgDurationSec / 86400) * 100,\n } : undefined\n\n for (const sp of policy.streams) {\n const category = `recording:${sp.streamId}` as DataCategory\n const config = this.db.resolveStorageConfig(deviceId, category)\n const retentionDays = config?.retentionDays ?? null\n const retentionGb = config?.retentionGb ?? null\n\n const streamStats = stats?.streams[sp.streamId]\n const observedBitrate = streamStats?.observedBitrateKbps ?? 0\n const bitrateKbps = observedBitrate > 0\n ? observedBitrate\n : (streamStats?.nominalBitrateKbps ?? 4000)\n\n let estimatedGb = 0\n if (retentionDays !== null) {\n const retentionSeconds = retentionDays * 86400\n estimatedGb = (bitrateKbps * retentionSeconds) / 8 / 1024 / 1024 / 1024\n }\n\n if (policy.mode === 'motion' && motionEstimate) {\n estimatedGb = estimatedGb * motionEstimate.dutyCyclePercent / 100\n }\n\n let estimatedDaysAtCapacity: number | null = null\n if (retentionGb !== null && estimatedGb > retentionGb) {\n estimatedDaysAtCapacity = retentionDays !== null ? retentionDays * (retentionGb / estimatedGb) : null\n estimatedGb = retentionGb\n }\n\n perStream[sp.streamId] = { bitrateKbps, retentionDays, retentionGb, estimatedGb, estimatedDaysAtCapacity }\n totalGb += estimatedGb\n }\n\n const thumbRetentionDays = policy.streams[0]\n ? (this.db.resolveStorageConfig(deviceId, 'thumbnail:scrub')?.retentionDays ?? 7)\n : 7\n const thumbGb = (2 * 24 * thumbRetentionDays) / 1024\n totalGb += thumbGb\n\n return { perStream, thumbnails: { estimatedGb: thumbGb }, totalEstimatedGb: totalGb, motionEstimate }\n }\n\n /**\n * Estimate global storage across all devices with active policies.\n * Sums per-device estimates. No motion weighting — uses continuous mode\n * for the global view.\n */\n estimateGlobal(): StorageEstimate {\n const allPolicies = this.db.getEnabledPolicies()\n let totalGb = 0\n const perStream: Record<string, StreamEstimate> = {}\n let totalThumbGb = 0\n\n for (const policy of allPolicies) {\n if (!policy.enabled) continue\n const deviceEstimate = this.estimateForDevice(policy.deviceId)\n totalGb += deviceEstimate.totalEstimatedGb\n totalThumbGb += deviceEstimate.thumbnails.estimatedGb\n for (const [key, val] of Object.entries(deviceEstimate.perStream)) {\n const globalKey = `${policy.deviceId}/${key}`\n perStream[globalKey] = val\n }\n }\n\n return { perStream, thumbnails: { estimatedGb: totalThumbGb }, totalEstimatedGb: totalGb }\n }\n}\n"],"names":[],"mappings":"AASO,MAAM,iBAAiB;AAAA,EAC5B,YACmB,IACA,gBACjB;AAFiB,SAAA,KAAA;AACA,SAAA,iBAAA;AAAA,EAChB;AAAA,EAEH,kBAAkB,UAAkB,aAAoD;AACtF,UAAM,SAAS,KAAK,GAAG,UAAU,QAAQ;AACzC,QAAI,CAAC,OAAQ,QAAO,EAAE,WAAW,CAAA,GAAI,YAAY,EAAE,aAAa,KAAK,kBAAkB,EAAA;AAEvF,UAAM,QAAQ,KAAK,eAAe,eAAe,QAAQ;AACzD,UAAM,YAA4C,CAAA;AAClD,QAAI,UAAU;AAEd,UAAM,iBAAiB,cAAc;AAAA,MACnC,iBAAiB,YAAY;AAAA,MAC7B,gBAAgB,YAAY;AAAA,MAC5B,kBAAmB,YAAY,kBAAkB,YAAY,iBAAiB,QAAS;AAAA,IAAA,IACrF;AAEJ,eAAW,MAAM,OAAO,SAAS;AAC/B,YAAM,WAAW,aAAa,GAAG,QAAQ;AACzC,YAAM,SAAS,KAAK,GAAG,qBAAqB,UAAU,QAAQ;AAC9D,YAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,YAAM,cAAc,QAAQ,eAAe;AAE3C,YAAM,cAAc,OAAO,QAAQ,GAAG,QAAQ;AAC9C,YAAM,kBAAkB,aAAa,uBAAuB;AAC5D,YAAM,cAAc,kBAAkB,IAClC,kBACC,aAAa,sBAAsB;AAExC,UAAI,cAAc;AAClB,UAAI,kBAAkB,MAAM;AAC1B,cAAM,mBAAmB,gBAAgB;AACzC,sBAAe,cAAc,mBAAoB,IAAI,OAAO,OAAO;AAAA,MACrE;AAEA,UAAI,OAAO,SAAS,YAAY,gBAAgB;AAC9C,sBAAc,cAAc,eAAe,mBAAmB;AAAA,MAChE;AAEA,UAAI,0BAAyC;AAC7C,UAAI,gBAAgB,QAAQ,cAAc,aAAa;AACrD,kCAA0B,kBAAkB,OAAO,iBAAiB,cAAc,eAAe;AACjG,sBAAc;AAAA,MAChB;AAEA,gBAAU,GAAG,QAAQ,IAAI,EAAE,aAAa,eAAe,aAAa,aAAa,wBAAA;AACjF,iBAAW;AAAA,IACb;AAEA,UAAM,qBAAqB,OAAO,QAAQ,CAAC,IACtC,KAAK,GAAG,qBAAqB,UAAU,iBAAiB,GAAG,iBAAiB,IAC7E;AACJ,UAAM,UAAW,IAAI,KAAK,qBAAsB;AAChD,eAAW;AAEX,WAAO,EAAE,WAAW,YAAY,EAAE,aAAa,WAAW,kBAAkB,SAAS,eAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAkC;AAChC,UAAM,cAAc,KAAK,GAAG,mBAAA;AAC5B,QAAI,UAAU;AACd,UAAM,YAA4C,CAAA;AAClD,QAAI,eAAe;AAEnB,eAAW,UAAU,aAAa;AAChC,UAAI,CAAC,OAAO,QAAS;AACrB,YAAM,iBAAiB,KAAK,kBAAkB,OAAO,QAAQ;AAC7D,iBAAW,eAAe;AAC1B,sBAAgB,eAAe,WAAW;AAC1C,iBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,eAAe,SAAS,GAAG;AACjE,cAAM,YAAY,GAAG,OAAO,QAAQ,IAAI,GAAG;AAC3C,kBAAU,SAAS,IAAI;AAAA,MACzB;AAAA,IACF;AAEA,WAAO,EAAE,WAAW,YAAY,EAAE,aAAa,aAAA,GAAgB,kBAAkB,QAAA;AAAA,EACnF;AACF;"}