@camera.ui/server 0.0.105 → 0.0.106

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 (140) hide show
  1. package/dist/interface/assets/{404-dD7prz4d.js → 404-BAYYYl25.js} +1 -1
  2. package/dist/interface/assets/{About-4w_Ij32a.js → About-CF96M6HY.js} +1 -1
  3. package/dist/interface/assets/{Adminpanel-BgxU0Yh6.js → Adminpanel-DOaJyAyb.js} +1 -1
  4. package/dist/interface/assets/{Automation-CYsN1p2P.js → Automation-CKXlldCc.js} +2 -2
  5. package/dist/interface/assets/{Automations-CRd6MuM2.js → Automations-Bly4du8g.js} +1 -1
  6. package/dist/interface/assets/{Camera-DCqFhkAt.js → Camera-B_iqc3Zu.js} +2 -2
  7. package/dist/interface/assets/{CameraConsole-DfIBG8ZV.js → CameraConsole-DmkR-ATY.js} +1 -1
  8. package/dist/interface/assets/{Cameras-BK67w1OJ.js → Cameras-CBJqTSnN.js} +1 -1
  9. package/dist/interface/assets/{Camview-B0go1EMt.js → Camview-CF_Fa0E1.js} +1 -1
  10. package/dist/interface/assets/{Config-CeEi3tKd.js → Config-B10TESNa.js} +1 -1
  11. package/dist/interface/assets/{ConfigActionCameraControl-rP-oa_3f.js → ConfigActionCameraControl-BWpRxipc.js} +1 -1
  12. package/dist/interface/assets/{ConfigActionDelay-BJeC4VAJ.js → ConfigActionDelay-NBOa8ulm.js} +1 -1
  13. package/dist/interface/assets/{ConfigActionHttp-F8Mpo56C.js → ConfigActionHttp-CpeMles1.js} +1 -1
  14. package/dist/interface/assets/{ConfigActionImageInput-Drtv5ElC.js → ConfigActionImageInput-He5suR1p.js} +1 -1
  15. package/dist/interface/assets/{ConfigActionNotification-DR8c22Y1.js → ConfigActionNotification-BrYGUn_B.js} +1 -1
  16. package/dist/interface/assets/{ConfigActionOutput-CbT2-VnU.js → ConfigActionOutput-Dy32ypu0.js} +1 -1
  17. package/dist/interface/assets/{ConfigActionPlugin-DE-S6S0y.js → ConfigActionPlugin-DZgDVj2J.js} +1 -1
  18. package/dist/interface/assets/{ConfigActionSensor-Dw_V9cYY.js → ConfigActionSensor-B9aJwfb2.js} +1 -1
  19. package/dist/interface/assets/{ConfigActionSnapshot-5xUvGsae.js → ConfigActionSnapshot-Bisnu1Va.js} +1 -1
  20. package/dist/interface/assets/{ConfigActionVariable-Bub1V_a3.js → ConfigActionVariable-BcQ-pUs-.js} +1 -1
  21. package/dist/interface/assets/{ConfigConditionIfElse-CAt9ubD2.js → ConfigConditionIfElse-DKyGnLRO.js} +1 -1
  22. package/dist/interface/assets/{ConfigConditionSensorState-DhP32uo8.js → ConfigConditionSensorState-mKh6F8lJ.js} +1 -1
  23. package/dist/interface/assets/{ConfigConditionSwitch-DB2r6i-I.js → ConfigConditionSwitch-CSZTkyIE.js} +1 -1
  24. package/dist/interface/assets/{ConfigConditionTime-zqIQQ-tD.js → ConfigConditionTime-C8_R0ITE.js} +1 -1
  25. package/dist/interface/assets/{ConfigTriggerDetection-CVW5HXeG.js → ConfigTriggerDetection-a2NV6Ke1.js} +1 -1
  26. package/dist/interface/assets/{ConfigTriggerGeofence-BsPsPO4j.js → ConfigTriggerGeofence-DnS6ONJC.js} +1 -1
  27. package/dist/interface/assets/{ConfigTriggerManual-DhafkyQd.js → ConfigTriggerManual-CrKYDCVp.js} +1 -1
  28. package/dist/interface/assets/{ConfigTriggerSchedule-Bx3qlITv.js → ConfigTriggerSchedule-Dc6k-hJ2.js} +1 -1
  29. package/dist/interface/assets/{ConfigTriggerSensor-FVgMXGty.js → ConfigTriggerSensor-lmBAbpAF.js} +1 -1
  30. package/dist/interface/assets/{ConfigTriggerSystem-BJo-wIMS.js → ConfigTriggerSystem-BibBSkft.js} +1 -1
  31. package/dist/interface/assets/{ConfigTriggerWebhook-BaUrOAZB.js → ConfigTriggerWebhook-CcMI4u82.js} +1 -1
  32. package/dist/interface/assets/{Console-B23nM1WG.js → Console-CiqXek8C.js} +1 -1
  33. package/dist/interface/assets/{CuiActionButton-Dywht3_D.js → CuiActionButton-DmV0jhr5.js} +1 -1
  34. package/dist/interface/assets/{CuiAvatar-CdoyvPP1.js → CuiAvatar-DMZqcLoE.js} +1 -1
  35. package/dist/interface/assets/{CuiBBoxPlayground-DcAhwW8k.js → CuiBBoxPlayground-BakfNGCT.js} +1 -1
  36. package/dist/interface/assets/CuiBottomSheet-BJl4lLzC.js +1 -0
  37. package/dist/interface/assets/{CuiBottomSheet-CvkbklC_.js → CuiBottomSheet-CkJEMXQy.js} +1 -1
  38. package/dist/interface/assets/{CuiCameraCard-BxWf13Ct.js → CuiCameraCard-jWlEnJAQ.js} +1 -1
  39. package/dist/interface/assets/{CuiCameraPipCard-CR5a-MkM.js → CuiCameraPipCard-ClOJg9E-.js} +1 -1
  40. package/dist/interface/assets/{CuiCameraRecordings-BXfAlbHm.js → CuiCameraRecordings-BhM5UivW.js} +1 -1
  41. package/dist/interface/assets/{CuiCameraShares-CJpSVfdl.js → CuiCameraShares-CktUxrlR.js} +1 -1
  42. package/dist/interface/assets/{CuiCameraSnapshot-Cg8Vjve3.js → CuiCameraSnapshot-BE1xeM4q.js} +1 -1
  43. package/dist/interface/assets/{CuiCameraTable-CfJNlsEQ.js → CuiCameraTable-D87v9LhC.js} +1 -1
  44. package/dist/interface/assets/{CuiDataTable-C9mtC73b.js → CuiDataTable-C5toN4L-.js} +1 -1
  45. package/dist/interface/assets/{CuiFloatingButton-Bi1jS25U.js → CuiFloatingButton-DvdpuxUr.js} +1 -1
  46. package/dist/interface/assets/{CuiImage-DJcQfDpa.js → CuiImage-C-DSHyf2.js} +1 -1
  47. package/dist/interface/assets/{CuiMenu-150v0xB6.js → CuiMenu-CwumqO_L.js} +1 -1
  48. package/dist/interface/assets/{CuiPluginCard-CHLd5hzA.js → CuiPluginCard-DIqaLKcf.js} +2 -2
  49. package/dist/interface/assets/{CuiPluginOAuthButton-B7JHhElr.js → CuiPluginOAuthButton-CBTeQEb9.js} +2 -2
  50. package/dist/interface/assets/{CuiQRCode-ZbDxg42W.js → CuiQRCode-ChJuYXmm.js} +1 -1
  51. package/dist/interface/assets/{CuiRecordingsGrid-Bl0vRmPG.js → CuiRecordingsGrid-D1mYCCcE.js} +1 -1
  52. package/dist/interface/assets/{CuiSchema-DvWek91_.js → CuiSchema-BIGweVJy.js} +1 -1
  53. package/dist/interface/assets/{CuiTopNavbarItem-Dwm5c6so.js → CuiTopNavbarItem-FXY4aBoC.js} +1 -1
  54. package/dist/interface/assets/{CuiTopbarSlot-DE7fTsSm.js → CuiTopbarSlot-DCeAqmkQ.js} +1 -1
  55. package/dist/interface/assets/{Faces-6nDCr24_.js → Faces-B6JlzZ5i.js} +1 -1
  56. package/dist/interface/assets/{FirstSteps-DB7hnFYh.js → FirstSteps-CH1iro2p.js} +1 -1
  57. package/dist/interface/assets/{Instances-KpdnZAmV.js → Instances-BNNA4Z6H.js} +1 -1
  58. package/dist/interface/assets/{Logs-Cq2AF2x-.js → Logs-BkF4EFHV.js} +1 -1
  59. package/dist/interface/assets/{Menu-CeDR7bvT.js → Menu-DYejNhsi.js} +1 -1
  60. package/dist/interface/assets/{OAuthDeviceFlow-BVOHNDTs.js → OAuthDeviceFlow-BVeSCJiJ.js} +1 -1
  61. package/dist/interface/assets/{Plugin-BB6k9AtE.js → Plugin-zvdoGW2r.js} +1 -1
  62. package/dist/interface/assets/{PluginConsole-Cbo8LA6t.js → PluginConsole-CQA2A5Wc.js} +1 -1
  63. package/dist/interface/assets/{PluginSchema-CCfTSjTD.js → PluginSchema-xof7AYIK.js} +1 -1
  64. package/dist/interface/assets/{Plugins-DpTVWC5S.js → Plugins-DAwDjr_I.js} +2 -2
  65. package/dist/interface/assets/{Recordings-B0_4e1tu.js → Recordings-D7UhoAKi.js} +1 -1
  66. package/dist/interface/assets/{Settings-Wz10iv8b.js → Settings-CnU98cZv.js} +1 -1
  67. package/dist/interface/assets/{SettingsAccount-BNSg5Wx5.js → SettingsAccount-BVIztMFL.js} +1 -1
  68. package/dist/interface/assets/SettingsAccount-BmuJLRLH.js +1 -0
  69. package/dist/interface/assets/{SettingsAppearance-VHR3IVCx.js → SettingsAppearance-CW8mbN9Q.js} +1 -1
  70. package/dist/interface/assets/SettingsAppearance-CiVRn_RM.js +1 -0
  71. package/dist/interface/assets/{SettingsBackup-DGhqvHHm.js → SettingsBackup-DDNiOgvA.js} +1 -1
  72. package/dist/interface/assets/{SettingsNotifications-BHcRDJAp.js → SettingsNotifications-DLMT1o4I.js} +1 -1
  73. package/dist/interface/assets/{SettingsRecordings-CrMGLPfU.js → SettingsRecordings-DirvHeKB.js} +1 -1
  74. package/dist/interface/assets/{SettingsRemote-B1m3_4lr.js → SettingsRemote-CKWsHa5R.js} +1 -1
  75. package/dist/interface/assets/{SettingsSystem-z5r89MJJ.js → SettingsSystem-D9ZC11Mh.js} +2 -2
  76. package/dist/interface/assets/{SettingsUsers-yReLqEQ1.js → SettingsUsers-pcJeXZKp.js} +1 -1
  77. package/dist/interface/assets/{Terminal-BAiV8ZVj.js → Terminal-Cu3uC8EZ.js} +1 -1
  78. package/dist/interface/assets/{VariableInput-Dw0KbkD9.js → VariableInput-Bwu9vChK.js} +1 -1
  79. package/dist/interface/assets/{VariableSuggestions-D5_Zu_un.js → VariableSuggestions-l2MLjZre.js} +1 -1
  80. package/dist/interface/assets/{VersionsHandler-BDWjtbp0.js → VersionsHandler-BTxJHwdS.js} +1 -1
  81. package/dist/interface/assets/{Workers-DbnD_Bpy.js → Workers-BsEDKzmG.js} +1 -1
  82. package/dist/interface/assets/{api-D6SjwBWd.js → api-C3OjKngj.js} +1 -1
  83. package/dist/interface/assets/{api-C-NlYhuP.js → api-CFbWrm1k.js} +1 -1
  84. package/dist/interface/assets/{auth-dyUBxkxf.js → auth-C5IUhkWS.js} +1 -1
  85. package/dist/interface/assets/{automations-CrRSdJyJ.js → automations-DD8bCSnT.js} +1 -1
  86. package/dist/interface/assets/{automations-BH3C3DOU.js → automations-DusabINi.js} +1 -1
  87. package/dist/interface/assets/{backup-C2-2-LD2.js → backup-oG81xIPA.js} +1 -1
  88. package/dist/interface/assets/{cameras-Co3xGKAG.js → cameras-CmFEgULx.js} +1 -1
  89. package/dist/interface/assets/{cameras.schema-y2YP50-k.js → cameras.schema-iBaEWm0Y.js} +1 -1
  90. package/dist/interface/assets/cloudHandoff-BzwN18OZ.js +1 -0
  91. package/dist/interface/assets/{deviceId-CiXrj9Di.js → deviceId-opaLeE0R.js} +1 -1
  92. package/dist/interface/assets/{hasPermission-DKTmzAJw.js → hasPermission-ChIspc-L.js} +1 -1
  93. package/dist/interface/assets/{instances-BgFvZ06K.js → instances-ykXfoA2u.js} +1 -1
  94. package/dist/interface/assets/{locale-CH0o3x5d.js → locale-BliTvqss.js} +1 -1
  95. package/dist/interface/assets/{main-DZb_R3L7.js → main-DiUHKjqR.js} +2 -2
  96. package/dist/interface/assets/{notifications-DEU1TXne.js → notifications-BQyPgfnE.js} +1 -1
  97. package/dist/interface/assets/{plugins-Bj4_KCp7.js → plugins-BFzZB-8S.js} +1 -1
  98. package/dist/interface/assets/{round-restart-alt-BMdTt76H.js → round-restart-alt-C4TFl1Rk.js} +1 -1
  99. package/dist/interface/assets/{router-CIvI3oge.js → router-BzaHrqQ7.js} +2 -2
  100. package/dist/interface/assets/{routerState-cQknQxNw.js → routerState-UESa7YsN.js} +1 -1
  101. package/dist/interface/assets/{server-DeMUCrCz.js → server-7nJbrqvt.js} +1 -1
  102. package/dist/interface/assets/{shares-B5r7Nr5g.js → shares-BokQ1O4D.js} +1 -1
  103. package/dist/interface/assets/{theme-kssRfqyJ.js → theme-iSxYm9Ao.js} +1 -1
  104. package/dist/interface/assets/{types-BK05hngw.js → types-CVp3a4-E.js} +1 -1
  105. package/dist/interface/assets/{ui-B2i8B4yr.js → ui-CVUMjabl.js} +1 -1
  106. package/dist/interface/assets/{useBiometricCredentials-I52MbNzM.js → useBiometricCredentials-BTSuyr45.js} +1 -1
  107. package/dist/interface/assets/{useCameraOptions-uXN6hbSO.js → useCameraOptions-CuIFFMce.js} +1 -1
  108. package/dist/interface/assets/{useCuiCameraDrawer-BuIrXxOt.js → useCuiCameraDrawer-DHbL2uYT.js} +1 -1
  109. package/dist/interface/assets/{useCuiDialog-C4xS4vrs.js → useCuiDialog-DmnaFxId.js} +1 -1
  110. package/dist/interface/assets/{useFileDownload-C_Am2BRz.js → useFileDownload-D7uRiFqP.js} +1 -1
  111. package/dist/interface/assets/{useLogsSocket-PUFDb8MH.js → useLogsSocket-CA2uq1kZ.js} +1 -1
  112. package/dist/interface/assets/{useSharedComposables-Ca_A3w0h.js → useSharedComposables-Dsn2uiyW.js} +1 -1
  113. package/dist/interface/assets/{useStreamStatus-CIPBILoa.js → useStreamStatus-Dun63PvC.js} +1 -1
  114. package/dist/interface/assets/{users.schema-DGYmUjqk.js → users.schema-COvF8XP0.js} +1 -1
  115. package/dist/interface/assets/{vendor-cameraui-BABuGvhg.js → vendor-cameraui-B1JU4jwS.js} +38 -38
  116. package/dist/interface/assets/{vendor-core-C6lCucBy.js → vendor-core-BxjZmyZH.js} +1 -1
  117. package/dist/interface/assets/{vendor-primevue-CsC6U_Xu.js → vendor-primevue-gmNTz6qq.js} +1 -1
  118. package/dist/interface/assets/{view-grid-DM5fFhOq.js → view-grid-C3peaC6C.js} +1 -1
  119. package/dist/interface/index.html +40 -40
  120. package/dist/interface/sw.js +1 -1
  121. package/dist/server/package.json +1 -1
  122. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/channel.py +29 -23
  123. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/chunking.py +52 -5
  124. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/client.py +682 -231
  125. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/codec.py +277 -18
  126. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/handler.py +105 -17
  127. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/service.py +21 -7
  128. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/types.py +13 -0
  129. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/utils.py +50 -15
  130. package/dist/server/src/api/plugins/natsSubFirewall.js +0 -6
  131. package/dist/server/src/api/plugins/natsSubFirewall.js.map +1 -1
  132. package/dist/server/src/api/plugins/proxy.plugin.js +3 -0
  133. package/dist/server/src/api/plugins/proxy.plugin.js.map +1 -1
  134. package/dist/server/src/rpc/server.js +6 -3
  135. package/dist/server/src/rpc/server.js.map +1 -1
  136. package/package.json +1 -1
  137. package/dist/interface/assets/CuiBottomSheet-CU8irFoy.js +0 -1
  138. package/dist/interface/assets/SettingsAccount-DlGKfeGf.js +0 -1
  139. package/dist/interface/assets/SettingsAppearance-N4r7TCgr.js +0 -1
  140. package/dist/interface/assets/cloudHandoff-C9HXr7Oq.js +0 -1
