@camstack/core 0.1.15 → 0.1.17

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 (382) hide show
  1. package/dist/addon/addon-api-factory.d.ts +36 -0
  2. package/dist/addon/addon-api-factory.d.ts.map +1 -0
  3. package/dist/addon-routes/addon-route-registry.d.ts +38 -0
  4. package/dist/addon-routes/addon-route-registry.d.ts.map +1 -0
  5. package/dist/auth/api-key-manager.d.ts +27 -0
  6. package/dist/auth/api-key-manager.d.ts.map +1 -0
  7. package/dist/auth/auth-manager.d.ts +47 -0
  8. package/dist/auth/auth-manager.d.ts.map +1 -0
  9. package/dist/auth/parse-record.d.ts +19 -0
  10. package/dist/auth/parse-record.d.ts.map +1 -0
  11. package/dist/auth/scoped-token-manager.d.ts +18 -0
  12. package/dist/auth/scoped-token-manager.d.ts.map +1 -0
  13. package/dist/auth/user-manager.d.ts +34 -0
  14. package/dist/auth/user-manager.d.ts.map +1 -0
  15. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts +54 -0
  16. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts.map +1 -0
  17. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +223 -217
  18. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js.map +1 -1
  19. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +216 -7
  20. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs.map +1 -1
  21. package/dist/builtins/addon-pages-aggregator/index.d.ts +2 -0
  22. package/dist/builtins/addon-pages-aggregator/index.d.ts.map +1 -0
  23. package/dist/builtins/addon-pages-aggregator/index.js +6 -221
  24. package/dist/builtins/addon-pages-aggregator/index.mjs +2 -9
  25. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts +33 -0
  26. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts.map +1 -0
  27. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +199 -197
  28. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js.map +1 -1
  29. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +192 -7
  30. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs.map +1 -1
  31. package/dist/builtins/addon-widgets-aggregator/index.d.ts +2 -0
  32. package/dist/builtins/addon-widgets-aggregator/index.d.ts.map +1 -0
  33. package/dist/builtins/addon-widgets-aggregator/index.js +6 -201
  34. package/dist/builtins/addon-widgets-aggregator/index.mjs +2 -9
  35. package/dist/builtins/alerts/alerts.addon.d.ts +82 -0
  36. package/dist/builtins/alerts/alerts.addon.d.ts.map +1 -0
  37. package/dist/builtins/alerts/alerts.addon.js +590 -430
  38. package/dist/builtins/alerts/alerts.addon.js.map +1 -1
  39. package/dist/builtins/alerts/alerts.addon.mjs +595 -7
  40. package/dist/builtins/alerts/alerts.addon.mjs.map +1 -1
  41. package/dist/builtins/alerts/index.d.ts +2 -0
  42. package/dist/builtins/alerts/index.d.ts.map +1 -0
  43. package/dist/builtins/alerts/index.js +3 -443
  44. package/dist/builtins/alerts/index.mjs +2 -8
  45. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.d.ts +8 -0
  46. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.d.ts.map +1 -0
  47. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js +56 -0
  48. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js.map +1 -0
  49. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs +50 -0
  50. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs.map +1 -0
  51. package/dist/builtins/auth-orchestrator/index.d.ts +2 -0
  52. package/dist/builtins/auth-orchestrator/index.d.ts.map +1 -0
  53. package/dist/builtins/auth-orchestrator/index.js +7 -0
  54. package/dist/builtins/auth-orchestrator/index.mjs +2 -0
  55. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +148 -0
  56. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts.map +1 -0
  57. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +7639 -0
  58. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js.map +1 -0
  59. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +7627 -0
  60. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs.map +1 -0
  61. package/dist/builtins/backup-orchestrator/cron-helpers.d.ts +24 -0
  62. package/dist/builtins/backup-orchestrator/cron-helpers.d.ts.map +1 -0
  63. package/dist/builtins/backup-orchestrator/destination-policy.d.ts +73 -0
  64. package/dist/builtins/backup-orchestrator/destination-policy.d.ts.map +1 -0
  65. package/dist/builtins/backup-orchestrator/download-helpers.d.ts +13 -0
  66. package/dist/builtins/backup-orchestrator/download-helpers.d.ts.map +1 -0
  67. package/dist/builtins/backup-orchestrator/index.d.ts +3 -0
  68. package/dist/builtins/backup-orchestrator/index.d.ts.map +1 -0
  69. package/dist/builtins/backup-orchestrator/index.js +7 -0
  70. package/dist/builtins/backup-orchestrator/index.mjs +2 -0
  71. package/dist/builtins/backup-orchestrator/manifest-store.d.ts +78 -0
  72. package/dist/builtins/backup-orchestrator/manifest-store.d.ts.map +1 -0
  73. package/dist/builtins/console-logging/console-destination.d.ts +14 -0
  74. package/dist/builtins/console-logging/console-destination.d.ts.map +1 -0
  75. package/dist/builtins/console-logging/console-logging.addon.d.ts +26 -0
  76. package/dist/builtins/console-logging/console-logging.addon.d.ts.map +1 -0
  77. package/dist/builtins/console-logging/index.d.ts +4 -0
  78. package/dist/builtins/console-logging/index.d.ts.map +1 -0
  79. package/dist/builtins/console-logging/index.js +99 -235
  80. package/dist/builtins/console-logging/index.js.map +1 -1
  81. package/dist/builtins/console-logging/index.mjs +95 -9
  82. package/dist/builtins/console-logging/index.mjs.map +1 -1
  83. package/dist/builtins/device-manager/device-event-propagator.d.ts +27 -0
  84. package/dist/builtins/device-manager/device-event-propagator.d.ts.map +1 -0
  85. package/dist/builtins/device-manager/device-manager.addon.d.ts +259 -0
  86. package/dist/builtins/device-manager/device-manager.addon.d.ts.map +1 -0
  87. package/dist/builtins/device-manager/device-manager.addon.js +2125 -2127
  88. package/dist/builtins/device-manager/device-manager.addon.js.map +1 -1
  89. package/dist/builtins/device-manager/device-manager.addon.mjs +2145 -7
  90. package/dist/builtins/device-manager/device-manager.addon.mjs.map +1 -1
  91. package/dist/builtins/device-manager/index.d.ts +3 -0
  92. package/dist/builtins/device-manager/index.d.ts.map +1 -0
  93. package/dist/builtins/device-manager/index.js +6 -2156
  94. package/dist/builtins/device-manager/index.mjs +2 -10
  95. package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +45 -0
  96. package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts.map +1 -0
  97. package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts +16 -0
  98. package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts.map +1 -0
  99. package/dist/builtins/hub-forwarder/index.d.ts +4 -0
  100. package/dist/builtins/hub-forwarder/index.d.ts.map +1 -0
  101. package/dist/builtins/hub-forwarder/index.js +150 -291
  102. package/dist/builtins/hub-forwarder/index.js.map +1 -1
  103. package/dist/builtins/hub-forwarder/index.mjs +145 -9
  104. package/dist/builtins/hub-forwarder/index.mjs.map +1 -1
  105. package/dist/builtins/local-auth/auth-schema.d.ts +12 -0
  106. package/dist/builtins/local-auth/auth-schema.d.ts.map +1 -0
  107. package/dist/builtins/local-auth/index.d.ts +2 -0
  108. package/dist/builtins/local-auth/index.d.ts.map +1 -0
  109. package/dist/builtins/local-auth/index.js +3 -623
  110. package/dist/builtins/local-auth/index.mjs +2 -8
  111. package/dist/builtins/local-auth/local-auth.addon.d.ts +17 -0
  112. package/dist/builtins/local-auth/local-auth.addon.d.ts.map +1 -0
  113. package/dist/builtins/local-auth/local-auth.addon.js +6861 -589
  114. package/dist/builtins/local-auth/local-auth.addon.js.map +1 -1
  115. package/dist/builtins/local-auth/local-auth.addon.mjs +6883 -7
  116. package/dist/builtins/local-auth/local-auth.addon.mjs.map +1 -1
  117. package/dist/builtins/local-network/index.d.ts +3 -0
  118. package/dist/builtins/local-network/index.d.ts.map +1 -0
  119. package/dist/builtins/local-network/index.js +9 -0
  120. package/dist/builtins/local-network/index.mjs +2 -0
  121. package/dist/builtins/local-network/local-network.addon.d.ts +110 -0
  122. package/dist/builtins/local-network/local-network.addon.d.ts.map +1 -0
  123. package/dist/builtins/local-network/local-network.addon.js +399 -0
  124. package/dist/builtins/local-network/local-network.addon.js.map +1 -0
  125. package/dist/builtins/local-network/local-network.addon.mjs +387 -0
  126. package/dist/builtins/local-network/local-network.addon.mjs.map +1 -0
  127. package/dist/builtins/mesh-orchestrator/index.d.ts +2 -0
  128. package/dist/builtins/mesh-orchestrator/index.d.ts.map +1 -0
  129. package/dist/builtins/mesh-orchestrator/index.js +7 -0
  130. package/dist/builtins/mesh-orchestrator/index.mjs +2 -0
  131. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.d.ts +9 -0
  132. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.d.ts.map +1 -0
  133. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.js +83 -0
  134. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.js.map +1 -0
  135. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.mjs +77 -0
  136. package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.mjs.map +1 -0
  137. package/dist/builtins/native-metrics/index.d.ts +3 -0
  138. package/dist/builtins/native-metrics/index.d.ts.map +1 -0
  139. package/dist/builtins/native-metrics/native-metrics-provider.d.ts +49 -0
  140. package/dist/builtins/native-metrics/native-metrics-provider.d.ts.map +1 -0
  141. package/dist/builtins/native-metrics/native-metrics.addon.d.ts +74 -0
  142. package/dist/builtins/native-metrics/native-metrics.addon.d.ts.map +1 -0
  143. package/dist/builtins/native-metrics/native-metrics.addon.js +887 -861
  144. package/dist/builtins/native-metrics/native-metrics.addon.js.map +1 -1
  145. package/dist/builtins/native-metrics/native-metrics.addon.mjs +914 -5
  146. package/dist/builtins/native-metrics/native-metrics.addon.mjs.map +1 -1
  147. package/dist/builtins/platform-probe/index.d.ts +12 -0
  148. package/dist/builtins/platform-probe/index.d.ts.map +1 -0
  149. package/dist/builtins/platform-probe/index.js +539 -0
  150. package/dist/builtins/platform-probe/index.js.map +1 -0
  151. package/dist/builtins/platform-probe/index.mjs +530 -0
  152. package/dist/builtins/platform-probe/index.mjs.map +1 -0
  153. package/dist/builtins/platform-probe/inference-config-resolver.d.ts +30 -0
  154. package/dist/builtins/platform-probe/inference-config-resolver.d.ts.map +1 -0
  155. package/dist/builtins/platform-probe/platform-scorer.d.ts +22 -0
  156. package/dist/builtins/platform-probe/platform-scorer.d.ts.map +1 -0
  157. package/dist/builtins/remote-access-orchestrator/index.d.ts +2 -0
  158. package/dist/builtins/remote-access-orchestrator/index.d.ts.map +1 -0
  159. package/dist/builtins/remote-access-orchestrator/index.js +7 -0
  160. package/dist/builtins/remote-access-orchestrator/index.mjs +2 -0
  161. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts +9 -0
  162. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts.map +1 -0
  163. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +72 -0
  164. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js.map +1 -0
  165. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +66 -0
  166. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs.map +1 -0
  167. package/dist/builtins/snapshot/index.d.ts +3 -0
  168. package/dist/builtins/snapshot/index.d.ts.map +1 -0
  169. package/dist/builtins/snapshot/index.js +481 -491
  170. package/dist/builtins/snapshot/index.js.map +1 -1
  171. package/dist/builtins/snapshot/index.mjs +475 -464
  172. package/dist/builtins/snapshot/index.mjs.map +1 -1
  173. package/dist/builtins/snapshot/snapshot.addon.d.ts +121 -0
  174. package/dist/builtins/snapshot/snapshot.addon.d.ts.map +1 -0
  175. package/dist/builtins/sqlite-storage/config-store.d.ts +9 -0
  176. package/dist/builtins/sqlite-storage/config-store.d.ts.map +1 -0
  177. package/dist/builtins/sqlite-storage/device-store.d.ts +24 -0
  178. package/dist/builtins/sqlite-storage/device-store.d.ts.map +1 -0
  179. package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts +87 -0
  180. package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts.map +1 -0
  181. package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts +32 -0
  182. package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts.map +1 -0
  183. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +312 -56
  184. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js.map +1 -1
  185. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +305 -7
  186. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs.map +1 -1
  187. package/dist/builtins/sqlite-storage/index.d.ts +12 -0
  188. package/dist/builtins/sqlite-storage/index.d.ts.map +1 -0
  189. package/dist/builtins/sqlite-storage/index.js +229 -1001
  190. package/dist/builtins/sqlite-storage/index.js.map +1 -1
  191. package/dist/builtins/sqlite-storage/index.mjs +268 -26
  192. package/dist/builtins/sqlite-storage/index.mjs.map +1 -1
  193. package/dist/builtins/sqlite-storage/integration-registry.d.ts +28 -0
  194. package/dist/builtins/sqlite-storage/integration-registry.d.ts.map +1 -0
  195. package/dist/builtins/sqlite-storage/settings-store.d.ts +40 -0
  196. package/dist/builtins/sqlite-storage/settings-store.d.ts.map +1 -0
  197. package/dist/builtins/sqlite-storage/sql-schema.d.ts +33 -0
  198. package/dist/builtins/sqlite-storage/sql-schema.d.ts.map +1 -0
  199. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +94 -0
  200. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts.map +1 -0
  201. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +15 -0
  202. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts.map +1 -0
  203. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +586 -653
  204. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js.map +1 -1
  205. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +582 -7
  206. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs.map +1 -1
  207. package/dist/builtins/storage-orchestrator/index.d.ts +7 -0
  208. package/dist/builtins/storage-orchestrator/index.d.ts.map +1 -0
  209. package/dist/builtins/storage-orchestrator/index.js +9 -0
  210. package/dist/builtins/storage-orchestrator/index.mjs +2 -0
  211. package/dist/builtins/storage-orchestrator/location-store.d.ts +50 -0
  212. package/dist/builtins/storage-orchestrator/location-store.d.ts.map +1 -0
  213. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +60 -0
  214. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts.map +1 -0
  215. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +755 -0
  216. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js.map +1 -0
  217. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +746 -0
  218. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs.map +1 -0
  219. package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +121 -0
  220. package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts.map +1 -0
  221. package/dist/builtins/system-backup/system-backup.service.d.ts +138 -0
  222. package/dist/builtins/system-backup/system-backup.service.d.ts.map +1 -0
  223. package/dist/builtins/system-config/index.d.ts +2 -0
  224. package/dist/builtins/system-config/index.d.ts.map +1 -0
  225. package/dist/builtins/system-config/index.js +6 -188
  226. package/dist/builtins/system-config/index.mjs +2 -10
  227. package/dist/builtins/system-config/system-config.addon.d.ts +11 -0
  228. package/dist/builtins/system-config/system-config.addon.d.ts.map +1 -0
  229. package/dist/builtins/system-config/system-config.addon.js +227 -180
  230. package/dist/builtins/system-config/system-config.addon.js.map +1 -1
  231. package/dist/builtins/system-config/system-config.addon.mjs +226 -7
  232. package/dist/builtins/system-config/system-config.addon.mjs.map +1 -1
  233. package/dist/builtins/turn-orchestrator/index.d.ts +2 -0
  234. package/dist/builtins/turn-orchestrator/index.d.ts.map +1 -0
  235. package/dist/builtins/turn-orchestrator/index.js +7 -0
  236. package/dist/builtins/turn-orchestrator/index.mjs +2 -0
  237. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.d.ts +10 -0
  238. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.d.ts.map +1 -0
  239. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.js +78 -0
  240. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.js.map +1 -0
  241. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.mjs +72 -0
  242. package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.mjs.map +1 -0
  243. package/dist/builtins/winston-logging/index.d.ts +4 -0
  244. package/dist/builtins/winston-logging/index.d.ts.map +1 -0
  245. package/dist/builtins/winston-logging/index.js +153 -300
  246. package/dist/builtins/winston-logging/index.js.map +1 -1
  247. package/dist/builtins/winston-logging/index.mjs +144 -9
  248. package/dist/builtins/winston-logging/index.mjs.map +1 -1
  249. package/dist/builtins/winston-logging/winston-destination.d.ts +22 -0
  250. package/dist/builtins/winston-logging/winston-destination.d.ts.map +1 -0
  251. package/dist/builtins/winston-logging/winston-logging.addon.d.ts +20 -0
  252. package/dist/builtins/winston-logging/winston-logging.addon.d.ts.map +1 -0
  253. package/dist/chunk-C13QxCFV.js +50 -0
  254. package/dist/chunk-hT5z_Zn9.mjs +35 -0
  255. package/dist/download/model-download-service.d.ts +42 -0
  256. package/dist/download/model-download-service.d.ts.map +1 -0
  257. package/dist/download/model-downloader.d.ts +32 -0
  258. package/dist/download/model-downloader.d.ts.map +1 -0
  259. package/dist/events/event-bus.d.ts +11 -0
  260. package/dist/events/event-bus.d.ts.map +1 -0
  261. package/dist/events/system-event-bus.d.ts +15 -0
  262. package/dist/events/system-event-bus.d.ts.map +1 -0
  263. package/dist/feature/feature-manager.d.ts +12 -0
  264. package/dist/feature/feature-manager.d.ts.map +1 -0
  265. package/dist/formatter-C-5An4Bl.mjs +164 -0
  266. package/dist/formatter-C-5An4Bl.mjs.map +1 -0
  267. package/dist/formatter-Dr_6NNZc.js +169 -0
  268. package/dist/formatter-Dr_6NNZc.js.map +1 -0
  269. package/dist/index.d.ts +76 -1696
  270. package/dist/index.d.ts.map +1 -0
  271. package/dist/index.js +7780 -8035
  272. package/dist/index.js.map +1 -1
  273. package/dist/index.mjs +7707 -2148
  274. package/dist/index.mjs.map +1 -1
  275. package/dist/lifecycle/lifecycle-state-machine.d.ts +29 -0
  276. package/dist/lifecycle/lifecycle-state-machine.d.ts.map +1 -0
  277. package/dist/logging/formatter.d.ts +31 -0
  278. package/dist/logging/formatter.d.ts.map +1 -0
  279. package/dist/logging/log-manager.d.ts +52 -0
  280. package/dist/logging/log-manager.d.ts.map +1 -0
  281. package/dist/logging/log-ring-buffer.d.ts +48 -0
  282. package/dist/logging/log-ring-buffer.d.ts.map +1 -0
  283. package/dist/logging/scoped-logger.d.ts +18 -0
  284. package/dist/logging/scoped-logger.d.ts.map +1 -0
  285. package/dist/network/network-quality.d.ts +12 -0
  286. package/dist/network/network-quality.d.ts.map +1 -0
  287. package/dist/notification/notification-service.d.ts +38 -0
  288. package/dist/notification/notification-service.d.ts.map +1 -0
  289. package/dist/notification/toast-service.d.ts +23 -0
  290. package/dist/notification/toast-service.d.ts.map +1 -0
  291. package/dist/pipeline/engine-manager-resolver.d.ts +16 -0
  292. package/dist/pipeline/engine-manager-resolver.d.ts.map +1 -0
  293. package/dist/pipeline/pipeline-runner.d.ts +9 -0
  294. package/dist/pipeline/pipeline-runner.d.ts.map +1 -0
  295. package/dist/pipeline/pipeline-validator.d.ts +14 -0
  296. package/dist/pipeline/pipeline-validator.d.ts.map +1 -0
  297. package/dist/process/resource-monitor.d.ts +12 -0
  298. package/dist/process/resource-monitor.d.ts.map +1 -0
  299. package/dist/python/python-env-manager.d.ts +13 -0
  300. package/dist/python/python-env-manager.d.ts.map +1 -0
  301. package/dist/repl/interfaces.d.ts +32 -0
  302. package/dist/repl/interfaces.d.ts.map +1 -0
  303. package/dist/repl/repl-engine.d.ts +9 -0
  304. package/dist/repl/repl-engine.d.ts.map +1 -0
  305. package/dist/resource-monitor-CmuWlmap.js +76 -0
  306. package/dist/resource-monitor-CmuWlmap.js.map +1 -0
  307. package/dist/resource-monitor-DcQdKGYU.mjs +59 -0
  308. package/dist/resource-monitor-DcQdKGYU.mjs.map +1 -0
  309. package/dist/storage/fs-storage-backend.d.ts +41 -0
  310. package/dist/storage/fs-storage-backend.d.ts.map +1 -0
  311. package/dist/storage/storage-location-manager.d.ts +24 -0
  312. package/dist/storage/storage-location-manager.d.ts.map +1 -0
  313. package/dist/storage/storage-manager.d.ts +77 -0
  314. package/dist/storage/storage-manager.d.ts.map +1 -0
  315. package/dist/tls/cert-manager.d.ts +27 -0
  316. package/dist/tls/cert-manager.d.ts.map +1 -0
  317. package/dist/tls/index.d.ts +2 -0
  318. package/dist/tls/index.d.ts.map +1 -0
  319. package/package.json +119 -23
  320. package/dist/builtins/addon-pages-aggregator/index.js.map +0 -1
  321. package/dist/builtins/addon-pages-aggregator/index.mjs.map +0 -1
  322. package/dist/builtins/addon-widgets-aggregator/index.js.map +0 -1
  323. package/dist/builtins/addon-widgets-aggregator/index.mjs.map +0 -1
  324. package/dist/builtins/alerts/index.js.map +0 -1
  325. package/dist/builtins/alerts/index.mjs.map +0 -1
  326. package/dist/builtins/device-manager/index.js.map +0 -1
  327. package/dist/builtins/device-manager/index.mjs.map +0 -1
  328. package/dist/builtins/local-auth/index.js.map +0 -1
  329. package/dist/builtins/local-auth/index.mjs.map +0 -1
  330. package/dist/builtins/local-backup/index.js +0 -173
  331. package/dist/builtins/local-backup/index.js.map +0 -1
  332. package/dist/builtins/local-backup/index.mjs +0 -10
  333. package/dist/builtins/local-backup/index.mjs.map +0 -1
  334. package/dist/builtins/system-config/index.js.map +0 -1
  335. package/dist/builtins/system-config/index.mjs.map +0 -1
  336. package/dist/chunk-2CIYKDRN.mjs +0 -1
  337. package/dist/chunk-2CIYKDRN.mjs.map +0 -1
  338. package/dist/chunk-2F76X6NL.mjs +0 -136
  339. package/dist/chunk-2F76X6NL.mjs.map +0 -1
  340. package/dist/chunk-2QUFBZ7M.mjs +0 -1
  341. package/dist/chunk-2QUFBZ7M.mjs.map +0 -1
  342. package/dist/chunk-3BK2Y7GY.mjs +0 -593
  343. package/dist/chunk-3BK2Y7GY.mjs.map +0 -1
  344. package/dist/chunk-4OOHFJHT.mjs +0 -421
  345. package/dist/chunk-4OOHFJHT.mjs.map +0 -1
  346. package/dist/chunk-4XHB7IHT.mjs +0 -809
  347. package/dist/chunk-4XHB7IHT.mjs.map +0 -1
  348. package/dist/chunk-6M2HSSTQ.mjs +0 -98
  349. package/dist/chunk-6M2HSSTQ.mjs.map +0 -1
  350. package/dist/chunk-7FI7SQS7.mjs +0 -135
  351. package/dist/chunk-7FI7SQS7.mjs.map +0 -1
  352. package/dist/chunk-ED57RCQE.mjs +0 -171
  353. package/dist/chunk-ED57RCQE.mjs.map +0 -1
  354. package/dist/chunk-FZN56HGQ.mjs +0 -626
  355. package/dist/chunk-FZN56HGQ.mjs.map +0 -1
  356. package/dist/chunk-GL4OOB25.mjs +0 -51
  357. package/dist/chunk-GL4OOB25.mjs.map +0 -1
  358. package/dist/chunk-KDG2NTDB.mjs +0 -137
  359. package/dist/chunk-KDG2NTDB.mjs.map +0 -1
  360. package/dist/chunk-NRBQWBDM.mjs +0 -191
  361. package/dist/chunk-NRBQWBDM.mjs.map +0 -1
  362. package/dist/chunk-O4V246GG.mjs +0 -2137
  363. package/dist/chunk-O4V246GG.mjs.map +0 -1
  364. package/dist/chunk-QT57H266.mjs +0 -163
  365. package/dist/chunk-QT57H266.mjs.map +0 -1
  366. package/dist/chunk-QX4RH25I.mjs +0 -141
  367. package/dist/chunk-QX4RH25I.mjs.map +0 -1
  368. package/dist/chunk-TB562PZX.mjs +0 -86
  369. package/dist/chunk-TB562PZX.mjs.map +0 -1
  370. package/dist/chunk-TDYPZXK5.mjs +0 -1
  371. package/dist/chunk-TDYPZXK5.mjs.map +0 -1
  372. package/dist/chunk-UJI4LN5P.mjs +0 -36
  373. package/dist/chunk-UJI4LN5P.mjs.map +0 -1
  374. package/dist/chunk-W6RTHQGP.mjs +0 -1
  375. package/dist/chunk-W6RTHQGP.mjs.map +0 -1
  376. package/dist/chunk-ZELBCPDC.mjs +0 -369
  377. package/dist/chunk-ZELBCPDC.mjs.map +0 -1
  378. package/dist/index.d.mts +0 -1696
  379. package/dist/resource-monitor-UZUGPIAU.mjs +0 -9
  380. package/dist/resource-monitor-UZUGPIAU.mjs.map +0 -1
  381. package/dist/storage-location-manager-HFNB3PCS.mjs +0 -7
  382. package/dist/storage-location-manager-HFNB3PCS.mjs.map +0 -1
