@camstack/core 0.1.14 → 0.1.16

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 (352) 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 +226 -0
  18. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js.map +1 -0
  19. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +218 -0
  20. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs.map +1 -0
  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 +7 -0
  24. package/dist/builtins/addon-pages-aggregator/index.mjs +2 -0
  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 +202 -0
  28. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js.map +1 -0
  29. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +194 -0
  30. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs.map +1 -0
  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 +7 -0
  34. package/dist/builtins/addon-widgets-aggregator/index.mjs +2 -0
  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 +603 -0
  38. package/dist/builtins/alerts/alerts.addon.js.map +1 -0
  39. package/dist/builtins/alerts/alerts.addon.mjs +597 -0
  40. package/dist/builtins/alerts/alerts.addon.mjs.map +1 -0
  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 -0
  44. package/dist/builtins/alerts/index.mjs +2 -0
  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 +106 -0
  80. package/dist/builtins/console-logging/index.js.map +1 -0
  81. package/dist/builtins/console-logging/index.mjs +97 -0
  82. package/dist/builtins/console-logging/index.mjs.map +1 -0
  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 +2153 -0
  88. package/dist/builtins/device-manager/device-manager.addon.js.map +1 -0
  89. package/dist/builtins/device-manager/device-manager.addon.mjs +2147 -0
  90. package/dist/builtins/device-manager/device-manager.addon.mjs.map +1 -0
  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 +7 -0
  94. package/dist/builtins/device-manager/index.mjs +2 -0
  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 +156 -0
  102. package/dist/builtins/hub-forwarder/index.js.map +1 -0
  103. package/dist/builtins/hub-forwarder/index.mjs +147 -0
  104. package/dist/builtins/hub-forwarder/index.mjs.map +1 -0
  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 -0
  110. package/dist/builtins/local-auth/index.mjs +2 -0
  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 +6895 -0
  114. package/dist/builtins/local-auth/local-auth.addon.js.map +1 -0
  115. package/dist/builtins/local-auth/local-auth.addon.mjs +6885 -0
  116. package/dist/builtins/local-auth/local-auth.addon.mjs.map +1 -0
  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 +102 -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 +404 -0
  124. package/dist/builtins/local-network/local-network.addon.js.map +1 -0
  125. package/dist/builtins/local-network/local-network.addon.mjs +392 -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 +924 -0
  144. package/dist/builtins/native-metrics/native-metrics.addon.js.map +1 -0
  145. package/dist/builtins/native-metrics/native-metrics.addon.mjs +916 -0
  146. package/dist/builtins/native-metrics/native-metrics.addon.mjs.map +1 -0
  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 +494 -0
  170. package/dist/builtins/snapshot/index.js.map +1 -0
  171. package/dist/builtins/snapshot/index.mjs +488 -0
  172. package/dist/builtins/snapshot/index.mjs.map +1 -0
  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 -2
  182. package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts.map +1 -0
  183. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +311 -205
  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 -4
  188. package/dist/builtins/sqlite-storage/index.d.ts.map +1 -0
  189. package/dist/builtins/sqlite-storage/index.js +258 -1097
  190. package/dist/builtins/sqlite-storage/index.js.map +1 -1
  191. package/dist/builtins/sqlite-storage/index.mjs +268 -28
  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 -2
  202. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts.map +1 -0
  203. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +588 -417
  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 +7 -0
  226. package/dist/builtins/system-config/index.mjs +2 -0
  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 +234 -0
  230. package/dist/builtins/system-config/system-config.addon.js.map +1 -0
  231. package/dist/builtins/system-config/system-config.addon.mjs +228 -0
  232. package/dist/builtins/system-config/system-config.addon.mjs.map +1 -0
  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 -30
  244. package/dist/builtins/winston-logging/index.d.ts.map +1 -0
  245. package/dist/builtins/winston-logging/index.js +153 -180
  246. package/dist/builtins/winston-logging/index.js.map +1 -1
  247. package/dist/builtins/winston-logging/index.mjs +144 -8
  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 -1137
  270. package/dist/index.d.ts.map +1 -0
  271. package/dist/index.js +7761 -7017
  272. package/dist/index.js.map +1 -1
  273. package/dist/index.mjs +7699 -3798
  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 +230 -13
  320. package/dist/builtins/local-backup/index.d.mts +0 -42
  321. package/dist/builtins/local-backup/index.d.ts +0 -42
  322. package/dist/builtins/local-backup/index.js +0 -188
  323. package/dist/builtins/local-backup/index.js.map +0 -1
  324. package/dist/builtins/local-backup/index.mjs +0 -10
  325. package/dist/builtins/local-backup/index.mjs.map +0 -1
  326. package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.mts +0 -2
  327. package/dist/builtins/sqlite-storage/index.d.mts +0 -4
  328. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.mts +0 -2
  329. package/dist/builtins/winston-logging/index.d.mts +0 -30
  330. package/dist/chunk-2F3XZYRW.mjs +0 -89
  331. package/dist/chunk-2F3XZYRW.mjs.map +0 -1
  332. package/dist/chunk-LQFPAEQF.mjs +0 -147
  333. package/dist/chunk-LQFPAEQF.mjs.map +0 -1
  334. package/dist/chunk-R3DIIBBX.mjs +0 -532
  335. package/dist/chunk-R3DIIBBX.mjs.map +0 -1
  336. package/dist/chunk-SMNR44VG.mjs +0 -386
  337. package/dist/chunk-SMNR44VG.mjs.map +0 -1
  338. package/dist/chunk-SO4LROOT.mjs +0 -150
  339. package/dist/chunk-SO4LROOT.mjs.map +0 -1
  340. package/dist/chunk-SPA4JBKN.mjs +0 -175
  341. package/dist/chunk-SPA4JBKN.mjs.map +0 -1
  342. package/dist/dist-3BY63UQ5.mjs +0 -2151
  343. package/dist/dist-3BY63UQ5.mjs.map +0 -1
  344. package/dist/filesystem-storage.addon-C42r589X.d.mts +0 -57
  345. package/dist/filesystem-storage.addon-C42r589X.d.ts +0 -57
  346. package/dist/index.d.mts +0 -1137
  347. package/dist/sql-schema-CKz78rId.d.mts +0 -97
  348. package/dist/sql-schema-CKz78rId.d.ts +0 -97
  349. package/dist/sqlite-settings.addon-KwG-uKMP.d.mts +0 -79
  350. package/dist/sqlite-settings.addon-KwG-uKMP.d.ts +0 -79
  351. package/dist/storage-location-manager-KKDQNAKA.mjs +0 -7
  352. package/dist/storage-location-manager-KKDQNAKA.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/builtins/snapshot/snapshot.addon.ts"],"sourcesContent":["import { execFile } from 'node:child_process'\nimport { DeviceFeature, DeviceType, snapshotCapability } from '@camstack/types'\nimport type { ConfigUISchemaWithValues, InferProvider, ProfileSlot, ProviderRegistration } from '@camstack/types'\nimport { BaseAddon, errMsg, streamQualityLabel } from '@camstack/types'\n\ntype ISnapshotProvider = InferProvider<typeof snapshotCapability>\ntype SnapshotImage = { base64: string; contentType: string }\n\n/**\n * Per-device snapshot settings stored via `ctx.settings.writeDeviceStore`.\n * Kept as a plain interface (not Zod) because the value set is tiny and\n * `snapshot` isn't worth the extra schema plumbing — runtime coercion\n * happens inline in `getDeviceStoreTyped` below.\n */\ninterface SnapshotDeviceSettings {\n /** Quality profile to prefer when grabbing a snapshot (e.g. `high`, `mid`). Empty = auto. */\n readonly snapshotStreamId?: string\n /** If true, log extra detail (timing, selected stream, error paths). */\n readonly snapshotDebug?: boolean\n /**\n * Maximum acceptable cache age in seconds. Below it the wrapper\n * serves the cached image; above it (or on `force`) it falls\n * through to the native (which on battery cams wakes the\n * firmware). When unset the per-device default applies:\n * `BATTERY_DEFAULT_MAX_AGE_S` for battery cams and\n * `NON_BATTERY_DEFAULT_MAX_AGE_S` for everything else.\n */\n readonly snapshotMaxAgeS?: number\n}\n\n/** Default cache window for non-battery cams (seconds). 10s feels live. */\nconst NON_BATTERY_DEFAULT_MAX_AGE_S = 10\n/** Default cache window for battery cams (seconds). 1h ≈ \"don't wake the cam unless asked\". */\nconst BATTERY_DEFAULT_MAX_AGE_S = 3600\n\ninterface CacheEntry {\n readonly data: SnapshotImage\n readonly ts: number\n /** Stream id resolved at capture time — 'high' | 'mid' | 'low' | custom | null. */\n readonly streamId: string | null\n}\n\ninterface SnapshotAddonConfig {\n /**\n * Last-resort cache age (ms): if every live capture path fails\n * (native + stream-broker fallback) AND a stale entry is older\n * than this, the wrapper still returns the stale image rather\n * than `null`. Keeps the UI from going blank during transient\n * camera unreachability. Per-device freshness is governed by\n * `snapshotMaxAgeS` instead.\n */\n readonly staleTtlMs: number\n}\n\n/**\n * SnapshotAddon — wrapper over the `snapshot` capability.\n *\n * Activated per-device (toggleable by user; default active). When active,\n * caches fresh snapshots in memory. On cache miss, delegates to the native\n * provider for this device via `ctx.getNativeProvider(snapshotCapability, id)`.\n *\n * No silent fallback — if the native fails, propagate the error up. Stale\n * cache is returned ONLY when the native throws AND a stale entry exists,\n * and the failure is logged so the fallback is never silent.\n *\n * Frame-grab fallback: when the native provider is absent (or returns null /\n * throws), we ask the `stream-broker` capability for the device's RTSP\n * restream URL and pipe one JPEG out of ffmpeg. stream-broker intentionally\n * does NOT expose a `grabFrame` method — the orchestration (native-first,\n * ffmpeg fallback, caching) is this addon's concern; stream-broker only\n * publishes stream endpoints.\n */\nexport class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {\n private readonly cache = new Map<number, CacheEntry>()\n\n constructor() {\n super({\n staleTtlMs: 60_000,\n })\n }\n\n protected async onInitialize(): Promise<ProviderRegistration[]> {\n this.ctx.logger.info('Snapshot wrapper initialized')\n const provider: ISnapshotProvider = {\n getSnapshot: (input) => this.getSnapshot(input),\n invalidateCache: (input) => this.invalidateCache(input),\n // DeviceSettingsContribution surface — numeric deviceId end-to-end.\n getDeviceSettingsContribution: (input) => this.buildDeviceSettingsContribution(input.deviceId),\n getDeviceLiveContribution: async () => null,\n applyDeviceSettingsPatch: (input) => this.saveDeviceSettingsPatch(input.deviceId, input.patch),\n // Status surface — derives a diagnostic snapshot from the cache\n // bookkeeping (lastCapturedAt, cacheAgeMs, lastBytes, lastStreamId).\n // Returns null when the device has never been captured.\n getStatus: async (input) => this.getStatus(input.deviceId),\n }\n return [{\n capability: snapshotCapability,\n provider,\n kind: 'wrapper',\n defaultActive: true,\n }]\n }\n\n protected async onShutdown(): Promise<void> {\n this.cache.clear()\n }\n\n protected globalSettingsSchema() {\n return this.schema({\n sections: [{\n id: 'snapshot-cache',\n title: 'Snapshot Cache',\n description: 'Stale fallback when live capture fails. Per-device freshness is configured under Device → Snapshot → Max cache age.',\n columns: 1,\n fields: [\n this.field({\n type: 'number', key: 'staleTtlMs', label: 'Stale fallback TTL (ms)',\n description: 'If live capture fails, cached snapshot younger than this is still returned.',\n min: 0, max: 3_600_000, step: 1_000, default: 60_000,\n }),\n ],\n }],\n })\n }\n\n // ── Capability methods ────────────────────────────────────────────────\n\n private async getSnapshot(input: { deviceId: number; streamId?: string; force?: boolean }): Promise<SnapshotImage | null> {\n const { deviceId, force } = input\n // Pull device name + battery feature with a single device-scoped\n // query. `getDevice` is cheaper than `listAll().find(...)` (one row\n // returned, no client-side filter) and surfaces the same fields.\n const meta = await this.lookupDeviceMeta(deviceId)\n const deviceName = meta?.name\n const isBatteryDevice = meta?.isBattery ?? false\n const log = this.ctx.logger.withTags({ deviceId, ...(deviceName ? { deviceName } : {}) })\n const now = Date.now()\n const hit = this.cache.get(deviceId)\n\n // Honour the per-device stored preference unless the caller specified\n // an explicit streamId. `snapshotDebug` just flips log verbosity —\n // read once per call so the flag can be toggled without restart.\n const prefs: SnapshotDeviceSettings = await this.readDeviceSettings(deviceId).catch(() => ({}))\n const rawPref = prefs.snapshotStreamId\n const effectiveStreamId = input.streamId ?? (rawPref && rawPref !== 'auto' ? rawPref : undefined)\n if (prefs.snapshotDebug) {\n log.info('debug on', { tags: { deviceId }, meta: { stream: effectiveStreamId ?? 'auto' } })\n }\n\n // 1. Effective max-age check. A single per-device knob replaces\n // the legacy fresh/battery/sleeping cascade — defaults are 10s\n // for non-battery cams (matches the live-feel UI poll cadence)\n // and 1h for battery cams (avoids gratuitous wake-ups). The\n // operator can override via the per-device `snapshotMaxAgeS`\n // setting; a `force=true` call (UI refresh button) bypasses\n // the gate entirely. Behaviour matrix:\n //\n // hit + ageMs < maxAgeMs + !force → serve cache\n // hit + sleeping + ageMs < maxAgeMs + !force → serve cache (no wake)\n // hit + sleeping + ageMs >= maxAgeMs + !force → cache is stale,\n // let the native\n // decide whether\n // to wake (the\n // native cap layer\n // handles the\n // \"are we awake?\"\n // question)\n // no hit → fall through (will wake)\n // force === true → fall through (will wake)\n const defaultMaxAgeS = isBatteryDevice ? BATTERY_DEFAULT_MAX_AGE_S : NON_BATTERY_DEFAULT_MAX_AGE_S\n const effectiveMaxAgeMs = (typeof prefs.snapshotMaxAgeS === 'number' && prefs.snapshotMaxAgeS >= 0\n ? prefs.snapshotMaxAgeS\n : defaultMaxAgeS) * 1_000\n if (!force && hit && now - hit.ts < effectiveMaxAgeMs) {\n if (prefs.snapshotDebug) {\n log.debug('snapshot: cache hit', {\n tags: { deviceId },\n meta: { ageMs: now - hit.ts, maxAgeMs: effectiveMaxAgeMs, isBattery: isBatteryDevice },\n })\n }\n return hit.data\n }\n\n // 2. Native provider (per-device, registered by the device-class addon).\n // Missing native is expected for cameras without a vendor snapshot\n // endpoint (e.g. a plain RTSP camera with no `snapshotUrl` configured).\n // We catch and fall through to the stream-broker ffmpeg path.\n let nativeError: unknown = null\n let nativeAbsent = false\n try {\n const native = this.ctx.getNativeProvider(snapshotCapability, deviceId)\n if (native) {\n const result = await native.getSnapshot(input)\n if (result) {\n this.cache.set(deviceId, { data: result, ts: now, streamId: effectiveStreamId ?? null })\n return result\n }\n } else {\n nativeAbsent = true\n }\n } catch (err) {\n const msg = errMsg(err)\n if (isAbsentNativeError(msg)) {\n nativeAbsent = true\n log.debug('native snapshot absent', { tags: { deviceId }, meta: { error: msg } })\n } else {\n nativeError = err\n log.warn('native snapshot failed', { tags: { deviceId }, meta: { error: msg } })\n }\n }\n\n // 3. Frame-grab fallback via stream-broker's RTSP restream. Passes\n // the effective streamId (explicit caller or stored preference) so\n // the fallback hits the same stream the user asked for instead of\n // always grabbing `main`.\n //\n // Battery-cam guard: skip the broker fallback only when the native\n // was ABSENT for a battery device — that's the case where invoking\n // the broker would be the first wake-up signal. If the native was\n // present (whether it succeeded with null, threw, or returned a\n // value), the camera is already being talked to (and likely awake);\n // the additional broker dial costs nothing extra. When a streaming\n // broker is already active, the fallback is unconditionally free\n // (someone is watching), so allow it regardless.\n const skipBrokerForBattery = isBatteryDevice\n && nativeAbsent\n && !(await this.hasStreamingBrokerForDevice(deviceId))\n if (!skipBrokerForBattery) {\n try {\n const fallback = await this.grabFrameFromBroker(deviceId, effectiveStreamId)\n if (fallback) {\n this.cache.set(deviceId, { data: fallback, ts: now, streamId: effectiveStreamId ?? null })\n return fallback\n }\n } catch (err) {\n log.warn('stream-broker snapshot fallback failed', { tags: { deviceId }, meta: { error: errMsg(err) } })\n }\n } else {\n log.debug('snapshot: skipping broker fallback — battery device with absent native and no streaming broker', {\n tags: { deviceId },\n })\n }\n\n // 4. Stale cache — last-resort \"don't go blank\" path.\n //\n // If ALL live paths failed and we have any cached entry, return\n // it and log the age. The UI keeps showing the last known frame\n // rather than a broken-image icon. The freshness gate at step 1\n // (per-device `snapshotMaxAgeS`) is the cap that decides whether\n // the cache is \"fresh enough\" in normal flow; this branch only\n // runs when every live source refused.\n if (hit) {\n const ageMs = now - hit.ts\n if (ageMs > this.config.staleTtlMs) {\n log.warn('snapshot: all live paths failed — serving stale cache', { tags: { deviceId }, meta: { ageMs } })\n }\n return hit.data\n }\n\n // Nothing produced a frame and nothing in cache. If the native provider\n // threw a real error (not just \"no provider registered for this\n // device\"), surface it so callers see the cause. If the native was\n // simply absent (camera has no snapshotUrl + no wrapper active),\n // return null so the UI renders \"no image yet\" instead of a 500.\n if (nativeError) throw nativeError\n if (nativeAbsent) return null\n return null\n }\n\n /**\n * Tell apart \"native provider isn't registered for this device\" from\n * \"native provider ran and threw a real error\". The former is the steady\n * state for cameras without a vendor snapshot endpoint and should not\n * propagate as a 500; the latter should.\n */\n\n /**\n * Pull one JPEG from the device's stream-broker RTSP restream using\n * a short-lived ffmpeg invocation.\n *\n * Stream selection strategy (picks the broker that won't stall):\n * 1. Explicit `preferredStreamId` (user set in per-device settings)\n * — always honoured, even if currently idle. Operator choice\n * wins.\n * 2. Auto: highest-quality broker currently in `streaming` state.\n * This is the whole point — prefer the stream that has active\n * subscribers (usually `low` for detection, but `mid`/`high`\n * if WebRTC is watching) so ffmpeg hits a warm pipe and\n * doesn't race the broker's resume.\n * 3. Fallback: highest-quality enabled entry regardless of status\n * (will wake a suspended broker — retry-guarded against the\n * cold-start error).\n *\n * The stream-broker auto-suspends idle streams on the \"no demand\"\n * signal; snapshots used to default to `high` which was often the\n * first to go idle, racing every snapshot with a broker resume.\n * Now we ask the orchestrator of streams which one is warm and grab\n * from there.\n */\n private async grabFrameFromBroker(\n deviceId: number,\n preferredStreamId?: string,\n ): Promise<SnapshotImage | null> {\n const dev = await this.ctx.fetchDevice(deviceId)\n const prefix = `${deviceId}/`\n\n // Device-scoped fetch: broker filters by deviceId server-side, no\n // cluster-wide list + client-side filter needed. Profile slot\n // statuses come from the same per-device facade for the warmth\n // ranking below.\n const [deviceEntries, profileSlots] = await Promise.all([\n dev.cameraStreams?.getRtspEntries({}) ?? [],\n dev.cameraStreams?.getBrokerStreams({}) ?? [],\n ])\n const usable = deviceEntries.filter(e => e.enabled && !!e.url)\n if (usable.length === 0) return null\n\n // 1. Explicit preference — try it first without status gating.\n if (preferredStreamId && preferredStreamId !== 'auto') {\n const explicit = usable.find(e => e.brokerId === `${prefix}${preferredStreamId}`)\n if (explicit) {\n const grabbed = await this.runGrabWithResumeRetry(explicit.url, deviceId)\n if (grabbed) return grabbed\n // Explicit pick failed even after retry — fall through to auto\n // rather than give up. Keeps the snapshot useful when the\n // operator's preferred stream is momentarily unreachable.\n this.ctx.logger.debug('grabFrame: explicit stream failed — falling back to auto', { meta: { preferredStreamId } })\n }\n }\n\n // Rank entries by quality (high → mid → low → other).\n const ranked = [...usable].sort(\n (a, b) => qualityRank(b.brokerId, prefix) - qualityRank(a.brokerId, prefix),\n )\n\n // Per-device slot status lookup keyed by brokerId, sourced from\n // the same `cameraStreams` facade — `status: 'streaming'` means the\n // broker is warm and an ffmpeg grab is free of dial overhead.\n const statusByBrokerId = new Map<string, ProfileSlot['status']>()\n for (const slot of profileSlots) statusByBrokerId.set(slot.brokerId, slot.status)\n const statuses = ranked.map(e => ({ entry: e, status: statusByBrokerId.get(e.brokerId) ?? 'idle' as const }))\n\n // 2. Highest-quality broker currently `streaming`.\n const warm = statuses.find(s => s.status === 'streaming')\n if (warm) {\n const grabbed = await this.runGrabWithResumeRetry(warm.entry.url, deviceId)\n if (grabbed) return grabbed\n }\n\n // 3. Final fallback: wake whichever broker has the highest quality.\n // The retry handles the resume race window.\n for (const { entry } of statuses) {\n const grabbed = await this.runGrabWithResumeRetry(entry.url, deviceId).catch(() => null)\n if (grabbed) return grabbed\n }\n return null\n }\n\n /**\n * Ffmpeg grab with one retry on the broker-cold-start error\n * signature. Covers the window between \"client connected\" and\n * \"first keyframe\" when a suspended broker resumes.\n */\n private async runGrabWithResumeRetry(url: string, deviceId: number): Promise<SnapshotImage | null> {\n let buf: Buffer\n try {\n buf = await runFfmpegFrameGrab(url, 15000)\n } catch (err) {\n const msg = errMsg(err)\n if (isBrokerColdError(msg)) {\n this.ctx.logger.debug('grabFrame: broker-resume race — retrying in 1500ms', { tags: { deviceId } })\n await new Promise((r) => setTimeout(r, 1500))\n buf = await runFfmpegFrameGrab(url, 15000)\n } else {\n throw err\n }\n }\n if (buf.length === 0) return null\n return { base64: buf.toString('base64'), contentType: 'image/jpeg' }\n }\n\n private async invalidateCache(input: { deviceId: number }): Promise<void> {\n this.cache.delete(input.deviceId)\n }\n\n /**\n * Non-throwing probe of the device's battery cap. Returns true only\n * when a battery native is registered AND its current status says\n * `sleeping: true`. Any error (no provider, native absent, getStatus\n * missing, RPC timeout) is swallowed and treated as \"awake\" — we'd\n * rather pay a wake-up than strand the caller on a cache that's\n * semantically stale. Debug-logged for observability.\n */\n /**\n * True when at least one of the device's brokers is actively\n * streaming (status === 'streaming'). Used by the battery-cam guard\n * around `grabFrameFromBroker` to allow the fallback ONLY when\n * grabbing a frame is free (a consumer is already keeping the\n * stream warm). When everything is suspended, the fallback would\n * dial the camera and wake it — defeats the sleeping cache.\n */\n private async hasStreamingBrokerForDevice(deviceId: number): Promise<boolean> {\n // `cameraStreams` is the device-scoped facade over the system\n // `stream-broker` cap — `getBrokerStreams` returns this device's\n // profile slots only (no cluster-wide scan + filter).\n try {\n const dev = await this.ctx.fetchDevice(deviceId)\n const slots = await dev.cameraStreams?.getBrokerStreams({}) ?? []\n return slots.some(s => s.status === 'streaming')\n } catch {\n return false\n }\n }\n\n /**\n * Diagnostic status for the `status` auto-injected cap method. Reports\n * the cache bookkeeping for this device — when the last snapshot was\n * captured, how stale the cached image is, its size, and which stream\n * was used. Returns null when the device has never been captured\n * (cache miss) since the addon started.\n */\n private async getStatus(deviceId: number): Promise<{\n lastCapturedAt: number | null\n cacheAgeMs: number | null\n lastBytes: number | null\n lastStreamId: string | null\n } | null> {\n const hit = this.cache.get(deviceId)\n if (!hit) return null\n return {\n lastCapturedAt: hit.ts,\n cacheAgeMs: Date.now() - hit.ts,\n lastBytes: hit.data.base64.length, // approx bytes = base64 length * 3/4, but length is stable enough\n lastStreamId: hit.streamId,\n }\n }\n\n // ── DeviceSettingsContribution ────────────────────────────────────────\n //\n // Snapshot carries two per-device knobs:\n // - `snapshotStreamId` — which stream to prefer when grabbing frames\n // (empty = auto / default \"main\")\n // - `snapshotDebug` — extra logging for troubleshooting snapshot paths\n //\n // Storage uses the addon's own per-device store (`ctx.settings\n // .writeDeviceStore`), not the device's config. The schema isn't\n // captured in a Zod object: the keys are optional and the UI layer\n // validates shapes.\n\n private async readDeviceSettings(deviceId: number): Promise<SnapshotDeviceSettings> {\n if (!this.ctx.settings) return {}\n const raw = await this.ctx.settings.readDeviceStore(deviceId)\n const rawAge = raw['snapshotMaxAgeS']\n const maxAgeS = typeof rawAge === 'number' && rawAge >= 0 && Number.isFinite(rawAge)\n ? rawAge\n : undefined\n return {\n snapshotStreamId: typeof raw['snapshotStreamId'] === 'string' ? raw['snapshotStreamId'] : undefined,\n snapshotDebug: raw['snapshotDebug'] === true,\n ...(maxAgeS !== undefined ? { snapshotMaxAgeS: maxAgeS } : {}),\n }\n }\n\n private async buildDeviceSettingsContribution(deviceId: number): Promise<ConfigUISchemaWithValues | null> {\n // Camera-only — snapshot settings are meaningless on Lights /\n // Switches / Sensors / Buttons, and surfacing the section there\n // produces ghost top-tabs (the device-detail UI builds the tab\n // list off the contribution sections). Source-side gate keeps the\n // policy with the addon that owns the cap; the admin-ui no longer\n // needs the symmetric `device-section-policy` allow-list.\n const meta = await this.lookupDeviceMeta(deviceId)\n if (meta && meta.type !== DeviceType.Camera) return null\n const current = await this.readDeviceSettings(deviceId)\n const streamOptions = await this.getStreamOptions(deviceId)\n const isBattery = await this.isDeviceBattery(deviceId)\n const defaultMaxAgeS = isBattery ? BATTERY_DEFAULT_MAX_AGE_S : NON_BATTERY_DEFAULT_MAX_AGE_S\n return {\n sections: [{\n id: 'snapshot-preferences',\n title: 'Snapshot',\n tab: 'snapshot',\n order: 60,\n fields: [\n {\n type: 'select' as const,\n key: 'snapshotStreamId',\n label: 'Preferred stream',\n description: 'Stream used when grabbing a snapshot',\n options: streamOptions,\n required: true,\n value: current.snapshotStreamId || 'auto',\n },\n {\n type: 'number' as const,\n key: 'snapshotMaxAgeS',\n label: 'Max cache age (s)',\n description:\n `Serve cached snapshot up to this age before re-capturing. Default ${defaultMaxAgeS}s for ` +\n `${isBattery ? 'battery cams (avoids gratuitous wake-ups)' : 'non-battery cams (live-feel)'}. ` +\n 'The UI refresh button always forces a fresh capture regardless of this value.',\n min: 0,\n max: 24 * 3600,\n step: 1,\n value: current.snapshotMaxAgeS ?? defaultMaxAgeS,\n },\n {\n type: 'boolean' as const,\n key: 'snapshotDebug',\n label: 'Debug logging',\n description: 'Log stream selection and timing details for this device.',\n value: current.snapshotDebug ?? false,\n },\n ],\n }],\n }\n }\n\n /**\n * Single-trip device lookup against device-manager. Returns the\n * fields the wrapper actually consults — name (logging) + battery\n * flag (cache window + broker-fallback gate). Sourced from the\n * device-manager registry rather than the battery cap so the answer\n * survives a momentarily-unreachable provider (the very condition\n * we're trying to be resilient to).\n *\n * Logged at debug + null return on failure: every call site already\n * has a sensible fallback path (cache hit, conservative default, …),\n * so we don't want a transient device-manager hiccup to throw.\n */\n private async lookupDeviceMeta(\n deviceId: number,\n ): Promise<{ name?: string; isBattery: boolean; type?: DeviceType } | null> {\n const api = this.ctx.api\n if (!api) return null\n try {\n const found = await api.deviceManager.getDevice.query({ deviceId })\n if (!found) return null\n const features = (found.features as readonly string[] | undefined) ?? []\n const rawType = (found as { type?: string }).type\n return {\n ...(found.name ? { name: found.name } : {}),\n isBattery: features.includes(DeviceFeature.BatteryOperated),\n ...(rawType ? { type: rawType as DeviceType } : {}),\n }\n } catch (err) {\n this.ctx.logger.debug('deviceManager.getDevice failed during snapshot', {\n tags: { deviceId },\n meta: { error: err instanceof Error ? err.message : String(err) },\n })\n return null\n }\n }\n\n /** Settings-UI helper — battery flag drives the default max-age in the field description. */\n private async isDeviceBattery(deviceId: number): Promise<boolean> {\n return (await this.lookupDeviceMeta(deviceId))?.isBattery ?? false\n }\n\n private async getStreamOptions(deviceId: number): Promise<Array<{ value: string; label: string }>> {\n const prefix = `${deviceId}/`\n try {\n const dev = await this.ctx.fetchDevice(deviceId)\n const entries = await dev.cameraStreams?.getRtspEntries({}) ?? []\n const streamIds = entries\n .filter(e => e.enabled)\n .map(e => e.brokerId.slice(prefix.length))\n return [\n { value: 'auto', label: 'Auto' },\n ...streamIds.map(id => ({ value: id, label: streamQualityLabel(id) })),\n ]\n } catch (err) {\n this.ctx.logger.error('getStreamOptions failed', { tags: { deviceId }, meta: { error: errMsg(err) } })\n return [{ value: 'auto', label: 'Auto' }]\n }\n }\n\n private async saveDeviceSettingsPatch(\n deviceId: number,\n patch: Record<string, unknown>,\n ): Promise<{ success: true }> {\n if (!this.ctx.settings) {\n throw new Error('[snapshot] settings store unavailable — cannot persist per-device settings')\n }\n const current = await this.ctx.settings.readDeviceStore(deviceId)\n const next: Record<string, unknown> = { ...current }\n if ('snapshotStreamId' in patch) {\n const v = patch['snapshotStreamId']\n next['snapshotStreamId'] = typeof v === 'string' && v.trim().length > 0 ? v.trim() : ''\n }\n if ('snapshotDebug' in patch) {\n next['snapshotDebug'] = patch['snapshotDebug'] === true\n }\n if ('snapshotMaxAgeS' in patch) {\n const v = patch['snapshotMaxAgeS']\n // Persist a finite non-negative number; anything else (null,\n // undefined, NaN, negative) falls back to the per-device\n // default at read time.\n if (typeof v === 'number' && Number.isFinite(v) && v >= 0) {\n next['snapshotMaxAgeS'] = v\n } else {\n delete next['snapshotMaxAgeS']\n }\n }\n await this.ctx.settings.writeDeviceStore(deviceId, next)\n // Drop the cache so the next `getSnapshot` applies the new stream/debug flags.\n this.cache.delete(deviceId)\n return { success: true as const }\n }\n}\n\nfunction isAbsentNativeError(msg: string): boolean {\n return msg.includes('no provider for') || msg.includes('no native provider for capability')\n}\n\n/**\n * Quality ordering for broker picker: `high` > `mid` > `low` > other.\n * The streamId is the suffix after `${deviceId}/` in the brokerId.\n * Unknown labels fall through to 0 so they land at the bottom of the\n * preference list without crashing.\n */\nfunction qualityRank(brokerId: string, prefix: string): number {\n const streamId = brokerId.startsWith(prefix) ? brokerId.slice(prefix.length) : brokerId\n const normalized = streamId.toLowerCase()\n if (normalized.includes('high') || normalized === 'main' || normalized === 'hd') return 3\n if (normalized.includes('mid') || normalized === 'medium') return 2\n if (normalized.includes('low') || normalized === 'sub' || normalized === 'sd') return 1\n return 0\n}\n\n/**\n * Detect ffmpeg failure signatures that indicate the broker wasn't\n * streaming yet when we tried to read its RTSP restream — a race\n * window that closes as soon as the broker lands its first keyframe.\n * Used by `grabFrameFromBroker` to retry once instead of giving up.\n */\nfunction isBrokerColdError(msg: string): boolean {\n return msg.includes('Invalid data found when processing input')\n || msg.includes('Error opening input')\n || msg.includes('Connection refused')\n || msg.includes('No route to host')\n}\n\nfunction runFfmpegFrameGrab(url: string, timeoutMs: number): Promise<Buffer> {\n return new Promise<Buffer>((resolve, reject) => {\n // ── IDR-first snapshot ────────────────────────────────────────────────\n //\n // `-skip_frame nokey` decodes only keyframes — the first frame handed\n // to the MJPEG encoder is guaranteed to be a complete IDR with all\n // references present, so the JPEG can't come out as a half-decoded\n // delta (the \"green stripe\" a non-keyframe decode produces).\n //\n // `-fflags +discardcorrupt` drops corrupt packets that slipped in\n // before sync — otherwise they propagate as green/gray smears into\n // the decoded output.\n //\n // No `-analyzeduration` / `-probesize` override: the old values\n // (5_000_000 µs = 5 s) forced ffmpeg to buffer 5 s of RTP before\n // decoding even when a keyframe was already in hand, which stacked\n // with a cold stream-broker's upstream handshake and pushed the\n // snapshot past the caller's ffmpeg timeout. Defaults are fine —\n // `-skip_frame nokey` + `-frames:v 1` already bound the work to a\n // single keyframe.\n const child = execFile(\n 'ffmpeg',\n [\n '-loglevel', 'error',\n '-rtsp_transport', 'tcp',\n '-fflags', '+discardcorrupt',\n '-skip_frame', 'nokey',\n '-i', url,\n '-vf', 'select=eq(pict_type\\\\,I)',\n '-vsync', 'vfr',\n '-frames:v', '1',\n '-q:v', '3',\n '-f', 'image2pipe',\n '-vcodec', 'mjpeg',\n 'pipe:1',\n ],\n { encoding: 'buffer', maxBuffer: 16 * 1024 * 1024, timeout: timeoutMs },\n (err, stdout, stderr) => {\n if (err) {\n // `execFile`'s default Error carries \"Command failed: …\" plus a\n // `code`/`signal` that Node fills in. ffmpeg with `-loglevel\n // error` is silent on RTSP-level failures; when the parent\n // kills the child on timeout, `killed === true` and stderr is\n // empty. Surface both sides so the log tells the real story.\n const errWithMeta = err as (Error & { code?: string | number; signal?: string | null; killed?: boolean })\n const stderrText = Buffer.isBuffer(stderr) ? stderr.toString('utf8').trim() : String(stderr ?? '').trim()\n const parts: string[] = [err instanceof Error ? err.message : String(err)]\n if (errWithMeta.killed) parts.push('killed=true')\n if (errWithMeta.code !== undefined) parts.push(`code=${String(errWithMeta.code)}`)\n if (errWithMeta.signal) parts.push(`signal=${errWithMeta.signal}`)\n if (stderrText) parts.push(`stderr: ${stderrText.slice(0, 500)}`)\n reject(new Error(parts.join(' — ')))\n return\n }\n resolve(Buffer.isBuffer(stdout) ? stdout : Buffer.from(stdout))\n },\n )\n child.on('error', (e: Error) => reject(e))\n })\n}\n"],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ import { ProviderRegistration, BaseAddon } from '@camstack/types';
2
+ interface SnapshotAddonConfig {
3
+ /**
4
+ * Last-resort cache age (ms): if every live capture path fails
5
+ * (native + stream-broker fallback) AND a stale entry is older
6
+ * than this, the wrapper still returns the stale image rather
7
+ * than `null`. Keeps the UI from going blank during transient
8
+ * camera unreachability. Per-device freshness is governed by
9
+ * `snapshotMaxAgeS` instead.
10
+ */
11
+ readonly staleTtlMs: number;
12
+ }
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
+ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
32
+ private readonly cache;
33
+ constructor();
34
+ protected onInitialize(): Promise<ProviderRegistration[]>;
35
+ protected onShutdown(): Promise<void>;
36
+ protected globalSettingsSchema(): import('@camstack/types').ConfigUISchema;
37
+ private getSnapshot;
38
+ /**
39
+ * Tell apart "native provider isn't registered for this device" from
40
+ * "native provider ran and threw a real error". The former is the steady
41
+ * state for cameras without a vendor snapshot endpoint and should not
42
+ * propagate as a 500; the latter should.
43
+ */
44
+ /**
45
+ * Pull one JPEG from the device's stream-broker RTSP restream using
46
+ * a short-lived ffmpeg invocation.
47
+ *
48
+ * Stream selection strategy (picks the broker that won't stall):
49
+ * 1. Explicit `preferredStreamId` (user set in per-device settings)
50
+ * — always honoured, even if currently idle. Operator choice
51
+ * wins.
52
+ * 2. Auto: highest-quality broker currently in `streaming` state.
53
+ * This is the whole point — prefer the stream that has active
54
+ * subscribers (usually `low` for detection, but `mid`/`high`
55
+ * if WebRTC is watching) so ffmpeg hits a warm pipe and
56
+ * doesn't race the broker's resume.
57
+ * 3. Fallback: highest-quality enabled entry regardless of status
58
+ * (will wake a suspended broker — retry-guarded against the
59
+ * cold-start error).
60
+ *
61
+ * The stream-broker auto-suspends idle streams on the "no demand"
62
+ * signal; snapshots used to default to `high` which was often the
63
+ * first to go idle, racing every snapshot with a broker resume.
64
+ * Now we ask the orchestrator of streams which one is warm and grab
65
+ * from there.
66
+ */
67
+ private grabFrameFromBroker;
68
+ /**
69
+ * Ffmpeg grab with one retry on the broker-cold-start error
70
+ * signature. Covers the window between "client connected" and
71
+ * "first keyframe" when a suspended broker resumes.
72
+ */
73
+ private runGrabWithResumeRetry;
74
+ private invalidateCache;
75
+ /**
76
+ * Non-throwing probe of the device's battery cap. Returns true only
77
+ * when a battery native is registered AND its current status says
78
+ * `sleeping: true`. Any error (no provider, native absent, getStatus
79
+ * missing, RPC timeout) is swallowed and treated as "awake" — we'd
80
+ * rather pay a wake-up than strand the caller on a cache that's
81
+ * semantically stale. Debug-logged for observability.
82
+ */
83
+ /**
84
+ * True when at least one of the device's brokers is actively
85
+ * streaming (status === 'streaming'). Used by the battery-cam guard
86
+ * around `grabFrameFromBroker` to allow the fallback ONLY when
87
+ * grabbing a frame is free (a consumer is already keeping the
88
+ * stream warm). When everything is suspended, the fallback would
89
+ * dial the camera and wake it — defeats the sleeping cache.
90
+ */
91
+ private hasStreamingBrokerForDevice;
92
+ /**
93
+ * Diagnostic status for the `status` auto-injected cap method. Reports
94
+ * the cache bookkeeping for this device — when the last snapshot was
95
+ * captured, how stale the cached image is, its size, and which stream
96
+ * was used. Returns null when the device has never been captured
97
+ * (cache miss) since the addon started.
98
+ */
99
+ private getStatus;
100
+ private readDeviceSettings;
101
+ private buildDeviceSettingsContribution;
102
+ /**
103
+ * Single-trip device lookup against device-manager. Returns the
104
+ * fields the wrapper actually consults — name (logging) + battery
105
+ * flag (cache window + broker-fallback gate). Sourced from the
106
+ * device-manager registry rather than the battery cap so the answer
107
+ * survives a momentarily-unreachable provider (the very condition
108
+ * we're trying to be resilient to).
109
+ *
110
+ * Logged at debug + null return on failure: every call site already
111
+ * has a sensible fallback path (cache hit, conservative default, …),
112
+ * so we don't want a transient device-manager hiccup to throw.
113
+ */
114
+ private lookupDeviceMeta;
115
+ /** Settings-UI helper — battery flag drives the default max-age in the field description. */
116
+ private isDeviceBattery;
117
+ private getStreamOptions;
118
+ private saveDeviceSettingsPatch;
119
+ }
120
+ export {};
121
+ //# sourceMappingURL=snapshot.addon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.addon.d.ts","sourceRoot":"","sources":["../../../src/builtins/snapshot/snapshot.addon.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAwD,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACjH,OAAO,EAAE,SAAS,EAA8B,MAAM,iBAAiB,CAAA;AAuCvE,UAAU,mBAAmB;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,aAAc,SAAQ,SAAS,CAAC,mBAAmB,CAAC;IAC/D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;;cAQtC,YAAY,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;cAsB/C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3C,SAAS,CAAC,oBAAoB;YAoBhB,WAAW;IA8IzB;;;;;OAKG;IAEH;;;;;;;;;;;;;;;;;;;;;;OAsBG;YACW,mBAAmB;IA2DjC;;;;OAIG;YACW,sBAAsB;YAkBtB,eAAe;IAI7B;;;;;;;OAOG;IACH;;;;;;;OAOG;YACW,2BAA2B;IAazC;;;;;;OAMG;YACW,SAAS;YA4BT,kBAAkB;YAclB,+BAA+B;IAsD7C;;;;;;;;;;;OAWG;YACW,gBAAgB;IAwB9B,6FAA6F;YAC/E,eAAe;YAIf,gBAAgB;YAkBhB,uBAAuB;CAgCtC"}
@@ -0,0 +1,9 @@
1
+ import { default as Database } from 'better-sqlite3';
2
+ export declare class ConfigStore {
3
+ private readonly db;
4
+ constructor(db: Database.Database);
5
+ save(addonId: string, stableId: string | null, data: Record<string, unknown>): void;
6
+ load(addonId: string, stableId: string | null): Record<string, unknown>;
7
+ remove(addonId: string, stableId: string | null): void;
8
+ }
9
+ //# sourceMappingURL=config-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../../src/builtins/sqlite-storage/config-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE1C,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAElD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAwBnF,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYvE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAOvD"}
@@ -0,0 +1,24 @@
1
+ import { default as Database } from 'better-sqlite3';
2
+ export interface DeviceRow {
3
+ readonly stableId: string;
4
+ readonly type: string;
5
+ readonly name: string;
6
+ readonly parentStableId: string | null;
7
+ readonly enabled: boolean;
8
+ }
9
+ interface InsertInput {
10
+ readonly stableId: string;
11
+ readonly type: string;
12
+ readonly name: string;
13
+ readonly parentStableId: string | null;
14
+ }
15
+ export declare class DeviceStore {
16
+ private readonly db;
17
+ constructor(db: Database.Database);
18
+ insert(addonId: string, device: InsertInput): void;
19
+ listByAddon(addonId: string): readonly DeviceRow[];
20
+ listChildren(addonId: string, parentStableId: string): readonly DeviceRow[];
21
+ remove(addonId: string, stableId: string): void;
22
+ }
23
+ export {};
24
+ //# sourceMappingURL=device-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-store.d.ts","sourceRoot":"","sources":["../../../src/builtins/sqlite-storage/device-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE1C,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;CACvC;AAED,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAElD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAQlD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,SAAS,EAAE;IAQlD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,SAAS,EAAE;IAQ3E,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAGhD"}
@@ -0,0 +1,87 @@
1
+ import { IStorageProviderImpl, StorageLocation, StorageLocationType } from '@camstack/types';
2
+ export declare class FilesystemStorageProvider implements IStorageProviderImpl {
3
+ static readonly providerId = "filesystem-storage";
4
+ static readonly displayName = "Filesystem";
5
+ private readonly uploads;
6
+ private readonly downloads;
7
+ getProviderInfo(): Promise<{
8
+ readonly providerId: string;
9
+ readonly displayName: string;
10
+ readonly supportedLocationTypes: readonly StorageLocationType[];
11
+ readonly configSchema: unknown;
12
+ }>;
13
+ testLocation({ config }: {
14
+ readonly config: Record<string, unknown>;
15
+ }): Promise<{
16
+ readonly ok: boolean;
17
+ readonly error?: string;
18
+ }>;
19
+ resolve({ location, relativePath, }: {
20
+ readonly location: StorageLocation;
21
+ readonly relativePath: string;
22
+ }): Promise<string>;
23
+ write({ location, relativePath, data, }: {
24
+ readonly location: StorageLocation;
25
+ readonly relativePath: string;
26
+ readonly data: Uint8Array;
27
+ }): Promise<void>;
28
+ read({ location, relativePath, }: {
29
+ readonly location: StorageLocation;
30
+ readonly relativePath: string;
31
+ }): Promise<Uint8Array<ArrayBuffer>>;
32
+ exists({ location, relativePath, }: {
33
+ readonly location: StorageLocation;
34
+ readonly relativePath: string;
35
+ }): Promise<boolean>;
36
+ list({ location, prefix, }: {
37
+ readonly location: StorageLocation;
38
+ readonly prefix?: string;
39
+ }): Promise<readonly string[]>;
40
+ delete({ location, relativePath, }: {
41
+ readonly location: StorageLocation;
42
+ readonly relativePath: string;
43
+ }): Promise<void>;
44
+ getAvailableSpace({ location, }: {
45
+ readonly location: StorageLocation;
46
+ }): Promise<number | null>;
47
+ beginUpload({ location, relativePath, }: {
48
+ readonly location: StorageLocation;
49
+ readonly relativePath: string;
50
+ readonly sizeBytes?: number;
51
+ }): Promise<{
52
+ readonly uploadId: string;
53
+ }>;
54
+ writeChunk({ uploadId, offset, data, }: {
55
+ readonly uploadId: string;
56
+ readonly offset: number;
57
+ readonly data: Uint8Array;
58
+ }): Promise<void>;
59
+ finalizeUpload({ uploadId }: {
60
+ readonly uploadId: string;
61
+ }): Promise<void>;
62
+ abortUpload({ uploadId }: {
63
+ readonly uploadId: string;
64
+ }): Promise<void>;
65
+ beginDownload({ location, relativePath, }: {
66
+ readonly location: StorageLocation;
67
+ readonly relativePath: string;
68
+ }): Promise<{
69
+ readonly downloadId: string;
70
+ readonly sizeBytes: number;
71
+ }>;
72
+ readChunk({ downloadId, offset, length, }: {
73
+ readonly downloadId: string;
74
+ readonly offset: number;
75
+ readonly length: number;
76
+ }): Promise<Uint8Array<ArrayBuffer>>;
77
+ endDownload({ downloadId }: {
78
+ readonly downloadId: string;
79
+ }): Promise<void>;
80
+ /**
81
+ * Abort all outstanding sessions. Called on addon shutdown so timers
82
+ * don't leak across hot-reload cycles.
83
+ */
84
+ dispose(): Promise<void>;
85
+ }
86
+ export default FilesystemStorageProvider;
87
+ //# sourceMappingURL=filesystem-storage-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-storage-provider.d.ts","sourceRoot":"","sources":["../../../src/builtins/sqlite-storage/filesystem-storage-provider.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,32 @@
1
- import '@camstack/types';
2
- export { F as FilesystemStorageAddon, F as default } from '../../filesystem-storage.addon-C42r589X.js';
1
+ import { ProviderRegistration, BaseAddon } from '@camstack/types';
2
+ import { FilesystemStorageProvider } from './filesystem-storage-provider.js';
3
+ interface FilesystemStorageConfig {
4
+ readonly rootPath: string;
5
+ }
6
+ /**
7
+ * Filesystem Storage addon — registers a filesystem-backed
8
+ * `storage-provider` (Task 7).
9
+ *
10
+ * Pre-Task 7 this addon registered against the (then-collection)
11
+ * `storage` cap. After Tasks 2/3/4 the consumer-facing `storage` cap is
12
+ * a singleton owned by `storage-orchestrator`; the orchestrator
13
+ * dispatches each call to whichever `storage-provider` matches
14
+ * `location.providerId`.
15
+ *
16
+ * The OLD `rootPath` config field is preserved for back-compat: the
17
+ * orchestrator's first-boot seeding step still uses the same env-var
18
+ * resolution chain (operator override → `CAMSTACK_DATA` → fallback) to
19
+ * derive the base path of every default location, then writes
20
+ * `config.basePath` into each persisted `StorageLocation` row. The
21
+ * provider itself is now stateless — every call carries the live
22
+ * `StorageLocation` inline.
23
+ */
24
+ export declare class FilesystemStorageAddon extends BaseAddon<FilesystemStorageConfig> {
25
+ private provider;
26
+ constructor();
27
+ protected onInitialize(): Promise<ProviderRegistration[]>;
28
+ protected onShutdown(): Promise<void>;
29
+ getProvider(): FilesystemStorageProvider | null;
30
+ }
31
+ export default FilesystemStorageAddon;
32
+ //# sourceMappingURL=filesystem-storage.addon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-storage.addon.d.ts","sourceRoot":"","sources":["../../../src/builtins/sqlite-storage/filesystem-storage.addon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAA6B,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAE5E,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,sBAAuB,SAAQ,SAAS,CAAC,uBAAuB,CAAC;IAC5E,OAAO,CAAC,QAAQ,CAAyC;;cAMzC,YAAY,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;cAM/C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3C,WAAW,IAAI,yBAAyB,GAAG,IAAI;CAGhD;AAED,eAAe,sBAAsB,CAAA"}