@@ -1,9 +1,10 @@
1
1
  """Optimized chunking system for large message handling."""
2
2
 
3
+ import time
3
4
  from collections.abc import Callable, Generator
4
5
  from typing import Any
5
6
 
6
- from .codec import decode
7
+ from .codec import decode_message
7
8
  from .types import ChunkData
8
9
 
9
10
 
@@ -152,10 +153,13 @@ class ChunkAssembler:
152
153
  raise RuntimeError("Cannot get data: Not all chunks have been received.")
153
154
 
154
155
  if self.buffer is not None:
155
- # Optimal path: The buffer is already fully assembled.
156
- # We create a memoryview to avoid copying the buffer before decoding.
156
+ # Optimal path: The buffer is already fully assembled. Chunked
157
+ # payloads are always full wire messages, so this goes through
158
+ # decode_message: a reassembled CUIB frame yields zero-copy
159
+ # memoryview slices into the assembly buffer (the views keep the
160
+ # bytearray alive after the assembler is pooled/reset).
157
161
  data_view = memoryview(self.buffer)
158
- return decode(data_view)
162
+ return decode_message(data_view)
159
163
  else:
160
164
  # Fallback path: Manually combine chunks from temporary storage.
161
165
  # This path involves a final copy operation.
@@ -167,7 +171,7 @@ class ChunkAssembler:
167
171
  chunk_len = len(chunk)