@@ -1,504 +1,494 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/builtins/snapshot/index.ts
21
- var snapshot_exports = {};
22
- __export(snapshot_exports, {
23
- SnapshotAddon: () => SnapshotAddon,
24
- default: () => SnapshotAddon
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
25
4
  });
26
- module.exports = __toCommonJS(snapshot_exports);
27
-
28
- // src/builtins/snapshot/snapshot.addon.ts
29
- var import_node_child_process = require("child_process");
30
- var import_types = require("@camstack/types");
31
- var import_types2 = require("@camstack/types");
5
+ require("../../chunk-C13QxCFV.js");
6
+ let node_child_process = require("node:child_process");
7
+ let _camstack_types = require("@camstack/types");
8
+ //#region src/builtins/snapshot/snapshot.addon.ts
9
+ /** Default cache window for non-battery cams (seconds). 10s feels live. */
32
10
  var NON_BATTERY_DEFAULT_MAX_AGE_S = 10;
11
+ /** Default cache window for battery cams (seconds). 1h ≈ "don't wake the cam unless asked". */
33
12
  var BATTERY_DEFAULT_MAX_AGE_S = 3600;
34
- var SnapshotAddon = class extends import_types2.BaseAddon {
35
- cache = /* @__PURE__ */ new Map();
36
- constructor() {
37
- super({
38
- staleTtlMs: 6e4
39
- });
40
- }
41
- async onInitialize() {
42
- this.ctx.logger.info("Snapshot wrapper initialized");
43
- const provider = {
44
- getSnapshot: (input) => this.getSnapshot(input),
45
- invalidateCache: (input) => this.invalidateCache(input),
46
- // DeviceSettingsContribution surface numeric deviceId end-to-end.
47
- getDeviceSettingsContribution: (input) => this.buildDeviceSettingsContribution(input.deviceId),
48
- getDeviceLiveContribution: async () => null,
49
- applyDeviceSettingsPatch: (input) => this.saveDeviceSettingsPatch(input.deviceId, input.patch),
50
- // Status surface — derives a diagnostic snapshot from the cache
51
- // bookkeeping (lastCapturedAt, cacheAgeMs, lastBytes, lastStreamId).
52
- // Returns null when the device has never been captured.
53
- getStatus: async (input) => this.getStatus(input.deviceId)
54
- };
55
- return [{
56
- capability: import_types.snapshotCapability,
57
- provider,
58
- kind: "wrapper",
59
- defaultActive: true
60
- }];
61
- }
62
- async onShutdown() {
63
- this.cache.clear();
64
- }
65
- globalSettingsSchema() {
66
- return this.schema({
67
- sections: [{
68
- id: "snapshot-cache",
69
- title: "Snapshot Cache",
70
- description: "Stale fallback when live capture fails. Per-device freshness is configured under Device \u2192 Snapshot \u2192 Max cache age.",
71
- columns: 1,
72
- fields: [
73
- this.field({
74
- type: "number",
75
- key: "staleTtlMs",
76
- label: "Stale fallback TTL (ms)",
77
- description: "If live capture fails, cached snapshot younger than this is still returned.",
78
- min: 0,
79
- max: 36e5,
80
- step: 1e3,
81
- default: 6e4
82
- })
83
- ]
84
- }]
85
- });
86
- }
87
- // ── Capability methods ────────────────────────────────────────────────
88
- async getSnapshot(input) {
89
- const { deviceId, force } = input;
90
- const meta = await this.lookupDeviceMeta(deviceId);
91
- const deviceName = meta?.name;
92
- const isBatteryDevice = meta?.isBattery ?? false;
93
- const log = this.ctx.logger.withTags({ deviceId, ...deviceName ? { deviceName } : {} });
94
- const now = Date.now();
95
- const hit = this.cache.get(deviceId);
96
- const prefs = await this.readDeviceSettings(deviceId).catch(() => ({}));
97
- const rawPref = prefs.snapshotStreamId;
98
- const effectiveStreamId = input.streamId ?? (rawPref && rawPref !== "auto" ? rawPref : void 0);
99
- if (prefs.snapshotDebug) {
100
- log.info("debug on", { tags: { deviceId }, meta: { stream: effectiveStreamId ?? "auto" } });
101
- }
102
- const defaultMaxAgeS = isBatteryDevice ? BATTERY_DEFAULT_MAX_AGE_S : NON_BATTERY_DEFAULT_MAX_AGE_S;
103
- const effectiveMaxAgeMs = (typeof prefs.snapshotMaxAgeS === "number" && prefs.snapshotMaxAgeS >= 0 ? prefs.snapshotMaxAgeS : defaultMaxAgeS) * 1e3;
104
- if (!force && hit && now - hit.ts < effectiveMaxAgeMs) {
105
- if (prefs.snapshotDebug) {
106
- log.debug("snapshot: cache hit", {
107
- tags: { deviceId },
108
- meta: { ageMs: now - hit.ts, maxAgeMs: effectiveMaxAgeMs, isBattery: isBatteryDevice }
109
- });
110
- }
111
- return hit.data;
112
- }
113
- let nativeError = null;
114
- let nativeAbsent = false;
115
- try {
116
- const native = this.ctx.getNativeProvider(import_types.snapshotCapability, deviceId);
117
- if (native) {
118
- const result = await native.getSnapshot(input);
119
- if (result) {
120
- this.cache.set(deviceId, { data: result, ts: now, streamId: effectiveStreamId ?? null });
121
- return result;
122
- }
123
- } else {
124
- nativeAbsent = true;
125
- }
126
- } catch (err) {
127
- const msg = (0, import_types2.errMsg)(err);
128
- if (isAbsentNativeError(msg)) {
129
- nativeAbsent = true;
130
- log.debug("native snapshot absent", { tags: { deviceId }, meta: { error: msg } });
131
- } else {
132
- nativeError = err;
133
- log.warn("native snapshot failed", { tags: { deviceId }, meta: { error: msg } });
134
- }
135
- }
136
- const skipBrokerForBattery = isBatteryDevice && nativeAbsent && !await this.hasStreamingBrokerForDevice(deviceId);
137
- if (!skipBrokerForBattery) {
138
- try {
139
- const fallback = await this.grabFrameFromBroker(deviceId, effectiveStreamId);
140
- if (fallback) {
141
- this.cache.set(deviceId, { data: fallback, ts: now, streamId: effectiveStreamId ?? null });
142
- return fallback;
143
- }
144
- } catch (err) {
145
- log.warn("stream-broker snapshot fallback failed", { tags: { deviceId }, meta: { error: (0, import_types2.errMsg)(err) } });
146
- }
147
- } else {
148
- log.debug("snapshot: skipping broker fallback \u2014 battery device with absent native and no streaming broker", {
149
- tags: { deviceId }
150
- });
151
- }
152
- if (hit) {
153
- const ageMs = now - hit.ts;
154
- if (ageMs > this.config.staleTtlMs) {
155
- log.warn("snapshot: all live paths failed \u2014 serving stale cache", { tags: { deviceId }, meta: { ageMs } });
156
- }
157
- return hit.data;
158
- }
159
- if (nativeError) throw nativeError;
160
- if (nativeAbsent) return null;
161
- return null;
162
- }
163
- /**
164
- * Tell apart "native provider isn't registered for this device" from
165
- * "native provider ran and threw a real error". The former is the steady
166
- * state for cameras without a vendor snapshot endpoint and should not
167
- * propagate as a 500; the latter should.
168
- */
169
- /**
170
- * Pull one JPEG from the device's stream-broker RTSP restream using
171
- * a short-lived ffmpeg invocation.
172
- *
173
- * Stream selection strategy (picks the broker that won't stall):
174
- * 1. Explicit `preferredStreamId` (user set in per-device settings)
175
- * — always honoured, even if currently idle. Operator choice
176
- * wins.
177
- * 2. Auto: highest-quality broker currently in `streaming` state.
178
- * This is the whole point — prefer the stream that has active
179
- * subscribers (usually `low` for detection, but `mid`/`high`
180
- * if WebRTC is watching) so ffmpeg hits a warm pipe and
181
- * doesn't race the broker's resume.
182
- * 3. Fallback: highest-quality enabled entry regardless of status
183
- * (will wake a suspended broker — retry-guarded against the
184
- * cold-start error).
185
- *
186
- * The stream-broker auto-suspends idle streams on the "no demand"
187
- * signal; snapshots used to default to `high` which was often the
188
- * first to go idle, racing every snapshot with a broker resume.
189
- * Now we ask the orchestrator of streams which one is warm and grab
190
- * from there.
191
- */
192
- async grabFrameFromBroker(deviceId, preferredStreamId) {
193
- const dev = await this.ctx.fetchDevice(deviceId);
194
- const prefix = `${deviceId}/`;
195
- const [deviceEntries, profileSlots] = await Promise.all([
196
- dev.cameraStreams?.getRtspEntries({}) ?? [],
197
- dev.cameraStreams?.getBrokerStreams({}) ?? []
198
- ]);
199
- const usable = deviceEntries.filter((e) => e.enabled && !!e.url);
200
- if (usable.length === 0) return null;
201
- if (preferredStreamId && preferredStreamId !== "auto") {
202
- const explicit = usable.find((e) => e.brokerId === `${prefix}${preferredStreamId}`);
203
- if (explicit) {
204
- const grabbed = await this.runGrabWithResumeRetry(explicit.url, deviceId);
205
- if (grabbed) return grabbed;
206
- this.ctx.logger.debug("grabFrame: explicit stream failed \u2014 falling back to auto", { meta: { preferredStreamId } });
207
- }
208
- }
209
- const ranked = [...usable].sort(
210
- (a, b) => qualityRank(b.brokerId, prefix) - qualityRank(a.brokerId, prefix)
211
- );
212
- const statusByBrokerId = /* @__PURE__ */ new Map();
213
- for (const slot of profileSlots) statusByBrokerId.set(slot.brokerId, slot.status);
214
- const statuses = ranked.map((e) => ({ entry: e, status: statusByBrokerId.get(e.brokerId) ?? "idle" }));
215
- const warm = statuses.find((s) => s.status === "streaming");
216
- if (warm) {
217
- const grabbed = await this.runGrabWithResumeRetry(warm.entry.url, deviceId);
218
- if (grabbed) return grabbed;
219
- }
220
- for (const { entry } of statuses) {
221
- const grabbed = await this.runGrabWithResumeRetry(entry.url, deviceId).catch(() => null);
222
- if (grabbed) return grabbed;
223
- }
224
- return null;
225
- }
226
- /**
227
- * Ffmpeg grab with one retry on the broker-cold-start error
228
- * signature. Covers the window between "client connected" and
229
- * "first keyframe" when a suspended broker resumes.
230
- */
231
- async runGrabWithResumeRetry(url, deviceId) {
232
- let buf;
233
- try {
234
- buf = await runFfmpegFrameGrab(url, 15e3);
235
- } catch (err) {
236
- const msg = (0, import_types2.errMsg)(err);
237
- if (isBrokerColdError(msg)) {
238
- this.ctx.logger.debug("grabFrame: broker-resume race \u2014 retrying in 1500ms", { tags: { deviceId } });
239
- await new Promise((r) => setTimeout(r, 1500));
240
- buf = await runFfmpegFrameGrab(url, 15e3);
241
- } else {
242
- throw err;
243
- }
244
- }
245
- if (buf.length === 0) return null;
246
- return { base64: buf.toString("base64"), contentType: "image/jpeg" };
247
- }
248
- async invalidateCache(input) {
249
- this.cache.delete(input.deviceId);
250
- }
251
- /**
252
- * Non-throwing probe of the device's battery cap. Returns true only
253
- * when a battery native is registered AND its current status says
254
- * `sleeping: true`. Any error (no provider, native absent, getStatus
255
- * missing, RPC timeout) is swallowed and treated as "awake" — we'd
256
- * rather pay a wake-up than strand the caller on a cache that's
257
- * semantically stale. Debug-logged for observability.
258
- */
259
- /**
260
- * True when at least one of the device's brokers is actively
261
- * streaming (status === 'streaming'). Used by the battery-cam guard
262
- * around `grabFrameFromBroker` to allow the fallback ONLY when
263
- * grabbing a frame is free (a consumer is already keeping the
264
- * stream warm). When everything is suspended, the fallback would
265
- * dial the camera and wake it — defeats the sleeping cache.
266
- */
267
- async hasStreamingBrokerForDevice(deviceId) {
268
- try {
269
- const dev = await this.ctx.fetchDevice(deviceId);
270
- const slots = await dev.cameraStreams?.getBrokerStreams({}) ?? [];
271
- return slots.some((s) => s.status === "streaming");
272
- } catch {
273
- return false;
274
- }
275
- }
276
- /**
277
- * Diagnostic status for the `status` auto-injected cap method. Reports
278
- * the cache bookkeeping for this device — when the last snapshot was
279
- * captured, how stale the cached image is, its size, and which stream
280
- * was used. Returns null when the device has never been captured
281
- * (cache miss) since the addon started.
282
- */
283
- async getStatus(deviceId) {
284
- const hit = this.cache.get(deviceId);
285
- if (!hit) return null;
286
- return {
287
- lastCapturedAt: hit.ts,
288
- cacheAgeMs: Date.now() - hit.ts,
289
- lastBytes: hit.data.base64.length,
290
- // approx bytes = base64 length * 3/4, but length is stable enough
291
- lastStreamId: hit.streamId
292
- };
293
- }
294
- // ── DeviceSettingsContribution ────────────────────────────────────────
295
- //
296
- // Snapshot carries two per-device knobs:
297
- // - `snapshotStreamId` which stream to prefer when grabbing frames
298
- // (empty = auto / default "main")
299
- // - `snapshotDebug` extra logging for troubleshooting snapshot paths
300
- //
301
- // Storage uses the addon's own per-device store (`ctx.settings
302
- // .writeDeviceStore`), not the device's config. The schema isn't
303
- // captured in a Zod object: the keys are optional and the UI layer
304
- // validates shapes.
305
- async readDeviceSettings(deviceId) {
306
- if (!this.ctx.settings) return {};
307
- const raw = await this.ctx.settings.readDeviceStore(deviceId);
308
- const rawAge = raw["snapshotMaxAgeS"];
309
- const maxAgeS = typeof rawAge === "number" && rawAge >= 0 && Number.isFinite(rawAge) ? rawAge : void 0;
310
- return {
311
- snapshotStreamId: typeof raw["snapshotStreamId"] === "string" ? raw["snapshotStreamId"] : void 0,
312
- snapshotDebug: raw["snapshotDebug"] === true,
313
- ...maxAgeS !== void 0 ? { snapshotMaxAgeS: maxAgeS } : {}
314
- };
315
- }
316
- async buildDeviceSettingsContribution(deviceId) {
317
- const meta = await this.lookupDeviceMeta(deviceId);
318
- if (meta && meta.type !== import_types.DeviceType.Camera) return null;
319
- const current = await this.readDeviceSettings(deviceId);
320
- const streamOptions = await this.getStreamOptions(deviceId);
321
- const isBattery = await this.isDeviceBattery(deviceId);
322
- const defaultMaxAgeS = isBattery ? BATTERY_DEFAULT_MAX_AGE_S : NON_BATTERY_DEFAULT_MAX_AGE_S;
323
- return {
324
- sections: [{
325
- id: "snapshot-preferences",
326
- title: "Snapshot",
327
- tab: "snapshot",
328
- order: 60,
329
- fields: [
330
- {
331
- type: "select",
332
- key: "snapshotStreamId",
333
- label: "Preferred stream",
334
- description: "Stream used when grabbing a snapshot",
335
- options: streamOptions,
336
- required: true,
337
- value: current.snapshotStreamId || "auto"
338
- },
339
- {
340
- type: "number",
341
- key: "snapshotMaxAgeS",
342
- label: "Max cache age (s)",
343
- description: `Serve cached snapshot up to this age before re-capturing. Default ${defaultMaxAgeS}s for ${isBattery ? "battery cams (avoids gratuitous wake-ups)" : "non-battery cams (live-feel)"}. The UI refresh button always forces a fresh capture regardless of this value.`,
344
- min: 0,
345
- max: 24 * 3600,
346
- step: 1,
347
- value: current.snapshotMaxAgeS ?? defaultMaxAgeS
348
- },
349
- {
350
- type: "boolean",
351
- key: "snapshotDebug",
352
- label: "Debug logging",
353
- description: "Log stream selection and timing details for this device.",
354
- value: current.snapshotDebug ?? false
355
- }
356
- ]
357
- }]
358
- };
359
- }
360
- /**
361
- * Single-trip device lookup against device-manager. Returns the
362
- * fields the wrapper actually consults — name (logging) + battery
363
- * flag (cache window + broker-fallback gate). Sourced from the
364
- * device-manager registry rather than the battery cap so the answer
365
- * survives a momentarily-unreachable provider (the very condition
366
- * we're trying to be resilient to).
367
- *
368
- * Logged at debug + null return on failure: every call site already
369
- * has a sensible fallback path (cache hit, conservative default, …),
370
- * so we don't want a transient device-manager hiccup to throw.
371
- */
372
- async lookupDeviceMeta(deviceId) {
373
- const api = this.ctx.api;
374
- if (!api) return null;
375
- try {
376
- const found = await api.deviceManager.getDevice.query({ deviceId });
377
- if (!found) return null;
378
- const features = found.features ?? [];
379
- const rawType = found.type;
380
- return {
381
- ...found.name ? { name: found.name } : {},
382
- isBattery: features.includes(import_types.DeviceFeature.BatteryOperated),
383
- ...rawType ? { type: rawType } : {}
384
- };
385
- } catch (err) {
386
- this.ctx.logger.debug("deviceManager.getDevice failed during snapshot", {
387
- tags: { deviceId },
388
- meta: { error: err instanceof Error ? err.message : String(err) }
389
- });
390
- return null;
391
- }
392
- }
393
- /** Settings-UI helper — battery flag drives the default max-age in the field description. */
394
- async isDeviceBattery(deviceId) {
395
- return (await this.lookupDeviceMeta(deviceId))?.isBattery ?? false;
396
- }
397
- async getStreamOptions(deviceId) {
398
- const prefix = `${deviceId}/`;
399
- try {
400
- const dev = await this.ctx.fetchDevice(deviceId);
401
- const entries = await dev.cameraStreams?.getRtspEntries({}) ?? [];
402
- const streamIds = entries.filter((e) => e.enabled).map((e) => e.brokerId.slice(prefix.length));
403
- return [
404
- { value: "auto", label: "Auto" },
405
- ...streamIds.map((id) => ({ value: id, label: (0, import_types2.streamQualityLabel)(id) }))
406
- ];
407
- } catch (err) {
408
- this.ctx.logger.error("getStreamOptions failed", { tags: { deviceId }, meta: { error: (0, import_types2.errMsg)(err) } });
409
- return [{ value: "auto", label: "Auto" }];
410
- }
411
- }
412
- async saveDeviceSettingsPatch(deviceId, patch) {
413
- if (!this.ctx.settings) {
414
- throw new Error("[snapshot] settings store unavailable \u2014 cannot persist per-device settings");
415
- }
416
- const current = await this.ctx.settings.readDeviceStore(deviceId);
417
- const next = { ...current };
418
- if ("snapshotStreamId" in patch) {
419
- const v = patch["snapshotStreamId"];
420
- next["snapshotStreamId"] = typeof v === "string" && v.trim().length > 0 ? v.trim() : "";
421
- }
422
- if ("snapshotDebug" in patch) {
423
- next["snapshotDebug"] = patch["snapshotDebug"] === true;
424
- }
425
- if ("snapshotMaxAgeS" in patch) {
426
- const v = patch["snapshotMaxAgeS"];
427
- if (typeof v === "number" && Number.isFinite(v) && v >= 0) {
428
- next["snapshotMaxAgeS"] = v;
429
- } else {
430
- delete next["snapshotMaxAgeS"];
431
- }
432
- }
433
- await this.ctx.settings.writeDeviceStore(deviceId, next);
434
- this.cache.delete(deviceId);
435
- return { success: true };
436
- }
13
+ /**
14
+ * SnapshotAddon wrapper over the `snapshot` capability.
15
+ *
16
+ * Activated per-device (toggleable by user; default active). When active,
17
+ * caches fresh snapshots in memory. On cache miss, delegates to the native
18
+ * provider for this device via `ctx.getNativeProvider(snapshotCapability, id)`.
19
+ *
20
+ * No silent fallback — if the native fails, propagate the error up. Stale
21
+ * cache is returned ONLY when the native throws AND a stale entry exists,
22
+ * and the failure is logged so the fallback is never silent.
23
+ *
24
+ * Frame-grab fallback: when the native provider is absent (or returns null /
25
+ * throws), we ask the `stream-broker` capability for the device's RTSP
26
+ * restream URL and pipe one JPEG out of ffmpeg. stream-broker intentionally
27
+ * does NOT expose a `grabFrame` method — the orchestration (native-first,
28
+ * ffmpeg fallback, caching) is this addon's concern; stream-broker only
29
+ * publishes stream endpoints.
30
+ */
31
+ var SnapshotAddon = class extends _camstack_types.BaseAddon {
32
+ cache = /* @__PURE__ */ new Map();
33
+ constructor() {
34
+ super({ staleTtlMs: 6e4 });
35
+ }
36
+ async onInitialize() {
37
+ this.ctx.logger.info("Snapshot wrapper initialized");
38
+ return [{
39
+ capability: _camstack_types.snapshotCapability,
40
+ provider: {
41
+ getSnapshot: (input) => this.getSnapshot(input),
42
+ invalidateCache: (input) => this.invalidateCache(input),
43
+ getDeviceSettingsContribution: (input) => this.buildDeviceSettingsContribution(input.deviceId),
44
+ getDeviceLiveContribution: async () => null,
45
+ applyDeviceSettingsPatch: (input) => this.saveDeviceSettingsPatch(input.deviceId, input.patch),
46
+ getStatus: async (input) => this.getStatus(input.deviceId)
47
+ },
48
+ kind: "wrapper",
49
+ defaultActive: true
50
+ }];
51
+ }
52
+ async onShutdown() {
53
+ this.cache.clear();
54
+ }
55
+ globalSettingsSchema() {
56
+ return this.schema({ sections: [{
57
+ id: "snapshot-cache",
58
+ title: "Snapshot Cache",
59
+ description: "Stale fallback when live capture fails. Per-device freshness is configured under Device → Snapshot → Max cache age.",
60
+ columns: 1,
61
+ fields: [this.field({
62
+ type: "number",
63
+ key: "staleTtlMs",
64
+ label: "Stale fallback TTL (ms)",
65
+ description: "If live capture fails, cached snapshot younger than this is still returned.",
66
+ min: 0,
67
+ max: 36e5,
68
+ step: 1e3,
69
+ default: 6e4
70
+ })]
71
+ }] });
72
+ }
73
+ async getSnapshot(input) {
74
+ const { deviceId, force } = input;
75
+ const meta = await this.lookupDeviceMeta(deviceId);
76
+ const deviceName = meta?.name;
77
+ const isBatteryDevice = meta?.isBattery ?? false;
78
+ const log = this.ctx.logger.withTags({
79
+ deviceId,
80
+ ...deviceName ? { deviceName } : {}
81
+ });
82
+ const now = Date.now();
83
+ const hit = this.cache.get(deviceId);
84
+ const prefs = await this.readDeviceSettings(deviceId).catch(() => ({}));
85
+ const rawPref = prefs.snapshotStreamId;
86
+ const effectiveStreamId = input.streamId ?? (rawPref && rawPref !== "auto" ? rawPref : void 0);
87
+ if (prefs.snapshotDebug) log.info("debug on", {
88
+ tags: { deviceId },
89
+ meta: { stream: effectiveStreamId ?? "auto" }
90
+ });
91
+ const defaultMaxAgeS = isBatteryDevice ? BATTERY_DEFAULT_MAX_AGE_S : NON_BATTERY_DEFAULT_MAX_AGE_S;
92
+ const effectiveMaxAgeMs = (typeof prefs.snapshotMaxAgeS === "number" && prefs.snapshotMaxAgeS >= 0 ? prefs.snapshotMaxAgeS : defaultMaxAgeS) * 1e3;
93
+ if (!force && hit && now - hit.ts < effectiveMaxAgeMs) {
94
+ if (prefs.snapshotDebug) log.debug("snapshot: cache hit", {
95
+ tags: { deviceId },
96
+ meta: {
97
+ ageMs: now - hit.ts,
98
+ maxAgeMs: effectiveMaxAgeMs,
99
+ isBattery: isBatteryDevice
100
+ }
101
+ });
102
+ return hit.data;
103
+ }
104
+ let nativeError = null;
105
+ let nativeAbsent = false;
106
+ try {
107
+ const native = this.ctx.getNativeProvider(_camstack_types.snapshotCapability, deviceId);
108
+ if (native) {
109
+ const result = await native.getSnapshot(input);
110
+ if (result) {
111
+ this.cache.set(deviceId, {
112
+ data: result,
113
+ ts: now,
114
+ streamId: effectiveStreamId ?? null
115
+ });
116
+ return result;
117
+ }
118
+ } else nativeAbsent = true;
119
+ } catch (err) {
120
+ const msg = (0, _camstack_types.errMsg)(err);
121
+ if (isAbsentNativeError(msg)) {
122
+ nativeAbsent = true;
123
+ log.debug("native snapshot absent", {
124
+ tags: { deviceId },
125
+ meta: { error: msg }
126
+ });
127
+ } else {
128
+ nativeError = err;
129
+ log.warn("native snapshot failed", {
130
+ tags: { deviceId },
131
+ meta: { error: msg }
132
+ });
133
+ }
134
+ }
135
+ if (!(isBatteryDevice && nativeAbsent && !await this.hasStreamingBrokerForDevice(deviceId))) try {
136
+ const fallback = await this.grabFrameFromBroker(deviceId, effectiveStreamId);
137
+ if (fallback) {
138
+ this.cache.set(deviceId, {
139
+ data: fallback,
140
+ ts: now,
141
+ streamId: effectiveStreamId ?? null
142
+ });
143
+ return fallback;
144
+ }
145
+ } catch (err) {
146
+ log.warn("stream-broker snapshot fallback failed", {
147
+ tags: { deviceId },
148
+ meta: { error: (0, _camstack_types.errMsg)(err) }
149
+ });
150
+ }
151
+ else log.debug("snapshot: skipping broker fallback — battery device with absent native and no streaming broker", { tags: { deviceId } });
152
+ if (hit) {
153
+ const ageMs = now - hit.ts;
154
+ if (ageMs > this.config.staleTtlMs) log.warn("snapshot: all live paths failed — serving stale cache", {
155
+ tags: { deviceId },
156
+ meta: { ageMs }
157
+ });
158
+ return hit.data;
159
+ }
160
+ if (nativeError) throw nativeError;
161
+ if (nativeAbsent) return null;
162
+ return null;
163
+ }
164
+ /**
165
+ * Tell apart "native provider isn't registered for this device" from
166
+ * "native provider ran and threw a real error". The former is the steady
167
+ * state for cameras without a vendor snapshot endpoint and should not
168
+ * propagate as a 500; the latter should.
169
+ */
170
+ /**
171
+ * Pull one JPEG from the device's stream-broker RTSP restream using
172
+ * a short-lived ffmpeg invocation.
173
+ *
174
+ * Stream selection strategy (picks the broker that won't stall):
175
+ * 1. Explicit `preferredStreamId` (user set in per-device settings)
176
+ * — always honoured, even if currently idle. Operator choice
177
+ * wins.
178
+ * 2. Auto: highest-quality broker currently in `streaming` state.
179
+ * This is the whole point — prefer the stream that has active
180
+ * subscribers (usually `low` for detection, but `mid`/`high`
181
+ * if WebRTC is watching) so ffmpeg hits a warm pipe and
182
+ * doesn't race the broker's resume.
183
+ * 3. Fallback: highest-quality enabled entry regardless of status
184
+ * (will wake a suspended broker — retry-guarded against the
185
+ * cold-start error).
186
+ *
187
+ * The stream-broker auto-suspends idle streams on the "no demand"
188
+ * signal; snapshots used to default to `high` which was often the
189
+ * first to go idle, racing every snapshot with a broker resume.
190
+ * Now we ask the orchestrator of streams which one is warm and grab
191
+ * from there.
192
+ */
193
+ async grabFrameFromBroker(deviceId, preferredStreamId) {
194
+ const dev = await this.ctx.fetchDevice(deviceId);
195
+ const prefix = `${deviceId}/`;
196
+ const [deviceEntries, profileSlots] = await Promise.all([dev.cameraStreams?.getRtspEntries({}) ?? [], dev.cameraStreams?.getBrokerStreams({}) ?? []]);
197
+ const usable = deviceEntries.filter((e) => e.enabled && !!e.url);
198
+ if (usable.length === 0) return null;
199
+ if (preferredStreamId && preferredStreamId !== "auto") {
200
+ const explicit = usable.find((e) => e.brokerId === `${prefix}${preferredStreamId}`);
201
+ if (explicit) {
202
+ const grabbed = await this.runGrabWithResumeRetry(explicit.url, deviceId);
203
+ if (grabbed) return grabbed;
204
+ this.ctx.logger.debug("grabFrame: explicit stream failed — falling back to auto", { meta: { preferredStreamId } });
205
+ }
206
+ }
207
+ const ranked = [...usable].sort((a, b) => qualityRank(b.brokerId, prefix) - qualityRank(a.brokerId, prefix));
208
+ const statusByBrokerId = /* @__PURE__ */ new Map();
209
+ for (const slot of profileSlots) statusByBrokerId.set(slot.brokerId, slot.status);
210
+ const statuses = ranked.map((e) => ({
211
+ entry: e,
212
+ status: statusByBrokerId.get(e.brokerId) ?? "idle"
213
+ }));
214
+ const warm = statuses.find((s) => s.status === "streaming");
215
+ if (warm) {
216
+ const grabbed = await this.runGrabWithResumeRetry(warm.entry.url, deviceId);
217
+ if (grabbed) return grabbed;
218
+ }
219
+ for (const { entry } of statuses) {
220
+ const grabbed = await this.runGrabWithResumeRetry(entry.url, deviceId).catch(() => null);
221
+ if (grabbed) return grabbed;
222
+ }
223
+ return null;
224
+ }
225
+ /**
226
+ * Ffmpeg grab with one retry on the broker-cold-start error
227
+ * signature. Covers the window between "client connected" and
228
+ * "first keyframe" when a suspended broker resumes.
229
+ */
230
+ async runGrabWithResumeRetry(url, deviceId) {
231
+ let buf;
232
+ try {
233
+ buf = await runFfmpegFrameGrab(url, 15e3);
234
+ } catch (err) {
235
+ if (isBrokerColdError((0, _camstack_types.errMsg)(err))) {
236
+ this.ctx.logger.debug("grabFrame: broker-resume race — retrying in 1500ms", { tags: { deviceId } });
237
+ await new Promise((r) => setTimeout(r, 1500));
238
+ buf = await runFfmpegFrameGrab(url, 15e3);
239
+ } else throw err;
240
+ }
241
+ if (buf.length === 0) return null;
242
+ return {
243
+ base64: buf.toString("base64"),
244
+ contentType: "image/jpeg"
245
+ };
246
+ }
247
+ async invalidateCache(input) {
248
+ this.cache.delete(input.deviceId);
249
+ }
250
+ /**
251
+ * Non-throwing probe of the device's battery cap. Returns true only
252
+ * when a battery native is registered AND its current status says
253
+ * `sleeping: true`. Any error (no provider, native absent, getStatus
254
+ * missing, RPC timeout) is swallowed and treated as "awake" — we'd
255
+ * rather pay a wake-up than strand the caller on a cache that's
256
+ * semantically stale. Debug-logged for observability.
257
+ */
258
+ /**
259
+ * True when at least one of the device's brokers is actively
260
+ * streaming (status === 'streaming'). Used by the battery-cam guard
261
+ * around `grabFrameFromBroker` to allow the fallback ONLY when
262
+ * grabbing a frame is free (a consumer is already keeping the
263
+ * stream warm). When everything is suspended, the fallback would
264
+ * dial the camera and wake it — defeats the sleeping cache.
265
+ */
266
+ async hasStreamingBrokerForDevice(deviceId) {
267
+ try {
268
+ return (await (await this.ctx.fetchDevice(deviceId)).cameraStreams?.getBrokerStreams({}) ?? []).some((s) => s.status === "streaming");
269
+ } catch {
270
+ return false;
271
+ }
272
+ }
273
+ /**
274
+ * Diagnostic status for the `status` auto-injected cap method. Reports
275
+ * the cache bookkeeping for this device — when the last snapshot was
276
+ * captured, how stale the cached image is, its size, and which stream
277
+ * was used. Returns null when the device has never been captured
278
+ * (cache miss) since the addon started.
279
+ */
280
+ async getStatus(deviceId) {
281
+ const hit = this.cache.get(deviceId);
282
+ if (!hit) return null;
283
+ return {
284
+ lastCapturedAt: hit.ts,
285
+ cacheAgeMs: Date.now() - hit.ts,
286
+ lastBytes: hit.data.base64.length,
287
+ lastStreamId: hit.streamId
288
+ };
289
+ }
290
+ async readDeviceSettings(deviceId) {
291
+ if (!this.ctx.settings) return {};
292
+ const raw = await this.ctx.settings.readDeviceStore(deviceId);
293
+ const rawAge = raw["snapshotMaxAgeS"];
294
+ const maxAgeS = typeof rawAge === "number" && rawAge >= 0 && Number.isFinite(rawAge) ? rawAge : void 0;
295
+ return {
296
+ snapshotStreamId: typeof raw["snapshotStreamId"] === "string" ? raw["snapshotStreamId"] : void 0,
297
+ snapshotDebug: raw["snapshotDebug"] === true,
298
+ ...maxAgeS !== void 0 ? { snapshotMaxAgeS: maxAgeS } : {}
299
+ };
300
+ }
301
+ async buildDeviceSettingsContribution(deviceId) {
302
+ const meta = await this.lookupDeviceMeta(deviceId);
303
+ if (meta && meta.type !== _camstack_types.DeviceType.Camera) return null;
304
+ const current = await this.readDeviceSettings(deviceId);
305
+ const streamOptions = await this.getStreamOptions(deviceId);
306
+ const isBattery = await this.isDeviceBattery(deviceId);
307
+ const defaultMaxAgeS = isBattery ? BATTERY_DEFAULT_MAX_AGE_S : NON_BATTERY_DEFAULT_MAX_AGE_S;
308
+ return { sections: [{
309
+ id: "snapshot-preferences",
310
+ title: "Snapshot",
311
+ tab: "snapshot",
312
+ order: 60,
313
+ fields: [
314
+ {
315
+ type: "select",
316
+ key: "snapshotStreamId",
317
+ label: "Preferred stream",
318
+ description: "Stream used when grabbing a snapshot",
319
+ options: streamOptions,
320
+ required: true,
321
+ value: current.snapshotStreamId || "auto"
322
+ },
323
+ {
324
+ type: "number",
325
+ key: "snapshotMaxAgeS",
326
+ label: "Max cache age (s)",
327
+ description: `Serve cached snapshot up to this age before re-capturing. Default ${defaultMaxAgeS}s for ${isBattery ? "battery cams (avoids gratuitous wake-ups)" : "non-battery cams (live-feel)"}. The UI refresh button always forces a fresh capture regardless of this value.`,
328
+ min: 0,
329
+ max: 24 * 3600,
330
+ step: 1,
331
+ value: current.snapshotMaxAgeS ?? defaultMaxAgeS
332
+ },
333
+ {
334
+ type: "boolean",
335
+ key: "snapshotDebug",
336
+ label: "Debug logging",
337
+ description: "Log stream selection and timing details for this device.",
338
+ value: current.snapshotDebug ?? false
339
+ }
340
+ ]
341
+ }] };
342
+ }
343
+ /**
344
+ * Single-trip device lookup against device-manager. Returns the
345
+ * fields the wrapper actually consults — name (logging) + battery
346
+ * flag (cache window + broker-fallback gate). Sourced from the
347
+ * device-manager registry rather than the battery cap so the answer
348
+ * survives a momentarily-unreachable provider (the very condition
349
+ * we're trying to be resilient to).
350
+ *
351
+ * Logged at debug + null return on failure: every call site already
352
+ * has a sensible fallback path (cache hit, conservative default, …),
353
+ * so we don't want a transient device-manager hiccup to throw.
354
+ */
355
+ async lookupDeviceMeta(deviceId) {
356
+ const api = this.ctx.api;
357
+ if (!api) return null;
358
+ try {
359
+ const found = await api.deviceManager.getDevice.query({ deviceId });
360
+ if (!found) return null;
361
+ const features = found.features ?? [];
362
+ const rawType = found.type;
363
+ return {
364
+ ...found.name ? { name: found.name } : {},
365
+ isBattery: features.includes(_camstack_types.DeviceFeature.BatteryOperated),
366
+ ...rawType ? { type: rawType } : {}
367
+ };
368
+ } catch (err) {
369
+ this.ctx.logger.debug("deviceManager.getDevice failed during snapshot", {
370
+ tags: { deviceId },
371
+ meta: { error: err instanceof Error ? err.message : String(err) }
372
+ });
373
+ return null;
374
+ }
375
+ }
376
+ /** Settings-UI helper — battery flag drives the default max-age in the field description. */
377
+ async isDeviceBattery(deviceId) {
378
+ return (await this.lookupDeviceMeta(deviceId))?.isBattery ?? false;
379
+ }
380
+ async getStreamOptions(deviceId) {
381
+ const prefix = `${deviceId}/`;
382
+ try {
383
+ return [{
384
+ value: "auto",
385
+ label: "Auto"
386
+ }, ...(await (await this.ctx.fetchDevice(deviceId)).cameraStreams?.getRtspEntries({}) ?? []).filter((e) => e.enabled).map((e) => e.brokerId.slice(prefix.length)).map((id) => ({
387
+ value: id,
388
+ label: (0, _camstack_types.streamQualityLabel)(id)
389
+ }))];
390
+ } catch (err) {
391
+ this.ctx.logger.error("getStreamOptions failed", {
392
+ tags: { deviceId },
393
+ meta: { error: (0, _camstack_types.errMsg)(err) }
394
+ });
395
+ return [{
396
+ value: "auto",
397
+ label: "Auto"
398
+ }];
399
+ }
400
+ }
401
+ async saveDeviceSettingsPatch(deviceId, patch) {
402
+ if (!this.ctx.settings) throw new Error("[snapshot] settings store unavailable — cannot persist per-device settings");
403
+ const next = { ...await this.ctx.settings.readDeviceStore(deviceId) };
404
+ if ("snapshotStreamId" in patch) {
405
+ const v = patch["snapshotStreamId"];
406
+ next["snapshotStreamId"] = typeof v === "string" && v.trim().length > 0 ? v.trim() : "";
407
+ }
408
+ if ("snapshotDebug" in patch) next["snapshotDebug"] = patch["snapshotDebug"] === true;
409
+ if ("snapshotMaxAgeS" in patch) {
410
+ const v = patch["snapshotMaxAgeS"];
411
+ if (typeof v === "number" && Number.isFinite(v) && v >= 0) next["snapshotMaxAgeS"] = v;
412
+ else delete next["snapshotMaxAgeS"];
413
+ }
414
+ await this.ctx.settings.writeDeviceStore(deviceId, next);
415
+ this.cache.delete(deviceId);
416
+ return { success: true };
417
+ }
437
418
  };
438
419
  function isAbsentNativeError(msg) {
439
- return msg.includes("no provider for") || msg.includes("no native provider for capability");
420
+ return msg.includes("no provider for") || msg.includes("no native provider for capability");
440
421
  }
422
+ /**
423
+ * Quality ordering for broker picker: `high` > `mid` > `low` > other.
424
+ * The streamId is the suffix after `${deviceId}/` in the brokerId.
425
+ * Unknown labels fall through to 0 so they land at the bottom of the
426
+ * preference list without crashing.
427
+ */
441
428
  function qualityRank(brokerId, prefix) {
442
- const streamId = brokerId.startsWith(prefix) ? brokerId.slice(prefix.length) : brokerId;
443
- const normalized = streamId.toLowerCase();
444
- if (normalized.includes("high") || normalized === "main" || normalized === "hd") return 3;
445
- if (normalized.includes("mid") || normalized === "medium") return 2;
446
- if (normalized.includes("low") || normalized === "sub" || normalized === "sd") return 1;
447
- return 0;
429
+ const normalized = (brokerId.startsWith(prefix) ? brokerId.slice(prefix.length) : brokerId).toLowerCase();
430
+ if (normalized.includes("high") || normalized === "main" || normalized === "hd") return 3;
431
+ if (normalized.includes("mid") || normalized === "medium") return 2;
432
+ if (normalized.includes("low") || normalized === "sub" || normalized === "sd") return 1;
433
+ return 0;
448
434
  }
435
+ /**
436
+ * Detect ffmpeg failure signatures that indicate the broker wasn't
437
+ * streaming yet when we tried to read its RTSP restream — a race
438
+ * window that closes as soon as the broker lands its first keyframe.
439
+ * Used by `grabFrameFromBroker` to retry once instead of giving up.
440
+ */
449
441
  function isBrokerColdError(msg) {
450
- return msg.includes("Invalid data found when processing input") || msg.includes("Error opening input") || msg.includes("Connection refused") || msg.includes("No route to host");
442
+ return msg.includes("Invalid data found when processing input") || msg.includes("Error opening input") || msg.includes("Connection refused") || msg.includes("No route to host");
451
443
  }
452
444
  function runFfmpegFrameGrab(url, timeoutMs) {
453
- return new Promise((resolve, reject) => {
454
- const child = (0, import_node_child_process.execFile)(
455
- "ffmpeg",
456
- [
457
- "-loglevel",
458
- "error",
459
- "-rtsp_transport",
460
- "tcp",
461
- "-fflags",
462
- "+discardcorrupt",
463
- "-skip_frame",
464
- "nokey",
465
- "-i",
466
- url,
467
- "-vf",
468
- "select=eq(pict_type\\,I)",
469
- "-vsync",
470
- "vfr",
471
- "-frames:v",
472
- "1",
473
- "-q:v",
474
- "3",
475
- "-f",
476
- "image2pipe",
477
- "-vcodec",
478
- "mjpeg",
479
- "pipe:1"
480
- ],
481
- { encoding: "buffer", maxBuffer: 16 * 1024 * 1024, timeout: timeoutMs },
482
- (err, stdout, stderr) => {
483
- if (err) {
484
- const errWithMeta = err;
485
- const stderrText = Buffer.isBuffer(stderr) ? stderr.toString("utf8").trim() : String(stderr ?? "").trim();
486
- const parts = [err instanceof Error ? err.message : String(err)];
487
- if (errWithMeta.killed) parts.push("killed=true");
488
- if (errWithMeta.code !== void 0) parts.push(`code=${String(errWithMeta.code)}`);
489
- if (errWithMeta.signal) parts.push(`signal=${errWithMeta.signal}`);
490
- if (stderrText) parts.push(`stderr: ${stderrText.slice(0, 500)}`);
491
- reject(new Error(parts.join(" \u2014 ")));
492
- return;
493
- }
494
- resolve(Buffer.isBuffer(stdout) ? stdout : Buffer.from(stdout));
495
- }
496
- );
497
- child.on("error", (e) => reject(e));
498
- });
445
+ return new Promise((resolve, reject) => {
446
+ (0, node_child_process.execFile)("ffmpeg", [
447
+ "-loglevel",
448
+ "error",
449
+ "-rtsp_transport",
450
+ "tcp",
451
+ "-fflags",
452
+ "+discardcorrupt",
453
+ "-skip_frame",
454
+ "nokey",
455
+ "-i",
456
+ url,
457
+ "-vf",
458
+ "select=eq(pict_type\\,I)",
459
+ "-vsync",
460
+ "vfr",
461
+ "-frames:v",
462
+ "1",
463
+ "-q:v",
464
+ "3",
465
+ "-f",
466
+ "image2pipe",
467
+ "-vcodec",
468
+ "mjpeg",
469
+ "pipe:1"
470
+ ], {
471
+ encoding: "buffer",
472
+ maxBuffer: 16 * 1024 * 1024,
473
+ timeout: timeoutMs
474
+ }, (err, stdout, stderr) => {
475
+ if (err) {
476
+ const errWithMeta = err;
477
+ const stderrText = Buffer.isBuffer(stderr) ? stderr.toString("utf8").trim() : String(stderr ?? "").trim();
478
+ const parts = [err instanceof Error ? err.message : String(err)];
479
+ if (errWithMeta.killed) parts.push("killed=true");
480
+ if (errWithMeta.code !== void 0) parts.push(`code=${String(errWithMeta.code)}`);
481
+ if (errWithMeta.signal) parts.push(`signal=${errWithMeta.signal}`);
482
+ if (stderrText) parts.push(`stderr: ${stderrText.slice(0, 500)}`);
483
+ reject(new Error(parts.join(" ")));
484
+ return;
485
+ }
486
+ resolve(Buffer.isBuffer(stdout) ? stdout : Buffer.from(stdout));
487
+ }).on("error", (e) => reject(e));
488
+ });
499
489
  }
500
- // Annotate the CommonJS export names for ESM import in node:
501
- 0 && (module.exports = {
502
- SnapshotAddon
503
- });
490
+ //#endregion
491
+ exports.SnapshotAddon = SnapshotAddon;
492
+ exports.default = SnapshotAddon;
493
+
504
494
  //# sourceMappingURL=index.js.map