@camstack/ui-library 1.2.256 → 1.2.258
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/composites/accelerator-label.d.ts +9 -9
- package/dist/composites/adaptive-downlink.d.ts +141 -143
- package/dist/composites/addon-global-settings-form.d.ts +73 -60
- package/dist/composites/addon-page-props.d.ts +34 -10
- package/dist/composites/agent-step-editor.d.ts +48 -47
- package/dist/composites/app-shell/app-shell.d.ts +17 -17
- package/dist/composites/app-shell/index.d.ts +3 -3
- package/dist/composites/app-shell/sidebar-item.d.ts +9 -8
- package/dist/composites/app-shell/sidebar.d.ts +10 -10
- package/dist/composites/audio-classification-list.d.ts +16 -15
- package/dist/composites/audio-level-waveform.d.ts +31 -30
- package/dist/composites/audio-waveform.d.ts +18 -17
- package/dist/composites/battery-badge.d.ts +27 -13
- package/dist/composites/breadcrumb.d.ts +21 -21
- package/dist/composites/camera-stream-player.d.ts +309 -309
- package/dist/composites/cap-settings/AutotrackSection.d.ts +19 -2
- package/dist/composites/cap-settings/CameraGridLayoutEditor.d.ts +24 -2
- package/dist/composites/cap-settings/ConsumablesPanel.d.ts +21 -2
- package/dist/composites/cap-settings/CoverageTrack.d.ts +21 -20
- package/dist/composites/cap-settings/EventBucketStrip.d.ts +21 -20
- package/dist/composites/cap-settings/EventHeatmap.d.ts +8 -7
- package/dist/composites/cap-settings/HomePresetPicker.d.ts +2 -2
- package/dist/composites/cap-settings/MaskShapeCanvas.d.ts +143 -41
- package/dist/composites/cap-settings/MotionZonesSettings.d.ts +41 -2
- package/dist/composites/cap-settings/NavigationPanel.d.ts +14 -2
- package/dist/composites/cap-settings/PrivacyMaskSettings.d.ts +3 -2
- package/dist/composites/cap-settings/PtzPanel.d.ts +15 -2
- package/dist/composites/cap-settings/RecordingBandsEditor.d.ts +33 -32
- package/dist/composites/cap-settings/RecordingPanel.d.ts +3 -2
- package/dist/composites/cap-settings/RecordingSettings.d.ts +11 -10
- package/dist/composites/cap-settings/RecordingTimeline.d.ts +3 -2
- package/dist/composites/cap-settings/SceneMonitorEditor.d.ts +3 -51
- package/dist/composites/cap-settings/SceneReferenceGallery.d.ts +62 -23
- package/dist/composites/cap-settings/SceneSettingsForm.d.ts +52 -16
- package/dist/composites/cap-settings/TimelineControls.d.ts +21 -20
- package/dist/composites/cap-settings/camera-grid-layout.d.ts +95 -95
- package/dist/composites/cap-settings/event-thumb.d.ts +9 -8
- package/dist/composites/cap-settings/index.d.ts +20 -20
- package/dist/composites/cap-settings/privacy-mask-audio.d.ts +47 -47
- package/dist/composites/cap-settings/recording-config-form.d.ts +25 -25
- package/dist/composites/cap-settings/recording-spans.d.ts +14 -14
- package/dist/composites/cap-settings/recording-timeline-model.d.ts +57 -57
- package/dist/composites/cap-settings/scene-monitor-copy.d.ts +58 -49
- package/dist/composites/client-network-sample.d.ts +41 -41
- package/dist/composites/clips/ClipBandBar.d.ts +44 -14
- package/dist/composites/clips/ClipPanel.d.ts +30 -6
- package/dist/composites/clips/ClipTile.d.ts +26 -5
- package/dist/composites/clips/ClipsSection.d.ts +107 -2
- package/dist/composites/clips/clip-band.d.ts +72 -38
- package/dist/composites/clips/clip-day-window.d.ts +7 -30
- package/dist/composites/clips/clip-source-state.d.ts +55 -26
- package/dist/composites/clips/clip-still-retry.d.ts +39 -39
- package/dist/composites/clips/clip-thumbnail-fetch.d.ts +9 -9
- package/dist/composites/clips/clip-tile-media.d.ts +64 -32
- package/dist/composites/clips/clip-view-state.d.ts +76 -46
- package/dist/composites/code-block.d.ts +5 -4
- package/dist/composites/config-form-builder.d.ts +14 -13
- package/dist/composites/config-form-field.d.ts +63 -62
- package/dist/composites/config-icon-field.d.ts +10 -9
- package/dist/composites/config-secret-field.d.ts +51 -27
- package/dist/composites/confirm-action-button.d.ts +52 -39
- package/dist/composites/confirm-dialog.d.ts +110 -48
- package/dist/composites/copy-button.d.ts +25 -19
- package/dist/composites/data-table/data-table-header.d.ts +8 -7
- package/dist/composites/data-table/data-table-pagination.d.ts +7 -6
- package/dist/composites/data-table/data-table-row.d.ts +8 -7
- package/dist/composites/data-table/data-table.d.ts +3 -2
- package/dist/composites/data-table/index.d.ts +2 -2
- package/dist/composites/data-table/types.d.ts +29 -29
- package/dist/composites/data-table-filter-bar.d.ts +30 -29
- package/dist/composites/data-table-filter.d.ts +34 -34
- package/dist/composites/data-table-layout.d.ts +24 -24
- package/dist/composites/data-table-pager.d.ts +5 -5
- package/dist/composites/data-table-pagination.d.ts +23 -23
- package/dist/composites/data-table-selection.d.ts +10 -10
- package/dist/composites/data-table.d.ts +167 -118
- package/dist/composites/detection-canvas.d.ts +34 -25
- package/dist/composites/detection-colors.d.ts +9 -9
- package/dist/composites/detection-overlay.d.ts +33 -32
- package/dist/composites/detection-result-tree.d.ts +22 -9
- package/dist/composites/dev-shell.d.ts +15 -14
- package/dist/composites/device-activity-panel.d.ts +37 -31
- package/dist/composites/device-card.d.ts +32 -32
- package/dist/composites/device-controls/ac-panel.d.ts +2 -2
- package/dist/composites/device-controls/alarm-hero-card.d.ts +42 -42
- package/dist/composites/device-controls/atoms.d.ts +50 -50
- package/dist/composites/device-controls/brightness-panel.d.ts +3 -3
- package/dist/composites/device-controls/button-control.d.ts +14 -14
- package/dist/composites/device-controls/climate-panel.d.ts +12 -12
- package/dist/composites/device-controls/container-primary-hero.d.ts +33 -16
- package/dist/composites/device-controls/container-primary.d.ts +68 -39
- package/dist/composites/device-controls/control-panel.d.ts +4 -4
- package/dist/composites/device-controls/control-registry.d.ts +81 -70
- package/dist/composites/device-controls/cover-hero-card.d.ts +26 -26
- package/dist/composites/device-controls/cover-inline.d.ts +20 -20
- package/dist/composites/device-controls/cover-panel.d.ts +2 -2
- package/dist/composites/device-controls/dummy-hero-card.d.ts +2 -2
- package/dist/composites/device-controls/fan-hero-card.d.ts +20 -20
- package/dist/composites/device-controls/fan-panel.d.ts +3 -3
- package/dist/composites/device-controls/humidifier-control.d.ts +46 -29
- package/dist/composites/device-controls/image-control.d.ts +41 -27
- package/dist/composites/device-controls/index.d.ts +34 -34
- package/dist/composites/device-controls/lawn-mower-control.d.ts +30 -16
- package/dist/composites/device-controls/light-hero-card.d.ts +15 -15
- package/dist/composites/device-controls/lock-hero-card.d.ts +14 -14
- package/dist/composites/device-controls/lock-panel.d.ts +3 -3
- package/dist/composites/device-controls/media-player-hero-card.d.ts +16 -16
- package/dist/composites/device-controls/media-player-panel.d.ts +7 -7
- package/dist/composites/device-controls/offline-badge.d.ts +23 -8
- package/dist/composites/device-controls/panel-controls.d.ts +39 -20
- package/dist/composites/device-controls/pet-feeder-panel.d.ts +27 -9
- package/dist/composites/device-controls/popover-row-action.d.ts +18 -6
- package/dist/composites/device-controls/primary-child-picker.d.ts +31 -15
- package/dist/composites/device-controls/primary-child.d.ts +14 -25
- package/dist/composites/device-controls/radial-gauge.d.ts +17 -17
- package/dist/composites/device-controls/script-automation-controls.d.ts +9 -9
- package/dist/composites/device-controls/sensor-hero-card.d.ts +26 -8
- package/dist/composites/device-controls/sensor-inline-control.d.ts +21 -9
- package/dist/composites/device-controls/sensor-value-atom.d.ts +97 -76
- package/dist/composites/device-controls/switch-hero-card.d.ts +11 -11
- package/dist/composites/device-controls/switch-panel.d.ts +2 -2
- package/dist/composites/device-controls/tap-toggle.d.ts +13 -13
- package/dist/composites/device-controls/thermostat-hero-card.d.ts +16 -16
- package/dist/composites/device-controls/types.d.ts +11 -11
- package/dist/composites/device-controls/update-control.d.ts +20 -7
- package/dist/composites/device-controls/vacuum-control.d.ts +41 -25
- package/dist/composites/device-controls/valve-control.d.ts +51 -35
- package/dist/composites/device-controls/water-heater-control.d.ts +48 -31
- package/dist/composites/device-controls/weather-control.d.ts +46 -28
- package/dist/composites/device-export-panel.d.ts +34 -34
- package/dist/composites/device-grid.d.ts +10 -10
- package/dist/composites/device-item/actions.d.ts +40 -18
- package/dist/composites/device-item/admin-link-quick-action.d.ts +66 -26
- package/dist/composites/device-item/child-layout.d.ts +43 -26
- package/dist/composites/device-item/child-section-accordion.d.ts +20 -6
- package/dist/composites/device-item/children-accordion.d.ts +11 -11
- package/dist/composites/device-item/container-children-context.d.ts +28 -11
- package/dist/composites/device-item/device-delete-action.d.ts +23 -5
- package/dist/composites/device-item/features.d.ts +33 -15
- package/dist/composites/device-item/header.d.ts +53 -31
- package/dist/composites/device-item/helpers.d.ts +291 -274
- package/dist/composites/device-item/index.d.ts +18 -9
- package/dist/composites/device-item/preview.d.ts +41 -21
- package/dist/composites/device-item/quick-detail-action.d.ts +4 -4
- package/dist/composites/device-item/reboot-quick-action.d.ts +28 -7
- package/dist/composites/device-item/role-display-defaults-context.d.ts +28 -12
- package/dist/composites/device-item/status-dot.d.ts +24 -6
- package/dist/composites/device-list/batch-actions-bar.d.ts +23 -12
- package/dist/composites/device-list/batch-toolbar.d.ts +13 -13
- package/dist/composites/device-list/columns.d.ts +108 -108
- package/dist/composites/device-list/device-integration.d.ts +48 -58
- package/dist/composites/device-list/device-mode.d.ts +121 -121
- package/dist/composites/device-list/empty-state.d.ts +14 -3
- package/dist/composites/device-list/filter-chips.d.ts +42 -29
- package/dist/composites/device-list/fuzzy-match.d.ts +22 -22
- package/dist/composites/device-list/generic-mode.d.ts +88 -88
- package/dist/composites/device-list/group.d.ts +62 -35
- package/dist/composites/device-list/hardware-cell.d.ts +14 -3
- package/dist/composites/device-list/hardware.d.ts +29 -11
- package/dist/composites/device-list/icon-action.d.ts +27 -15
- package/dist/composites/device-list/index.d.ts +46 -23
- package/dist/composites/device-list/multi-select.d.ts +17 -17
- package/dist/composites/device-list/page-size-select.d.ts +13 -7
- package/dist/composites/device-list/pagination.d.ts +19 -12
- package/dist/composites/device-list/sort.d.ts +28 -15
- package/dist/composites/device-list/sortable-header.d.ts +20 -7
- package/dist/composites/device-list/table-layout.d.ts +44 -44
- package/dist/composites/device-list/type-filter.d.ts +16 -16
- package/dist/composites/device-list/url-state.d.ts +35 -35
- package/dist/composites/device-meta.d.ts +43 -43
- package/dist/composites/device-picker/DevicePicker.d.ts +72 -33
- package/dist/composites/device-picker/SelectedChip.d.ts +10 -9
- package/dist/composites/device-picker/device-filter-bar.d.ts +19 -18
- package/dist/composites/device-picker/device-fleet-view.d.ts +11 -3
- package/dist/composites/device-picker/device-parent.d.ts +27 -27
- package/dist/composites/device-picker/device-picker-grouping.d.ts +3 -3
- package/dist/composites/device-picker/device-picker-model.d.ts +140 -140
- package/dist/composites/device-picker/device-selection-rows.d.ts +31 -24
- package/dist/composites/device-picker/device-selection.d.ts +43 -43
- package/dist/composites/device-picker/index.d.ts +9 -9
- package/dist/composites/device-select-field.d.ts +17 -16
- package/dist/composites/device-select-filter.d.ts +78 -78
- package/dist/composites/device-selector-picker.d.ts +25 -25
- package/dist/composites/device-step-matrix.d.ts +54 -28
- package/dist/composites/discovery-panel.d.ts +22 -22
- package/dist/composites/doorbell-recent-panel.d.ts +9 -8
- package/dist/composites/empty-state.d.ts +8 -8
- package/dist/composites/error-box.d.ts +32 -17
- package/dist/composites/event-kind-visuals.d.ts +29 -18
- package/dist/composites/event-stream.d.ts +59 -42
- package/dist/composites/extensions/AssociationSlotCard.d.ts +45 -24
- package/dist/composites/extensions/ExtensionsPanel.d.ts +41 -18
- package/dist/composites/extensions/extensions-view-state.d.ts +71 -53
- package/dist/composites/filter-bar.d.ts +22 -21
- package/dist/composites/form-field.d.ts +9 -9
- package/dist/composites/format-state-value.d.ts +23 -51
- package/dist/composites/grouped-model-selector.d.ts +7 -6
- package/dist/composites/hls-quality.d.ts +26 -26
- package/dist/composites/hls-video.d.ts +62 -39
- package/dist/composites/hover-zoom-image.d.ts +35 -16
- package/dist/composites/icon-picker.d.ts +86 -50
- package/dist/composites/image-selector.d.ts +21 -20
- package/dist/composites/index.d.ts +204 -204
- package/dist/composites/inference-config-selector.d.ts +36 -35
- package/dist/composites/kebab-menu.d.ts +53 -35
- package/dist/composites/key-value-list.d.ts +14 -14
- package/dist/composites/log-stream-scroll.d.ts +24 -24
- package/dist/composites/log-stream.d.ts +81 -70
- package/dist/composites/login-form.d.ts +7 -6
- package/dist/composites/model-bound-slider.d.ts +46 -26
- package/dist/composites/model-picker.d.ts +20 -19
- package/dist/composites/mount-addon-page.d.ts +12 -12
- package/dist/composites/network-link-badge.d.ts +7 -6
- package/dist/composites/node-picker.d.ts +14 -13
- package/dist/composites/notification-targets-field.d.ts +76 -58
- package/dist/composites/notification-targets-options.d.ts +9 -6
- package/dist/composites/option-select/OptionSelect.d.ts +23 -22
- package/dist/composites/option-select/index.d.ts +4 -4
- package/dist/composites/option-select/option-select-model.d.ts +35 -35
- package/dist/composites/page-header.d.ts +6 -6
- package/dist/composites/peer-connection-config.d.ts +9 -9
- package/dist/composites/phase-icon.d.ts +10 -3
- package/dist/composites/pipeline-builder.d.ts +21 -13
- package/dist/composites/pipeline-matrix-shared.d.ts +159 -150
- package/dist/composites/pipeline-runtime-selector.d.ts +12 -11
- package/dist/composites/pipeline-step.d.ts +39 -31
- package/dist/composites/placeholder-field/PlaceholderChipField.d.ts +23 -22
- package/dist/composites/placeholder-field/index.d.ts +1 -1
- package/dist/composites/provider-badge.d.ts +6 -5
- package/dist/composites/ptz-overlay.d.ts +38 -18
- package/dist/composites/qr-code.d.ts +24 -10
- package/dist/composites/reconnect-schedule.d.ts +22 -22
- package/dist/composites/resolve-step-default-model.d.ts +94 -94
- package/dist/composites/response-log.d.ts +7 -6
- package/dist/composites/root-model-source.d.ts +21 -10
- package/dist/composites/scope-picker.d.ts +49 -25
- package/dist/composites/section-card.d.ts +19 -11
- package/dist/composites/setting-row.d.ts +39 -21
- package/dist/composites/snapshot-button.d.ts +23 -19
- package/dist/composites/sort-header-button.d.ts +25 -8
- package/dist/composites/stat-card.d.ts +20 -8
- package/dist/composites/state-values-stream.d.ts +49 -24
- package/dist/composites/status-badge.d.ts +10 -8
- package/dist/composites/step-inspector/gate-control.d.ts +13 -12
- package/dist/composites/step-inspector/index.d.ts +8 -8
- package/dist/composites/step-inspector/layered-settings-form.d.ts +41 -30
- package/dist/composites/step-inspector/segmented-choice.d.ts +8 -7
- package/dist/composites/step-inspector/setting-values.d.ts +13 -8
- package/dist/composites/step-inspector/step-detail-dock.d.ts +39 -23
- package/dist/composites/step-inspector/step-inspector-panel.d.ts +34 -28
- package/dist/composites/step-inspector/step-model-row.d.ts +29 -24
- package/dist/composites/step-inspector/step-search.d.ts +11 -11
- package/dist/composites/step-timings.d.ts +7 -6
- package/dist/composites/step-tree.d.ts +17 -12
- package/dist/composites/stream-broker-selector.d.ts +29 -8
- package/dist/composites/stream-debug/stream-debug-overlay.d.ts +40 -40
- package/dist/composites/stream-debug/webrtc-debug-stats.d.ts +144 -129
- package/dist/composites/stream-panel.d.ts +212 -201
- package/dist/composites/table-sort.d.ts +61 -61
- package/dist/composites/timezone-selector.d.ts +15 -13
- package/dist/composites/training/send-frame-to-training.d.ts +5 -4
- package/dist/composites/training/training-collection-picker.d.ts +4 -3
- package/dist/composites/training/training-refusal-text.d.ts +6 -6
- package/dist/composites/unit-picker/UnitPicker.d.ts +19 -14
- package/dist/composites/unit-picker/index.d.ts +1 -1
- package/dist/composites/use-data-table-filter.d.ts +19 -19
- package/dist/composites/version-badge.d.ts +19 -18
- package/dist/composites/webrtc-diagnostics/EndpointTestCard.d.ts +7 -7
- package/dist/composites/webrtc-diagnostics/HubSessionTestCard.d.ts +14 -14
- package/dist/composites/webrtc-diagnostics/RunReport.d.ts +10 -5
- package/dist/composites/webrtc-diagnostics/endpoint-probe.d.ts +41 -21
- package/dist/composites/webrtc-diagnostics/endpoint-test.d.ts +37 -32
- package/dist/composites/webrtc-diagnostics/format.d.ts +3 -3
- package/dist/composites/webrtc-diagnostics/ice-candidates.d.ts +49 -49
- package/dist/composites/webrtc-diagnostics/nat-mapping.d.ts +36 -36
- package/dist/composites/webrtc-diagnostics/session-run.d.ts +108 -95
- package/dist/composites/webrtc-diagnostics/session-verdict.d.ts +29 -20
- package/dist/composites/widget-panel.d.ts +23 -23
- package/dist/composites/widget-slot.d.ts +35 -17
- package/dist/contexts/custom-field-renderers.d.ts +53 -17
- package/dist/contexts/device-context.d.ts +32 -12
- package/dist/contexts/device-quick-detail.d.ts +13 -4
- package/dist/contexts/player-overlays.d.ts +82 -42
- package/dist/contexts/recorded-playback.d.ts +40 -18
- package/dist/contexts/system-context.d.ts +28 -13
- package/dist/contexts/vod-playback.d.ts +39 -22
- package/dist/contexts/widget-registry.d.ts +139 -102
- package/dist/contexts/zone-editing.d.ts +69 -46
- package/dist/generated/system-hooks.d.ts +17 -1
- package/dist/hooks/index.d.ts +43 -43
- package/dist/hooks/turn-server-cache.d.ts +69 -69
- package/dist/hooks/use-capability-presence.d.ts +65 -28
- package/dist/hooks/use-cluster-nodes.d.ts +54 -27
- package/dist/hooks/use-device-autotrack.d.ts +7 -7
- package/dist/hooks/use-device-battery.d.ts +24 -11
- package/dist/hooks/use-device-cap-slice.d.ts +15 -15
- package/dist/hooks/use-device-capability.d.ts +61 -27
- package/dist/hooks/use-device-detections.d.ts +32 -32
- package/dist/hooks/use-device-features.d.ts +18 -18
- package/dist/hooks/use-device-list-page-size.d.ts +19 -6
- package/dist/hooks/use-device-network-link.d.ts +15 -7
- package/dist/hooks/use-device-proxy.d.ts +98 -92
- package/dist/hooks/use-device-snapshot.d.ts +23 -23
- package/dist/hooks/use-device-webrtc.d.ts +211 -205
- package/dist/hooks/use-devices.d.ts +9 -9
- package/dist/hooks/use-doorbell-events.d.ts +13 -13
- package/dist/hooks/use-event-stream.d.ts +6 -3
- package/dist/hooks/use-is-mobile.d.ts +5 -5
- package/dist/hooks/use-live-buffer.d.ts +5 -5
- package/dist/hooks/use-live-event.d.ts +1 -1
- package/dist/hooks/use-navigation.d.ts +20 -20
- package/dist/hooks/use-optimistic-slice.d.ts +13 -13
- package/dist/hooks/use-persisted-page-size.d.ts +10 -10
- package/dist/hooks/use-ptz.d.ts +108 -108
- package/dist/hooks/use-stationary-overlay.d.ts +37 -37
- package/dist/hooks/use-system-query.d.ts +33 -10
- package/dist/hooks/use-url-query.d.ts +3 -3
- package/dist/icons/index.d.ts +2 -2
- package/dist/icons/provider-icons.d.ts +2 -2
- package/dist/icons/status-icons.d.ts +2 -2
- package/dist/index.cjs +123 -69
- package/dist/index.d.ts +31 -27
- package/dist/index.js +123 -69
- package/dist/lib/cap-error.d.ts +18 -39
- package/dist/lib/cn.d.ts +1 -1
- package/dist/lib/fleet-query-defaults.d.ts +68 -34
- package/dist/lib/format-control-datetime.d.ts +16 -16
- package/dist/lib/format-duration.d.ts +12 -12
- package/dist/lib/format-last-seen.d.ts +5 -18
- package/dist/lib/format-numeric.d.ts +7 -7
- package/dist/lib/hub-mount.d.ts +8 -42
- package/dist/lib/index.d.ts +21 -21
- package/dist/lib/phase-config.d.ts +24 -11
- package/dist/lib/pipeline-mirror.d.ts +16 -16
- package/dist/lib/recorded-control-protocol.d.ts +41 -43
- package/dist/lib/resolve-sensor-display.d.ts +36 -20
- package/dist/lib/responsive.d.ts +54 -54
- package/dist/lib/scrub-controller.d.ts +75 -78
- package/dist/lib/shared-context.d.ts +27 -2
- package/dist/lib/tailwind-variants.d.ts +20 -20
- package/dist/primitives/badge.d.ts +5 -10
- package/dist/primitives/bottom-sheet.d.ts +7 -7
- package/dist/primitives/button.d.ts +5 -9
- package/dist/primitives/card.d.ts +4 -8
- package/dist/primitives/checkbox.d.ts +3 -4
- package/dist/primitives/collapsible-card.d.ts +23 -13
- package/dist/primitives/dialog.d.ts +33 -59
- package/dist/primitives/dropdown.d.ts +13 -13
- package/dist/primitives/floating-panel.d.ts +41 -20
- package/dist/primitives/icon-button.d.ts +8 -12
- package/dist/primitives/index.d.ts +22 -22
- package/dist/primitives/input.d.ts +6 -16
- package/dist/primitives/label.d.ts +3 -4
- package/dist/primitives/mobile-drawer.d.ts +8 -8
- package/dist/primitives/password-input.d.ts +18 -18
- package/dist/primitives/popover.d.ts +7 -7
- package/dist/primitives/scroll-area.d.ts +3 -4
- package/dist/primitives/select.d.ts +20 -20
- package/dist/primitives/separator.d.ts +4 -8
- package/dist/primitives/skeleton.d.ts +3 -4
- package/dist/primitives/switch.d.ts +6 -6
- package/dist/primitives/tabs.d.ts +26 -26
- package/dist/primitives/tooltip.d.ts +12 -12
- package/dist/theme/create-theme.d.ts +1 -1
- package/dist/theme/defaults.d.ts +1 -1
- package/dist/theme/index.d.ts +6 -6
- package/dist/theme/theme-provider.d.ts +8 -7
- package/dist/theme/theme-to-css.d.ts +1 -1
- package/dist/theme/types.d.ts +98 -100
- package/dist/theme/use-theme-mode.d.ts +1 -1
- package/dist/trpc-react.d.ts +23 -3
- package/dist/widgets/host-widgets.d.ts +4 -4
- package/package.json +8 -4
- package/src/tailwind/camstack-theme.css +11 -0
- package/dist/composites/unit-picker/UnitPicker.spec.d.ts +0 -1
|
@@ -1,16 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The clips section's timebar — the recording section's own controls, driving
|
|
3
|
+
* a clip list instead of a player (D564).
|
|
4
|
+
*
|
|
5
|
+
* *"Possiamo utilizzare lo stesso componente della sezione recording con la
|
|
6
|
+
* timebar dove selezionare un periodo e mostrare le clip solo di quella banda
|
|
7
|
+
* selezionata, espandibile."* [We can use the same component as the recording section with the timebar where a period can be selected and show the clips of that selected band only, expandable.] — the operator, 2026-09-20. So this is not a
|
|
8
|
+
* second timebar: it is `TimelineControls` and `EventHeatmap`, the two pieces
|
|
9
|
+
* `RecordingTimeline` is itself built from, over the same
|
|
10
|
+
* `recording-timeline-model` (`dayWindow`, `panWindow`,
|
|
11
|
+
* `zoomWindowAnchoredRight`, `bucketMsForSpan`, `axisTicks`). One
|
|
12
|
+
* implementation, one model, two surfaces.
|
|
13
|
+
*
|
|
14
|
+
* ## What it does NOT take from the recording timeline
|
|
15
|
+
*
|
|
16
|
+
* `CoverageTrack` stays behind. There it is the seek surface — a click drives
|
|
17
|
+
* the hero player through the `camstack-control` channel or an HLS VOD
|
|
18
|
+
* request. A copy here would either be a dead bar or a SECOND thing claiming
|
|
19
|
+
* to move the playhead, and two components holding two ideas of the same
|
|
20
|
+
* position is the defect this repo keeps paying for. The clips section plays a
|
|
21
|
+
* clip through `ClipPanel`, which is its own, already-shipped path.
|
|
22
|
+
*
|
|
23
|
+
* ## This component is presentational
|
|
24
|
+
*
|
|
25
|
+
* It holds no state. The day, the visible window and the picked bucket all
|
|
26
|
+
* live in `ClipsSection`, because that is where the band is turned into the
|
|
27
|
+
* `listClips` argument — a bar that kept its own copy of the selection would
|
|
28
|
+
* be the second authority again, one component down.
|
|
29
|
+
*/
|
|
30
|
+
import { type JSX } from "react";
|
|
31
|
+
import { type DayWindow, type DensityBucket } from "../cap-settings/recording-timeline-model.js";
|
|
2
32
|
export interface ClipBandBarProps {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
33
|
+
/** The calendar day the window is inside. */
|
|
34
|
+
readonly day: Date;
|
|
35
|
+
readonly onDayChange: (day: Date) => void;
|
|
36
|
+
/** The visible window — the band, whenever no bucket is picked. */
|
|
37
|
+
readonly view: DayWindow;
|
|
38
|
+
/** The full day, the clamp for every zoom and pan. */
|
|
39
|
+
readonly dayBounds: DayWindow;
|
|
40
|
+
readonly onViewChange: (view: DayWindow) => void;
|
|
41
|
+
readonly buckets: readonly DensityBucket[];
|
|
42
|
+
readonly selectedBucketIndex: number | null;
|
|
43
|
+
readonly onSelectBucket: (index: number) => void;
|
|
44
|
+
readonly densityLoading: boolean;
|
|
15
45
|
}
|
|
16
|
-
export declare function ClipBandBar({ day, onDayChange, view, dayBounds, onViewChange, buckets, selectedBucketIndex, onSelectBucket, densityLoading
|
|
46
|
+
export declare function ClipBandBar({ day, onDayChange, view, dayBounds, onViewChange, buckets, selectedBucketIndex, onSelectBucket, densityLoading }: ClipBandBarProps): JSX.Element;
|
|
@@ -1,8 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The selected clip — what it is, how it plays, and how it is saved.
|
|
3
|
+
*
|
|
4
|
+
* **No second player.** `getClipPlayback` answers `{ playbackUrl, format,
|
|
5
|
+
* served }` and the panel hands it to the SAME hero the recordings timeline
|
|
6
|
+
* drives: `vod.play({ url, format })` → `StreamPanel playbackUrl/playbackFormat`
|
|
7
|
+
* → `HlsVideo`'s `mp4` branch (`video.src`, no hls.js). Building a clip player
|
|
8
|
+
* here is the thing D549 decision 22 exists to refuse.
|
|
9
|
+
*
|
|
10
|
+
* **`format` travels.** An MP4 handed to hls.js is parsed as a manifest and
|
|
11
|
+
* fails, so the format the provider named is forwarded verbatim and never
|
|
12
|
+
* defaulted here.
|
|
13
|
+
*
|
|
14
|
+
* **`served` is shown.** A clip that holds only one twin answers with the one
|
|
15
|
+
* it has, and the surface SAYS so — a missing main twin must never be served
|
|
16
|
+
* silently as if it were the asked-for quality (D549 decision 15). Both ids
|
|
17
|
+
* are already on the row, so changing quality re-asks the hub and never
|
|
18
|
+
* re-searches the camera.
|
|
19
|
+
*
|
|
20
|
+
* **Nothing is appended to the URL.** The route is `access:'authenticated'`
|
|
21
|
+
* and the session cookie authenticates it (D549 decision 22); the same URL is
|
|
22
|
+
* the download.
|
|
23
|
+
*/
|
|
24
|
+
import { type JSX } from "react";
|
|
25
|
+
import type { CamProfile, Clip } from "@camstack/types";
|
|
2
26
|
export interface ClipPanelProps {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
27
|
+
readonly deviceId: number;
|
|
28
|
+
readonly clip: Clip;
|
|
29
|
+
readonly profile: CamProfile;
|
|
30
|
+
readonly onProfileChange: (profile: CamProfile) => void;
|
|
7
31
|
}
|
|
8
|
-
export declare function ClipPanel({ deviceId, clip, profile, onProfileChange }: ClipPanelProps):
|
|
32
|
+
export declare function ClipPanel({ deviceId, clip, profile, onProfileChange }: ClipPanelProps): JSX.Element;
|
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* One clip, as a tile.
|
|
3
|
+
*
|
|
4
|
+
* The picture is resolved by `resolveTileMedia` — vouched JPEG, an offer, or
|
|
5
|
+
* the reason there is none (D549 decision 5). An offer is fetched rather than
|
|
6
|
+
* dropped into an `<img src>`, because the route's **204 + x-camstack-reason**
|
|
7
|
+
* is invisible to an `<img>`: it fires `onerror` with nothing to say. The
|
|
8
|
+
* refusal is LATCHED for the life of the tile and never retried behind the
|
|
9
|
+
* operator's back.
|
|
10
|
+
*
|
|
11
|
+
* The row also carries what the camera itself said: its native types, the
|
|
12
|
+
* behaviours beside the class, which storages hold it, and — for a row that
|
|
13
|
+
* is an EVENT sitting inside no file — `playable: false` with its reason
|
|
14
|
+
* (measured: 1 of 29 hub events on 3628). Such a row is SHOWN, never dropped
|
|
15
|
+
* and never offered as playable-then-failing (D549 decision 19).
|
|
16
|
+
*
|
|
17
|
+
* The CHROME is the library's: a `Card` for the tile, `Badge` for every label
|
|
18
|
+
* the camera gave it, `Skeleton` while a mint is in flight. Only the ladder
|
|
19
|
+
* above is this file's own, because only it is a decision.
|
|
20
|
+
*/
|
|
21
|
+
import { type JSX } from "react";
|
|
22
|
+
import type { Clip } from "@camstack/types";
|
|
2
23
|
export interface ClipTileProps {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
24
|
+
readonly clip: Clip;
|
|
25
|
+
readonly selected: boolean;
|
|
26
|
+
readonly onSelect: (clip: Clip) => void;
|
|
6
27
|
}
|
|
7
|
-
export declare function ClipTile({ clip, selected, onSelect }: ClipTileProps):
|
|
28
|
+
export declare function ClipTile({ clip, selected, onSelect }: ClipTileProps): JSX.Element;
|
|
@@ -1,4 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `host/clips-browser` — a camera's clips, from EVERY source it has, as the
|
|
3
|
+
* LAST SECTION of the Recording tab.
|
|
4
|
+
*
|
|
5
|
+
* Mounted by the framework, not by hand: `videoclips.cap.ts` declares
|
|
6
|
+
* `deviceConfig.ui = { kind:'widget', widgetId:'host/clips-browser',
|
|
7
|
+
* tab:'recording', topTab:true, order:100 }` and
|
|
8
|
+
* `deriveDeviceConfigContribution` emits the section (D14). `DeviceDetail.tsx`
|
|
9
|
+
* is not edited — placement is data. Because the admin Recordings page renders
|
|
10
|
+
* every `location:'top-tab'` + `tab:'recording'` section behind its camera
|
|
11
|
+
* picker (`CameraRecordingSettingsSection`), the same declaration puts this on
|
|
12
|
+
* both surfaces with no second wiring.
|
|
13
|
+
*
|
|
14
|
+
* ## Built from the library, not from scratch
|
|
15
|
+
*
|
|
16
|
+
* It shipped as its own top tab made of five bespoke components, and the
|
|
17
|
+
* operator rejected both: *"La UI è orribile, non segue la nostra UI affatto …
|
|
18
|
+
* Io in realtà utilizzerei la stessa tab recordings, lì abbiamo già tutto il
|
|
19
|
+
* necessario, una nuova sezione alla fine per le clips dove possiamo
|
|
20
|
+
* selezionare le source con un multiselect common, non componenti nuovi
|
|
21
|
+
* anonimi."* [The UI is horrible, it does not follow our UI at all … I would actually use the same recordings tab, we already have everything necessary there, a new section at the end for the clips where we can select the sources with a common multiselect, no new anonymous components.] So every piece of chrome here is a component this repo already
|
|
22
|
+
* has: `Select`, `DataTable`, `EmptyState`, `ErrorBox`, `Pagination`, `Card`,
|
|
23
|
+
* `Badge`, `Button`, `Skeleton`. What the chrome CARRIES is unchanged, and it
|
|
24
|
+
* is the feature:
|
|
25
|
+
*
|
|
26
|
+
* - **The source list is complete, always.** Every source the camera has,
|
|
27
|
+
* with its availability and the age of its catalog, whichever provider is
|
|
28
|
+
* being asked. A source never leaves the table.
|
|
29
|
+
* - **Nothing is deduped.** A clip held in two storages appears twice, once
|
|
30
|
+
* per source, and every tile says which (D549).
|
|
31
|
+
* - **Four states are tellable apart**: loading, empty-with-a-cause,
|
|
32
|
+
* degraded-per-source, and each silent source in its own words. Every one
|
|
33
|
+
* of them used to render as "no clips", which is the defect this whole line
|
|
34
|
+
* of work is about — a camera with no SD card (640) is not quiet, and a
|
|
35
|
+
* camera whose own index disagrees with its own calendar (618, 6–20
|
|
36
|
+
* September) is not quiet either.
|
|
37
|
+
*
|
|
38
|
+
* ## The period comes from the recording section's timebar, not a day picker
|
|
39
|
+
*
|
|
40
|
+
* It shipped with its own `‹ day ›` pair and the operator replaced it the same
|
|
41
|
+
* way he replaced the chrome: *"Possiamo utilizzare lo stesso componente della
|
|
42
|
+
* sezione recording con la timebar dove selezionare un periodo e mostrare le
|
|
43
|
+
* clip solo di quella banda selezionata, espandibile."* [We can use the same component as the recording section with the timebar where a period can be selected and show the clips of that selected band only, expandable.] So the list follows a
|
|
44
|
+
* BAND (D564) — `TimelineControls` for the day, the zoom and the pan,
|
|
45
|
+
* `EventHeatmap` for picking a narrower window out of it, both of them the
|
|
46
|
+
* pieces `RecordingTimeline` is itself built from, over the same
|
|
47
|
+
* `recording-timeline-model`. Three things that are decisions, not details:
|
|
48
|
+
*
|
|
49
|
+
* - **The band lives HERE, once.** `ClipBandBar` is presentational. Two
|
|
50
|
+
* components holding two ideas of the selected period is the defect this
|
|
51
|
+
* repo keeps paying for, and the period is what the query is made of.
|
|
52
|
+
* - **`CoverageTrack` stayed behind**, because there it is the seek surface
|
|
53
|
+
* that moves the hero player's playhead. A copy here would be a dead bar or
|
|
54
|
+
* a second claimant on that position.
|
|
55
|
+
* - **A band is asked for only if it is affordable.** `clip-band.ts` counts
|
|
56
|
+
* the LOCAL days it touches — the camera's own search is clamped to one per
|
|
57
|
+
* call, and a day listing is 4.3–6.0 s on 592 — and refuses past the bound
|
|
58
|
+
* by name rather than asking and rendering whichever days answered.
|
|
59
|
+
*
|
|
60
|
+
* ## The picker WRITES nothing, and there is nothing for it to write
|
|
61
|
+
*
|
|
62
|
+
* A clip source is not enabled or disabled — it EXISTS, because of a
|
|
63
|
+
* configuration that lives somewhere else. The operator put it exactly:
|
|
64
|
+
* *"non è affatto necessario lo stato di abilitato o meno delle sources. Loro
|
|
65
|
+
* vivono lì, ad esempio hksv c'è se la camera è esportata su homekit, reolink
|
|
66
|
+
* la dà di suo così come il camstack."* [the enabled-or-not state of the sources is not necessary at all. They live there, for example hksv is there if the camera is exported to homekit, reolink provides it on its own, as does camstack.] HKSV is there if the camera is
|
|
67
|
+
* exported to HomeKit; the Reolink source is there because Reolink is that
|
|
68
|
+
* camera's provider; CamStack's is always there. None of that is a decision to
|
|
69
|
+
* make in a clips list, so this surface offers no switch and writes no
|
|
70
|
+
* authority (D557, amended). A directory-wide guard in
|
|
71
|
+
* `clips-section-sources.test.tsx` keeps it that way.
|
|
72
|
+
*
|
|
73
|
+
* ## Why the picker is a SELECT and not a multiselect
|
|
74
|
+
*
|
|
75
|
+
* The operator asked for *"un multiselect common"* while `listClips` still
|
|
76
|
+
* took `sources?: string[]`. It now takes ONE `provider` —
|
|
77
|
+
* *"l'utilizzatore è uno solo"* [there is only one user] — and a multi-pick control over a
|
|
78
|
+
* one-at-a-time argument offers a sum the hub cannot answer. So the control is
|
|
79
|
+
* the shared single-choice one, `Select`: the same component the Recordings
|
|
80
|
+
* page's own camera picker uses, which is what *"segue la nostra UI"* means
|
|
81
|
+
* here.
|
|
82
|
+
*
|
|
83
|
+
* ## The control's value is ALWAYS what the query carries
|
|
84
|
+
*
|
|
85
|
+
* There is no "default" option and no empty value. This section used to send
|
|
86
|
+
* no `provider` at all until the operator chose, because the cap documented
|
|
87
|
+
* absence as "the device's bound provider, which is CamStack on every camera".
|
|
88
|
+
* No code implemented that: measured on device 592 (2026-09-20, bound to
|
|
89
|
+
* `recorder` AND `provider-reolink`) a bare `listClips` with `limit: 3`
|
|
90
|
+
* answered SIX rows — three per source, merged — while the default option read
|
|
91
|
+
* "CamStack recordings". The label named one thing and the query asked two.
|
|
92
|
+
*
|
|
93
|
+
* Naming a provider is now required (D554 amended), and the default is this surface's
|
|
94
|
+
* to make: the FIRST source the camera lists, shown selected in the control, so
|
|
95
|
+
* what is on screen and what was asked are the same fact. A camera that lists
|
|
96
|
+
* no source is asked NOTHING — the query never fires and the body says nobody
|
|
97
|
+
* answered, rather than spinning against a question with no addressee.
|
|
98
|
+
*
|
|
99
|
+
* ## One provider is a fleet STATE
|
|
100
|
+
*
|
|
101
|
+
* `listSources` derives from `deviceManager.getBindings`. A camera bound to one
|
|
102
|
+
* provider makes the selector inert, and it SAYS why: an empty or silently
|
|
103
|
+
* single-entry control would read as a defect.
|
|
104
|
+
*/
|
|
105
|
+
import { type JSX } from "react";
|
|
1
106
|
export interface ClipsSectionProps {
|
|
2
|
-
|
|
107
|
+
readonly deviceId: number;
|
|
3
108
|
}
|
|
4
|
-
export declare function ClipsSection({ deviceId }: ClipsSectionProps):
|
|
109
|
+
export declare function ClipsSection({ deviceId }: ClipsSectionProps): JSX.Element | null;
|
|
@@ -1,58 +1,92 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The BAND — the period the clip list is asked for, and what it costs.
|
|
3
|
+
*
|
|
4
|
+
* The clips section used to own a day picker. It now follows a period selected
|
|
5
|
+
* on the recording timebar (D564), so the window it asks `listClips` for is no
|
|
6
|
+
* longer a calendar day: it is whatever the operator has zoomed, panned or
|
|
7
|
+
* bucket-clicked down to. Everything in this module exists because a period is
|
|
8
|
+
* a different KIND of thing from a day in exactly two ways.
|
|
9
|
+
*
|
|
10
|
+
* ## The cost is counted in LOCAL days, because the camera's own search is
|
|
11
|
+
*
|
|
12
|
+
* A Reolink search is clamped to one camera-local day per call — measured
|
|
13
|
+
* 2026-09-20 on hub child 3628: a two-day ask answered 39 windows all dated
|
|
14
|
+
* the START day, silently, and `nodelink-js` now clamps and trace-logs it. The
|
|
15
|
+
* provider therefore LOOPS local days
|
|
16
|
+
* (`reolink-videoclips-provider.ts`), and a day listing is 4.3–6.0 s on 592
|
|
17
|
+
* (209 clips in 6.0 s; 546 in 4.3 s). A band's width in ms says nothing about
|
|
18
|
+
* what it costs; the number of local days it touches says everything. That is
|
|
19
|
+
* the unit here, and the walk goes through `Date`'s own day arithmetic so a
|
|
20
|
+
* DST week is seven days and not 6.96 (`clip-day-window.ts`).
|
|
21
|
+
*
|
|
22
|
+
* ## A band wider than the bound is REFUSED, never asked and partly shown
|
|
23
|
+
*
|
|
24
|
+
* The recording timebar cannot itself express more than a local day — its
|
|
25
|
+
* widest zoom level is 24 h and `zoomWindowAnchoredRight` clamps to the day's
|
|
26
|
+
* bounds — so {@link MAX_BAND_LOCAL_DAYS} is set at the one place a reachable
|
|
27
|
+
* band can still exceed one day: a window that straddles local midnight. The
|
|
28
|
+
* bound is enforced HERE rather than trusted to the control, because a control
|
|
29
|
+
* that later grows a wider zoom must not silently hand the list a
|
|
30
|
+
* recording-sized ask. Above it the query is not fired at all and the surface
|
|
31
|
+
* says which band it refused and why. Trimming the band to the days it could
|
|
32
|
+
* afford and rendering those is the defect this refusal exists to prevent — it
|
|
33
|
+
* is an empty list reading as "no clips" with extra steps.
|
|
34
|
+
*/
|
|
35
|
+
import type { DayWindow } from "../cap-settings/recording-timeline-model.js";
|
|
2
36
|
/** The half-open instant range `listClips` is asked for. */
|
|
3
37
|
export interface ClipBand {
|
|
4
|
-
|
|
5
|
-
|
|
38
|
+
readonly fromMs: number;
|
|
39
|
+
readonly toMs: number;
|
|
6
40
|
}
|
|
7
41
|
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
42
|
+
* How many local days a band may touch and still be asked for.
|
|
43
|
+
*
|
|
44
|
+
* Two, which is every band the timebar can produce: its view window never
|
|
45
|
+
* spans more than one calendar day, and the only way to reach a second is to
|
|
46
|
+
* sit across local midnight. A third is not a gesture this control has, so it
|
|
47
|
+
* is a bug or a future widening — either way the list refuses rather than
|
|
48
|
+
* guesses.
|
|
49
|
+
*/
|
|
16
50
|
export declare const MAX_BAND_LOCAL_DAYS = 2;
|
|
17
51
|
/** What the surface may do with a band, decided once. */
|
|
18
52
|
export type ClipBandPlan = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
53
|
+
readonly kind: "askable";
|
|
54
|
+
readonly band: ClipBand;
|
|
55
|
+
readonly localDays: number;
|
|
22
56
|
} | {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
57
|
+
readonly kind: "too-wide";
|
|
58
|
+
readonly band: ClipBand;
|
|
59
|
+
readonly localDays: number;
|
|
60
|
+
readonly maxLocalDays: number;
|
|
27
61
|
};
|
|
28
62
|
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
63
|
+
* How many LOCAL calendar days the half-open band touches.
|
|
64
|
+
*
|
|
65
|
+
* The end instant is exclusive, so a band that ends exactly at the next local
|
|
66
|
+
* midnight is one day, not two — otherwise every whole-day band would report
|
|
67
|
+
* double what it costs.
|
|
68
|
+
*/
|
|
35
69
|
export declare function localDaysInBand(band: ClipBand): number;
|
|
36
70
|
/** Whether this band may be asked for, and what it costs, in one value. */
|
|
37
71
|
export declare function planClipBand(band: ClipBand): ClipBandPlan;
|
|
38
72
|
/** A density bucket's own window, as `EventHeatmap` hands it back. */
|
|
39
73
|
export interface ClipBandBucket {
|
|
40
|
-
|
|
41
|
-
|
|
74
|
+
readonly startMs: number;
|
|
75
|
+
readonly endMs: number;
|
|
42
76
|
}
|
|
43
77
|
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
78
|
+
* The band for the current selection: the picked bucket, or — when nothing is
|
|
79
|
+
* picked — the whole visible window.
|
|
80
|
+
*
|
|
81
|
+
* "Nothing picked means everything visible" is safe here and only here,
|
|
82
|
+
* because the visible window is itself bounded by the timebar. It is never
|
|
83
|
+
* "everything the camera holds" (D382's unstated ask).
|
|
84
|
+
*/
|
|
51
85
|
export declare function bandForSelection(view: DayWindow, bucket: ClipBandBucket | null): ClipBand;
|
|
52
86
|
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
87
|
+
* The band, spelled out.
|
|
88
|
+
*
|
|
89
|
+
* Every state renders it — an empty list has to say WHICH period it is empty
|
|
90
|
+
* for, the same rule the day label carried before the band replaced it.
|
|
91
|
+
*/
|
|
58
92
|
export declare function formatBandLabel(band: ClipBand): string;
|
|
@@ -1,36 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* LOCAL calendar-day arithmetic for the clips browser.
|
|
3
|
-
*
|
|
4
|
-
* The browser no longer NAVIGATES days — it follows a band selected on the
|
|
5
|
-
* recording timebar (D564) — but the local day survived the move as the unit
|
|
6
|
-
* the COST is counted in: a Reolink search is clamped to one camera-local day
|
|
7
|
-
* per call, so `clip-band.ts` counts a band's local days to decide whether it
|
|
8
|
-
* may be asked for. The window builder this file used to own went with the day
|
|
9
|
-
* picker; `recording-timeline-model.ts`'s `dayWindow(date, nowMs)` is the one
|
|
10
|
-
* that builds windows now, and one directory holding two functions of that
|
|
11
|
-
* name was the confusion worth deleting.
|
|
12
|
-
*
|
|
13
|
-
* Two properties are pinned by spec because both are invisible until they are
|
|
14
|
-
* wrong:
|
|
15
|
-
*
|
|
16
|
-
* - Deriving the day in UTC shifts every band by the browser's offset, and an
|
|
17
|
-
* operator in Berlin would see a 22:00 clip filed under the next day.
|
|
18
|
-
* - Walking days by adding 86 400 000 ms repeats or skips a calendar day
|
|
19
|
-
* across a DST change. The walk goes through `Date`'s own day arithmetic.
|
|
20
|
-
*
|
|
21
|
-
* A day id is `YYYY-MM-DD` — it orders lexicographically, which is what lets
|
|
22
|
-
* the band's day walk terminate on a comparison rather than on a count.
|
|
23
|
-
*/
|
|
24
1
|
/** The LOCAL calendar day an instant falls in, as `YYYY-MM-DD`. */
|
|
25
2
|
export declare function toDayId(instant: Date): string;
|
|
26
3
|
/** Walk `days` calendar days from `dayId` — DST-safe, because `Date` does it. */
|
|
27
4
|
export declare function shiftDay(dayId: string, days: number): string;
|
|
28
5
|
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
6
|
+
* The day, spelled out — the calendar half of a band's label.
|
|
7
|
+
*
|
|
8
|
+
* An empty list has to say WHICH period it is empty for; "no clips" with no
|
|
9
|
+
* date beside it is the ambiguity this surface exists to remove. `formatBandLabel`
|
|
10
|
+
* puts the times around it, and every state renders the result, not only the
|
|
11
|
+
* populated one.
|
|
12
|
+
*/
|
|
36
13
|
export declare function formatDayLabel(dayId: string): string;
|
|
@@ -1,34 +1,63 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* What a clip SOURCE is saying right now, in words an operator can act on.
|
|
3
|
+
*
|
|
4
|
+
* `ClipSourceAvailability.state` has five values and four of them used to
|
|
5
|
+
* render identically — as an empty list, which reads "this camera has no
|
|
6
|
+
* recordings". That is the defect the whole external-videoclips line exists to
|
|
7
|
+
* fix ([D549](../../../../../docs/decisions/adr-0549-an-external-clip-catalog-is-another-videoclips-provider-served-by-the-devices-owner-and-listed-beside-the-others.md)
|
|
8
|
+
* § 7b), measured on real cameras:
|
|
9
|
+
*
|
|
10
|
+
* - 640 has **no SD card** (`HddInfo mount 0`). It is not quiet; it stores
|
|
11
|
+
* nothing.
|
|
12
|
+
* - 618's own calendar marks 6–20 September present and its own index then
|
|
13
|
+
* lists **zero files** for those days, with 177 GB free. That is a defect
|
|
14
|
+
* ON THE CAMERA, and the only honest thing to say is which days were asked
|
|
15
|
+
* for and came back empty.
|
|
16
|
+
* - A standalone battery camera is **asleep**; a read would be a wake, so
|
|
17
|
+
* what you are looking at is a CACHE with an age.
|
|
18
|
+
* - `native:reolink:hub` is **unreachable** today because the library parser
|
|
19
|
+
* for the events view has not landed — so the degraded case is not
|
|
20
|
+
* hypothetical, it is what every hub child looks like right now.
|
|
21
|
+
*
|
|
22
|
+
* This module is the one place those five become words, kept pure so the
|
|
23
|
+
* distinctness can be pinned without a React tree (a rendering test that only
|
|
24
|
+
* checked colour would pass with all five saying "no clips").
|
|
25
|
+
*
|
|
26
|
+
* The provider's own `reason` travels VERBATIM. It is the camera's refusal in
|
|
27
|
+
* the camera's words; re-writing it here would lose the only detail that tells
|
|
28
|
+
* an operator whether to look at the card, the network or the firmware.
|
|
29
|
+
*/
|
|
30
|
+
import type { ClipSource } from "@camstack/types";
|
|
2
31
|
/** How loudly a source's state should read. Never the whole message. */
|
|
3
|
-
export type ClipSourceTone =
|
|
32
|
+
export type ClipSourceTone = "ok" | "warn" | "error";
|
|
4
33
|
/** A source's state, rendered. */
|
|
5
34
|
export interface ClipSourceNotice {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
35
|
+
/** The source's own id (`analytics`, `native:reolink:hub`, …). */
|
|
36
|
+
readonly source: string;
|
|
37
|
+
/** The operator-facing source name the provider gave it. */
|
|
38
|
+
readonly label: string;
|
|
39
|
+
/** One line, unique per state. Never "no clips". */
|
|
40
|
+
readonly headline: string;
|
|
41
|
+
/** The provider's reason, verbatim, or null when it gave none. */
|
|
42
|
+
readonly detail: string | null;
|
|
43
|
+
readonly tone: ClipSourceTone;
|
|
44
|
+
/**
|
|
45
|
+
* Did this source contribute rows to the list on screen?
|
|
46
|
+
*
|
|
47
|
+
* `sleeping` answers TRUE: a sleeping camera serves its persisted catalog
|
|
48
|
+
* (D549 decision 4), so its clips ARE in the list — only their age is
|
|
49
|
+
* different. The other three contribute nothing, and an empty day must name
|
|
50
|
+
* them as the reason rather than claim the camera was quiet.
|
|
51
|
+
*/
|
|
52
|
+
readonly answered: boolean;
|
|
24
53
|
}
|
|
25
54
|
/** Turn one source row into the line the picker and the list show. */
|
|
26
55
|
export declare function describeSource(source: ClipSource): ClipSourceNotice;
|
|
27
56
|
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
57
|
+
* How old a source's catalog is, or null when it did not say.
|
|
58
|
+
*
|
|
59
|
+
* Null is NOT "now". A source that omits `catalogAsOf` was read live and has
|
|
60
|
+
* no age to show; inventing "just now" for a source that never told us would
|
|
61
|
+
* be the same lie as drawing a cached list as current (D549 decision 13).
|
|
62
|
+
*/
|
|
34
63
|
export declare function formatCatalogAge(catalogAsOf: number | undefined, now: number): string | null;
|
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
2
|
+
* When a tile comes back for a still the server said was queued — and when it
|
|
3
|
+
* gives up (D563).
|
|
4
|
+
*
|
|
5
|
+
* ## Why a retry, and not a queue or a push
|
|
6
|
+
*
|
|
7
|
+
* A deferred refusal is FREE. The provider's lane rejects past its capacity
|
|
8
|
+
* without touching the camera, so asking again costs one cheap HTTP round trip
|
|
9
|
+
* to the addon and zero Baichuan commands. That is what rules out the
|
|
10
|
+
* alternatives: a push would need a channel, a subscription and server-side
|
|
11
|
+
* fan-out of 60 tile identities to save requests that cost nothing, and a
|
|
12
|
+
* client-side queue would be a second copy of the authority that already lives
|
|
13
|
+
* where the camera's real constraint is. Scroll-into-view alone does not help
|
|
14
|
+
* either — the 43 tiles measured refusing on 592 are already on screen.
|
|
15
|
+
*
|
|
16
|
+
* ## The shape
|
|
17
|
+
*
|
|
18
|
+
* Exponential, jittered, bounded. Exponential because a fixed interval either
|
|
19
|
+
* hammers or dawdles; JITTERED because 43 tiles refused in the same paint
|
|
20
|
+
* would otherwise come back in the same instant and refuse together again;
|
|
21
|
+
* BOUNDED because a tile that asks for ever is the other way to show the
|
|
22
|
+
* operator nothing.
|
|
23
|
+
*
|
|
24
|
+
* The server's `retry-after` is taken only when it is LONGER than the curve.
|
|
25
|
+
* The curve is the floor, so a provider answering `retry-after: 1` for a whole
|
|
26
|
+
* page cannot turn this into 43 requests a second.
|
|
27
|
+
*
|
|
28
|
+
* Sized against the measurement: one page is 60 tiles and the provider serves
|
|
29
|
+
* one mint in flight per host, so the last tile is ~60 mints away. The budget
|
|
30
|
+
* below outlasts that; a shorter one would be theatre.
|
|
31
|
+
*/
|
|
32
32
|
/** How many times a tile comes back before it says so and stops. */
|
|
33
33
|
export declare const STILL_RETRY_ATTEMPTS = 4;
|
|
34
34
|
/** First wait, doubling from there. */
|
|
35
|
-
export declare const STILL_RETRY_BASE_MS =
|
|
35
|
+
export declare const STILL_RETRY_BASE_MS = 4e3;
|
|
36
36
|
/** No single wait is longer than this, whatever the server hints. */
|
|
37
|
-
export declare const STILL_RETRY_MAX_WAIT_MS =
|
|
37
|
+
export declare const STILL_RETRY_MAX_WAIT_MS = 3e4;
|
|
38
38
|
export interface StillRetryInput {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
/** 0 for the first retry, 1 for the second, … */
|
|
40
|
+
readonly attempt: number;
|
|
41
|
+
/** The server's `retry-after`, in ms, or `null` when it sent none. */
|
|
42
|
+
readonly serverHintMs: number | null;
|
|
43
|
+
/** Injected so the schedule is assertable; `Math.random` in production. */
|
|
44
|
+
readonly random: () => number;
|
|
45
45
|
}
|
|
46
46
|
export interface StillRetryPlan {
|
|
47
|
-
|
|
47
|
+
readonly waitMs: number;
|
|
48
48
|
}
|
|
49
49
|
/** The next wait, or `null` when the budget is spent. */
|
|
50
50
|
export declare function planStillRetry(input: StillRetryInput): StillRetryPlan | null;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { ClipTileMedia } from
|
|
1
|
+
import { type ClipTileMedia } from "./clip-tile-media.js";
|
|
2
2
|
/** The `fetch` this module uses — injected so the contract is testable. */
|
|
3
3
|
export type ThumbnailFetcher = (url: string, init: RequestInit) => Promise<Response>;
|
|
4
4
|
/** A minted still, or the reason there is none. */
|
|
5
5
|
export type MintedThumbnail = {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
readonly kind: "image";
|
|
7
|
+
readonly blob: Blob;
|
|
8
8
|
} | ClipTileMedia;
|
|
9
9
|
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
* Ask a mint route for one still.
|
|
11
|
+
*
|
|
12
|
+
* Never rejects: a thrown fetch is a refusal like any other, because a tile
|
|
13
|
+
* that throws is a tile that renders nothing and says nothing — the exact
|
|
14
|
+
* failure this module exists to prevent.
|
|
15
|
+
*/
|
|
16
16
|
export declare function fetchMintedThumbnail(url: string, fetcher: ThumbnailFetcher): Promise<MintedThumbnail>;
|