168
172
  combined[offset : offset + chunk_len] = chunk
169
173
  offset += chunk_len
170
- return decode(combined)
174
+ return decode_message(combined)
171
175
 
172
176
  def get_progress(self) -> dict[str, int | float]:
173
177
  """Get the current progress of the chunk transfer."""
@@ -180,11 +184,22 @@ class ChunkAssembler:
180
184
  class ChunkingManager:
181
185
  """Manages multiple concurrent chunk transfers."""
182
186
 
187
+ # Incomplete transfers hold their full pre-allocated buffer. If a single
188
+ # chunk is lost (sender reconnected mid-transfer), the assembler would
189
+ # otherwise sit in memory until the whole client disconnects — so stale
190
+ # transfers are swept lazily on every start_receiving/process_chunk call.
191
+ _STALE_TRANSFER_TTL: float = 30.0
192
+ # Sweeping on every chunk of a large transfer is pure overhead — one
193
+ # sweep per second is more than enough for a 30s TTL.
194
+ _SWEEP_INTERVAL: float = 1.0
195
+
183
196
  def __init__(self) -> None:
184
197
  self.assemblers: dict[str, ChunkAssembler] = {}
185
198
  self.completed_callbacks: dict[str, Callable[[Any], None]] = {}
186
199
  self.error_callbacks: dict[str, Callable[[Exception], None]] = {}
187
200
  self._assembler_pool: list[ChunkAssembler] = []
201
+ self._last_activity: dict[str, float] = {}
202
+ self._last_sweep: float = 0.0
188
203
 
189
204
  def _get_assembler(self, transfer_id: str) -> ChunkAssembler:
190
205
  """Get a reusable assembler from a pool or create a new one."""
@@ -228,14 +243,42 @@ class ChunkingManager:
228
243
  on_error: Callback to execute if an error occurs.
229
244
  total_size: The total size of the final data for pre-allocation.
230
245
  """
246
+ self._sweep_stale()
231
247
  assembler = self._get_assembler(transfer_id)
232
248
  assembler.set_expected_chunks(total_chunks, total_size, chunk_size)
233
249
  self.assemblers[transfer_id] = assembler
234
250
  self.completed_callbacks[transfer_id] = on_complete
235
251
  self.error_callbacks[transfer_id] = on_error
252
+ self._last_activity[transfer_id] = time.monotonic()
253
+
254
+ def _sweep_stale(self) -> None:
255
+ """Drop incomplete transfers with no activity for _STALE_TRANSFER_TTL.
256
+
257
+ Rate-limited to at most one sweep per _SWEEP_INTERVAL — this runs on
258
+ every start_receiving/process_chunk call.
259
+ """
260
+ if not self._last_activity:
261
+ return
262
+ now = time.monotonic()
263
+ if now - self._last_sweep < self._SWEEP_INTERVAL:
264
+ return
265
+ self._last_sweep = now
266
+ cutoff = now - self._STALE_TRANSFER_TTL
267
+ stale = [tid for tid, ts in self._last_activity.items() if ts < cutoff]
268
+ for transfer_id in stale:
269
+ error_callback = self.error_callbacks.pop(transfer_id, None)
270
+ assembler = self.assemblers.pop(transfer_id, None)
271
+ if assembler:
272
+ self._return_assembler(assembler)
273
+ self.completed_callbacks.pop(transfer_id, None)
274
+ self._last_activity.pop(transfer_id, None)
275
+ if error_callback:
276
+ error_callback(RuntimeError("Transfer timed out"))
236
277
 
237
278
  def process_chunk(self, chunk: dict[str, Any]) -> None:
238
279
  """Process an incoming chunk for a specific transfer."""
280
+ self._sweep_stale()
281
+
239
282
  transfer_id = chunk.get("id") or chunk.get("transferId")
240
283
  if not transfer_id:
241
284
  return
@@ -245,6 +288,8 @@ class ChunkingManager:
245
288
  # Received a chunk for an unknown or completed transfer.
246
289
  return
247
290
 
291
+ self._last_activity[transfer_id] = time.monotonic()
292
+
248
293
  try:
249
294
  # Normalize keys in-place to avoid allocating a new dict.
250
295
  # Handles minor key differences between JS/Go/Python senders.
@@ -261,6 +306,7 @@ class ChunkingManager:
261
306
  # Cleanup and return assembler to the pool
262
307
  del self.assemblers[transfer_id]
263
308
  self.error_callbacks.pop(transfer_id, None)
309
+ self._last_activity.pop(transfer_id, None)
264
310
  self._return_assembler(assembler)
265
311
 
266
312
  if callback:
@@ -276,6 +322,7 @@ class ChunkingManager:
276
322
  if assembler:
277
323
  self._return_assembler(assembler)
278
324
  self.completed_callbacks.pop(transfer_id, None)
325
+ self._last_activity.pop(transfer_id, None)
279
326
 
280
327
  if error_callback:
281
328
  error_callback(error)