@camstack/core 0.1.15 → 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 (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 +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 +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
@@ -0,0 +1,41 @@
1
+ export interface IStorageBackend {
2
+ /** Backend type identifier */
3
+ readonly type: string;
4
+ /** Base path of this backend */
5
+ readonly basePath: string;
6
+ /** Resolve a subpath to an absolute path */
7
+ resolve(subpath: string): string;
8
+ /**
9
+ * Check whether the backend is usable: either the base directory
10
+ * already exists and is writable, OR we can create it on first
11
+ * write (i.e. the nearest existing ancestor is writable).
12
+ */
13
+ isAvailable(): boolean;
14
+ /** No-op for lazy backends. Kept for API compatibility. */
15
+ initialize(): Promise<void>;
16
+ }
17
+ /**
18
+ * Filesystem storage backend — lazy by design.
19
+ *
20
+ * `initialize()` does NOT create the base directory eagerly. Instead,
21
+ * consumers that write via `FilesystemStorageProvider` (and other write
22
+ * helpers in storage-manager.ts) run `fs.mkdir(dirname(filePath), { recursive: true })`
23
+ * right before every `writeFile`, so the directory tree appears on demand.
24
+ *
25
+ * The previous behaviour eagerly mkdir'd every location declared in
26
+ * `StorageLocationManager.initializeDefaults()` — six directories (`db`,
27
+ * `media`, `recordings`, `models`, `cache`, `logs`) got created at boot
28
+ * even if the installation had no cameras, no recording addon, no
29
+ * analytics addon, etc. That meant every fresh install looked like it
30
+ * was producing data when it had nothing to write. Laziness fixes that:
31
+ * a directory only exists once an addon decides to put a file there.
32
+ */
33
+ export declare class FsStorageBackend implements IStorageBackend {
34
+ readonly type = "local";
35
+ readonly basePath: string;
36
+ constructor(basePath: string);
37
+ resolve(subpath: string): string;
38
+ isAvailable(): boolean;
39
+ initialize(): Promise<void>;
40
+ }
41
+ //# sourceMappingURL=fs-storage-backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-storage-backend.d.ts","sourceRoot":"","sources":["../../src/storage/fs-storage-backend.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,4CAA4C;IAC5C,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IAChC;;;;OAIG;IACH,WAAW,IAAI,OAAO,CAAA;IACtB,2DAA2D;IAC3D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACtD,QAAQ,CAAC,IAAI,WAAU;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;gBAEb,QAAQ,EAAE,MAAM;IAI5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAKhC,WAAW,IAAI,OAAO;IAwBhB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAIlC"}
@@ -0,0 +1,24 @@
1
+ import { IStorageBackend } from './fs-storage-backend.js';
2
+ export type StorageLocationName = 'data' | 'media' | 'recordings' | 'models' | 'cache' | 'logs';
3
+ export declare class StorageLocationManager {
4
+ private readonly backends;
5
+ private readonly dataPath;
6
+ constructor(dataPath: string);
7
+ /** Initialize all locations with default paths */
8
+ initializeDefaults(): Promise<void>;
9
+ /** Override a specific location's backend path */
10
+ setLocationPath(name: StorageLocationName, basePath: string): Promise<void>;
11
+ /** Get the backend for a location */
12
+ getBackend(name: StorageLocationName): IStorageBackend;
13
+ /** Resolve a path within a location */
14
+ resolve(location: StorageLocationName, subpath: string): string;
15
+ /** Check if all locations are available */
16
+ getStatus(): Array<{
17
+ name: StorageLocationName;
18
+ available: boolean;
19
+ path: string;
20
+ }>;
21
+ /** All location names */
22
+ getLocationNames(): StorageLocationName[];
23
+ }
24
+ //# sourceMappingURL=storage-location-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-location-manager.d.ts","sourceRoot":"","sources":["../../src/storage/storage-location-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEhF,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;AAE/F,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuD;IAChF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAErB,QAAQ,EAAE,MAAM;IAI5B,kDAAkD;IAC5C,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBzC,kDAAkD;IAC5C,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjF,qCAAqC;IACrC,UAAU,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe;IAMtD,uCAAuC;IACvC,OAAO,CAAC,QAAQ,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAI/D,2CAA2C;IAC3C,SAAS,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,mBAAmB,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAQnF,yBAAyB;IACzB,gBAAgB,IAAI,mBAAmB,EAAE;CAG1C"}
@@ -0,0 +1,77 @@
1
+ import { StorageLocationManager, StorageLocationName } from './storage-location-manager.js';
2
+ import { IStorageProvider as INewStorageProvider, ISettingsBackend } from '@camstack/types';
3
+ export interface IStorageProvider {
4
+ initialize(): Promise<void>;
5
+ shutdown(): Promise<void>;
6
+ getLocation(name: StorageLocationName): IStorageLocation;
7
+ export?(locationName: StorageLocationName): Promise<Buffer>;
8
+ import?(locationName: StorageLocationName, data: Buffer): Promise<void>;
9
+ }
10
+ export interface QueryFilter {
11
+ where?: Record<string, unknown>;
12
+ whereIn?: Record<string, unknown[]>;
13
+ whereBetween?: Record<string, [unknown, unknown]>;
14
+ orderBy?: {
15
+ field: string;
16
+ direction: 'asc' | 'desc';
17
+ };
18
+ limit?: number;
19
+ offset?: number;
20
+ }
21
+ export interface StorageRecord {
22
+ collection: string;
23
+ id: string;
24
+ data: Record<string, unknown>;
25
+ }
26
+ export interface IStructuredStorage {
27
+ query(collection: string, filter?: QueryFilter): Promise<readonly StorageRecord[]>;
28
+ insert(record: StorageRecord): Promise<StorageRecord>;
29
+ update(collection: string, id: string, data: Record<string, unknown>): Promise<StorageRecord>;
30
+ delete(collection: string, id: string): Promise<void>;
31
+ count(collection: string, filter?: QueryFilter): Promise<number>;
32
+ }
33
+ export interface IFileStorage {
34
+ readFile(path: string): Promise<Buffer>;
35
+ writeFile(path: string, data: Buffer): Promise<void>;
36
+ deleteFile(path: string): Promise<void>;
37
+ listFiles(prefix?: string): Promise<readonly string[]>;
38
+ getFileUrl(path: string): Promise<string>;
39
+ exists(path: string): Promise<boolean>;
40
+ }
41
+ export interface IStorageLocation {
42
+ structured?: IStructuredStorage;
43
+ files?: IFileStorage;
44
+ }
45
+ /**
46
+ * StorageManager — bridge between legacy code (getLocation/getLocationPath)
47
+ * and the new capability-based storage system.
48
+ *
49
+ * Legacy consumers call getLocation('addon', namespace) to get structured + file storage.
50
+ * This manager builds the response from:
51
+ * - SettingsBackend (for structured queries) — provided by sqlite-settings addon
52
+ * - LocationManager (for file paths) — set during Phase 2 boot
53
+ */
54
+ export declare class StorageManager {
55
+ private legacyProvider;
56
+ private locationManager;
57
+ private newStorageProvider;
58
+ private settingsBackend;
59
+ /** @deprecated Set by legacy capability consumer — use setNewStorageProvider instead */
60
+ setProvider(provider: IStorageProvider | INewStorageProvider): void;
61
+ setNewStorageProvider(provider: INewStorageProvider): void;
62
+ setSettingsBackend(backend: ISettingsBackend): void;
63
+ getSettingsBackend(): ISettingsBackend;
64
+ getProvider(): IStorageProvider;
65
+ setLocationManager(manager: StorageLocationManager): void;
66
+ getLocationManager(): StorageLocationManager;
67
+ initializeLocations(dataPath: string): Promise<void>;
68
+ getLocationPath(name: StorageLocationName): string;
69
+ /**
70
+ * Get a storage location with optional namespace scoping.
71
+ * Builds IStorageLocation from settingsBackend (structured) + locationManager (files).
72
+ */
73
+ getLocation(name: StorageLocationName | string, namespace?: string): IStorageLocation;
74
+ private createLegacyShim;
75
+ private createNamespacedLocation;
76
+ }
77
+ //# sourceMappingURL=storage-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-manager.d.ts","sourceRoot":"","sources":["../../src/storage/storage-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface TlsCertPair {
2
+ readonly cert: Buffer;
3
+ readonly key: Buffer;
4
+ }
5
+ export interface EnsureTlsResult {
6
+ readonly certPath: string;
7
+ readonly keyPath: string;
8
+ readonly generated: boolean;
9
+ }
10
+ export interface CertOptions {
11
+ /** Common Name for the cert (default: 'camstack.local') */
12
+ readonly commonName?: string;
13
+ /** Validity in days (default: 825 — max for browsers) */
14
+ readonly validDays?: number;
15
+ /** Additional SANs (DNS names or IPs) */
16
+ readonly extraSans?: readonly string[];
17
+ }
18
+ /**
19
+ * Ensure a self-signed TLS certificate exists in the given directory.
20
+ * Generates one if missing. Returns paths to cert and key files.
21
+ */
22
+ export declare function ensureTlsCert(dataDir: string, options?: CertOptions): Promise<EnsureTlsResult>;
23
+ /**
24
+ * Load TLS cert+key from files. Returns Buffers suitable for Node.js TLS options.
25
+ */
26
+ export declare function loadTlsCert(certPath: string, keyPath: string): TlsCertPair;
27
+ //# sourceMappingURL=cert-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cert-manager.d.ts","sourceRoot":"","sources":["../../src/tls/cert-manager.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACvC;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,eAAe,CAAC,CA4E1B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAK1E"}
@@ -0,0 +1,2 @@
1
+ export { ensureTlsCert, loadTlsCert, type TlsCertPair, type EnsureTlsResult, type CertOptions } from './cert-manager.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tls/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/core",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",
@@ -34,8 +34,7 @@
34
34
  "entry": "./dist/builtins/sqlite-storage/filesystem-storage.addon.js",
35
35
  "capabilities": [
36
36
  {
37
- "name": "storage",
38
- "mode": "collection"
37
+ "name": "storage-provider"
39
38
  }
40
39
  ]
41
40
  },
@@ -45,8 +44,7 @@
45
44
  "entry": "./dist/builtins/sqlite-storage/sqlite-settings.addon.js",
46
45
  "capabilities": [
47
46
  {
48
- "name": "settings-store",
49
- "mode": "singleton"
47
+ "name": "settings-store"
50
48
  }
51
49
  ]
52
50
  },
@@ -56,8 +54,7 @@
56
54
  "entry": "./dist/builtins/winston-logging/index.js",
57
55
  "capabilities": [
58
56
  {
59
- "name": "log-destination",
60
- "mode": "collection"
57
+ "name": "log-destination"
61
58
  }
62
59
  ]
63
60
  },
@@ -67,30 +64,45 @@
67
64
  "entry": "./dist/builtins/console-logging/index.js",
68
65
  "capabilities": [
69
66
  {
70
- "name": "log-destination",
71
- "mode": "collection"
67
+ "name": "log-destination"
72
68
  }
73
69
  ]
74
70
  },
75
71
  {
76
72
  "id": "hub-forwarder",
77
73
  "name": "Hub Log Forwarder",
74
+ "description": "Agent-only log destination — forwards every log entry to the hub via the cluster broker. Never runs on the hub itself (the hub already owns the log-receiver, registering hub-forwarder there would create a write→ingest→write feedback loop).",
78
75
  "entry": "./dist/builtins/hub-forwarder/index.js",
76
+ "execution": {
77
+ "placement": "agent-only"
78
+ },
79
79
  "capabilities": [
80
80
  {
81
- "name": "log-destination",
82
- "mode": "collection"
81
+ "name": "log-destination"
83
82
  }
84
83
  ]
85
84
  },
86
85
  {
87
- "id": "local-backup",
88
- "name": "Local Backup",
89
- "entry": "./dist/builtins/local-backup/index.js",
86
+ "id": "backup-orchestrator",
87
+ "name": "Backup Orchestrator",
88
+ "description": "System singleton that owns the schedule, builds the archive once, and fans it out to every enabled `backup-destination` provider (local, S3, rsync, …).",
89
+ "entry": "./dist/builtins/backup-orchestrator/index.js",
90
+ "protected": true,
90
91
  "capabilities": [
91
92
  {
92
- "name": "backup",
93
- "mode": "collection"
93
+ "name": "backup"
94
+ }
95
+ ]
96
+ },
97
+ {
98
+ "id": "storage-orchestrator",
99
+ "name": "Storage Orchestrator",
100
+ "description": "Hub-only singleton that owns the consumer-facing `storage` cap. Holds the `locationId → StorageLocation` map (Task 6 will persist to SQLite), resolves `StorageLocationRef` to concrete locations, and dispatches every call to the matching `storage-provider` collection registrant (`filesystem-storage` today; future SFTP / S3 / WebDAV addons plug in alongside).",
101
+ "entry": "./dist/builtins/storage-orchestrator/index.js",
102
+ "protected": true,
103
+ "capabilities": [
104
+ {
105
+ "name": "storage"
94
106
  }
95
107
  ]
96
108
  },
@@ -100,8 +112,7 @@
100
112
  "entry": "./dist/builtins/native-metrics/native-metrics.addon.js",
101
113
  "capabilities": [
102
114
  {
103
- "name": "metrics-provider",
104
- "mode": "singleton"
115
+ "name": "metrics-provider"
105
116
  }
106
117
  ]
107
118
  },
@@ -111,8 +122,7 @@
111
122
  "entry": "./dist/builtins/snapshot/index.js",
112
123
  "capabilities": [
113
124
  {
114
- "name": "snapshot",
115
- "mode": "singleton"
125
+ "name": "snapshot"
116
126
  }
117
127
  ]
118
128
  },
@@ -122,8 +132,7 @@
122
132
  "entry": "./dist/builtins/alerts/index.js",
123
133
  "capabilities": [
124
134
  {
125
- "name": "alerts",
126
- "mode": "collection"
135
+ "name": "alerts"
127
136
  }
128
137
  ]
129
138
  },
@@ -187,6 +196,87 @@
187
196
  "name": "user-management"
188
197
  }
189
198
  ]
199
+ },
200
+ {
201
+ "id": "platform-probe",
202
+ "name": "Platform Probe (Native)",
203
+ "description": "Probes hardware and inference runtimes on the local node. Registers the `platform-probe` capability consumed by every inference addon on this node.",
204
+ "entry": "./dist/builtins/platform-probe/index.js",
205
+ "protected": true,
206
+ "execution": {
207
+ "placement": "any-node"
208
+ },
209
+ "capabilities": [
210
+ {
211
+ "name": "platform-probe"
212
+ }
213
+ ]
214
+ },
215
+ {
216
+ "id": "local-network",
217
+ "name": "Local Network",
218
+ "description": "Enumerates the hub's network interfaces, classifies them (LAN / Wi-Fi / Docker / VPN / loopback), and ranks connection-endpoints for SDK clients. Hub-only — agents are not directly addressable.",
219
+ "entry": "./dist/builtins/local-network/index.js",
220
+ "protected": true,
221
+ "execution": {
222
+ "placement": "hub-only"
223
+ },
224
+ "capabilities": [
225
+ {
226
+ "name": "local-network"
227
+ }
228
+ ]
229
+ },
230
+ {
231
+ "id": "auth-orchestrator",
232
+ "name": "Authentication Orchestrator",
233
+ "description": "Hub-only singleton facade over the auth-provider collection. Surfaces a unified provider list to the admin UI's Authentication page and the login screen's provider picker.",
234
+ "entry": "./dist/builtins/auth-orchestrator/index.js",
235
+ "protected": true,
236
+ "capabilities": [
237
+ {
238
+ "name": "authentication"
239
+ }
240
+ ]
241
+ },
242
+ {
243
+ "id": "mesh-orchestrator",
244
+ "name": "Mesh Orchestrator",
245
+ "description": "Hub-only singleton facade over the mesh-network collection. Aggregates Tailscale / Headscale / ZeroTier providers for the admin UI's Mesh Networks page.",
246
+ "entry": "./dist/builtins/mesh-orchestrator/index.js",
247
+ "protected": true,
248
+ "execution": {
249
+ "placement": "hub-only"
250
+ },
251
+ "capabilities": [
252
+ {
253
+ "name": "mesh-orchestrator"
254
+ }
255
+ ]
256
+ },
257
+ {
258
+ "id": "remote-access-orchestrator",
259
+ "name": "Remote Access Orchestrator",
260
+ "description": "Hub-only singleton facade over the network-access collection (Cloudflare Tunnel, ngrok, …). Surfaces a unified provider list to the admin UI's Remote Access page.",
261
+ "entry": "./dist/builtins/remote-access-orchestrator/index.js",
262
+ "protected": true,
263
+ "capabilities": [
264
+ {
265
+ "name": "remote-access"
266
+ }
267
+ ]
268
+ },
269
+ {
270
+ "id": "turn-orchestrator",
271
+ "name": "TURN Orchestrator",
272
+ "description": "Hub-only singleton facade over the turn-provider collection. Aggregates ICE servers from all enabled TURN providers; consumed by the WebRTC layer at session creation.",
273
+ "entry": "./dist/builtins/turn-orchestrator/index.js",
274
+ "protected": true,
275
+ "capabilities": [
276
+ {
277
+ "name": "turn-orchestrator"
278
+ }
279
+ ]
190
280
  }
191
281
  ]
192
282
  },
@@ -194,7 +284,7 @@
194
284
  "dist"
195
285
  ],
196
286
  "scripts": {
197
- "build": "tsup",
287
+ "build": "vite build",
198
288
  "dev": "tsup --watch",
199
289
  "typecheck": "tsc --noEmit",
200
290
  "test": "vitest run",
@@ -205,7 +295,10 @@
205
295
  "@camstack/kernel": "*",
206
296
  "bcryptjs": "^2.4.3",
207
297
  "better-sqlite3": "^12.8.0",
298
+ "croner": "^10.0.1",
208
299
  "jsonwebtoken": "^9.0.0",
300
+ "systeminformation": "^5.0.0",
301
+ "tar": "^6.2.1",
209
302
  "winston": "^3.19.0",
210
303
  "winston-daily-rotate-file": "^5.0.0"
211
304
  },
@@ -218,8 +311,11 @@
218
311
  "@types/bcryptjs": "^2.4.6",
219
312
  "@types/better-sqlite3": "^7.6.13",
220
313
  "@types/jsonwebtoken": "^9.0.0",
314
+ "@types/tar": "^6.1.13",
221
315
  "tsup": "^8.0.0",
222
316
  "typescript": "~5.9.0",
317
+ "vite": "^8.0.11",
318
+ "vite-plugin-dts": "^5.0.0",
223
319
  "vitest": "^3.0.0"
224
320
  }
225
321
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/builtins/addon-pages-aggregator/index.ts","../../../src/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.ts"],"sourcesContent":["export { AddonPagesAggregatorAddon, default } from './addon-pages-aggregator.addon.js'\n","/**\n * Addon Pages Aggregator — hub-local builtin that owns the singleton\n * `addon-pages` cap.\n *\n * Walks every registered `addon-pages-source` (collection) provider and\n * emits an enriched `AddonPageInfo[]` list with versioned `bundleUrl`s\n * pointing at `/api/addon-pages/<addonId>/<bundle>?v=<mtime>`. The\n * filesystem `mtime` cache-buster lets the browser pick up addon\n * rebuilds without manual reload — same scheme the original\n * hand-written `AddonPagesService.listPages` used before this split.\n *\n * The static file endpoint (`/api/addon-pages/:addonId/*`) is still\n * served by `AddonPagesService.resolveBundle()` on the server side; this\n * addon only owns the listing surface.\n *\n * Why a builtin rather than a cap-providers helper:\n * - The aggregator is conceptually the \"addon-pages provider\" — addons\n * own caps, not the server. Living in `@camstack/core/builtins` keeps\n * the surface symmetrical with `system-config`, `local-auth`, etc.\n * - Lets the aggregator subscribe to source readiness without piping a\n * CapabilityRegistry handle through `RouterServices`.\n */\nimport * as path from 'node:path'\nimport * as fs from 'node:fs'\nimport { randomUUID } from 'node:crypto'\nimport {\n BaseAddon,\n EventCategory,\n addonPagesCapability,\n errMsg,\n type AddonPageInfo,\n type IAddonPageProvider,\n type IAddonPagesAggregatorProvider,\n type ProviderRegistration,\n} from '@camstack/types'\n\ninterface ResolvedPaths {\n readonly addonsDir: string\n}\n\n/**\n * Backoff schedule (ms) used to retry sources that failed during a\n * `listPages()` round-trip — typically because the cap was just\n * registered (provider connected via Moleculer) but the worker-side\n * action registration hadn't propagated yet, so `Service '...listPages'\n * is not found on '<node>'` raced ahead of the call.\n *\n * We schedule one retry per entry; if every retry fails we stop\n * (the next aggregate() run will pick the source up again). On\n * success we re-emit `AddonPageReady` so admin-ui invalidates its\n * `addonPages.listPages` query and the sidebar populates without a\n * page reload.\n */\nconst RETRY_BACKOFF_MS: readonly number[] = [500, 1500, 4000]\n\nexport class AddonPagesAggregatorAddon extends BaseAddon {\n readonly id = 'addon-pages-aggregator'\n\n private resolvedPaths: ResolvedPaths | null = null\n\n /**\n * Last successful `listPages()` snapshot per source. Used as the\n * \"stale-but-valid\" fallback when a source transiently fails — drops\n * happen often enough during boot (Moleculer service-discovery\n * window) that swallowing the error and returning empty leaves the\n * sidebar with nothing for several seconds. Keeping the previous\n * good entry means a flake is invisible to the operator.\n */\n private readonly lastGood = new Map<string, readonly AddonPageInfo[]>()\n\n /** In-flight retry guards keyed by sourceId. Avoids double-scheduling. */\n private readonly retryTimers = new Map<string, NodeJS.Timeout>()\n\n constructor() { super({}) }\n\n protected async onInitialize(): Promise<ProviderRegistration[]> {\n this.resolvedPaths = await this.resolvePaths()\n\n const provider: IAddonPagesAggregatorProvider = {\n listPages: async (): Promise<readonly AddonPageInfo[]> => this.aggregate(),\n }\n\n this.ctx.logger.info('Initialized — aggregating addon-pages-source providers')\n return [{ capability: addonPagesCapability, provider }]\n }\n\n protected async onShutdown(): Promise<void> {\n for (const t of this.retryTimers.values()) clearTimeout(t)\n this.retryTimers.clear()\n this.lastGood.clear()\n }\n\n // ── Aggregation ───────────────────────────────────────────────────\n\n private async aggregate(): Promise<readonly AddonPageInfo[]> {\n const sources = this.capabilities?.getCollection<IAddonPageProvider>('addon-pages-source') ?? []\n const out: AddonPageInfo[] = []\n const seenIds = new Set<string>()\n\n for (const source of sources) {\n seenIds.add(source.id)\n try {\n // listPages() may be async for remote Moleculer providers.\n const pages = await Promise.resolve(source.listPages())\n const enriched: AddonPageInfo[] = pages.map((page) => ({\n addonId: source.id,\n page,\n bundleUrl: this.makeBundleUrl(source.id, page.bundle),\n }))\n for (const item of enriched) out.push(item)\n // Cache successful snapshot — used as fallback on next failure.\n this.lastGood.set(source.id, enriched)\n } catch (err: unknown) {\n const message = errMsg(err)\n this.ctx.logger.warn('addon-pages-source provider failed', {\n meta: { sourceId: source.id, error: message },\n })\n // Fall back to the last-good snapshot for this source so a\n // transient Moleculer service-discovery race (cap registered\n // but action not yet callable) doesn't blank the sidebar.\n const cached = this.lastGood.get(source.id)\n if (cached !== undefined) {\n for (const item of cached) out.push(item)\n this.ctx.logger.info('addon-pages-source falling back to cached snapshot', {\n meta: { sourceId: source.id, cachedPages: cached.length },\n })\n }\n // Schedule a background retry. On success we re-emit\n // `AddonPageReady` so admin-ui's queryClient invalidates and\n // any newly-loaded pages show up without a manual reload.\n this.scheduleRetry(source.id)\n }\n }\n\n // Drop cache entries for sources that have disappeared from the\n // registry — keeps the fallback aligned with the live collection.\n for (const cachedId of this.lastGood.keys()) {\n if (!seenIds.has(cachedId)) this.lastGood.delete(cachedId)\n }\n\n return out\n }\n\n // ── Retry on transient Moleculer race ─────────────────────────────\n\n /**\n * Schedule background re-call of `listPages()` on a source that just\n * failed. Walks `RETRY_BACKOFF_MS` from index 0 — each successful\n * call updates the cache and emits `AddonPageReady` so the admin UI\n * invalidates its query. Stops on first success or after the schedule\n * is exhausted.\n */\n private scheduleRetry(sourceId: string, attempt = 0): void {\n if (attempt >= RETRY_BACKOFF_MS.length) return\n if (this.retryTimers.has(sourceId)) return // already pending\n\n const delayMs = RETRY_BACKOFF_MS[attempt] ?? RETRY_BACKOFF_MS[RETRY_BACKOFF_MS.length - 1]!\n const timer = setTimeout(() => {\n this.retryTimers.delete(sourceId)\n void this.retrySource(sourceId, attempt)\n }, delayMs)\n this.retryTimers.set(sourceId, timer)\n }\n\n private async retrySource(sourceId: string, attempt: number): Promise<void> {\n const sources = this.capabilities?.getCollection<IAddonPageProvider>('addon-pages-source') ?? []\n const source = sources.find((s) => s.id === sourceId)\n if (!source) return // provider went away; nothing to retry\n\n try {\n const pages = await Promise.resolve(source.listPages())\n const enriched: AddonPageInfo[] = pages.map((page) => ({\n addonId: source.id,\n page,\n bundleUrl: this.makeBundleUrl(source.id, page.bundle),\n }))\n this.lastGood.set(source.id, enriched)\n this.ctx.logger.info('addon-pages-source recovered after retry', {\n meta: { sourceId, attempt: attempt + 1, pages: enriched.length },\n })\n // Re-emit AddonPageReady so admin-ui invalidates and refetches.\n this.ctx.eventBus.emit({\n id: randomUUID(),\n timestamp: new Date(),\n source: { type: 'addon', id: this.id },\n category: EventCategory.AddonPageReady,\n data: { addonId: sourceId, recovered: true },\n })\n } catch (err: unknown) {\n this.ctx.logger.debug('addon-pages-source retry failed', {\n meta: { sourceId, attempt: attempt + 1, error: errMsg(err) },\n })\n this.scheduleRetry(sourceId, attempt + 1)\n }\n }\n\n // ── Bundle URL stamping ──────────────────────────────────────────\n\n /**\n * Build `/api/addon-pages/<addonId>/<bundle>?v=<mtime>`. Falls back\n * to `Date.now()` when the bundle path can't be stat'd (remote addon\n * with no local file, addon not yet on disk, etc.) — the browser\n * just gets a fresh URL on each call instead of cache-friendly mtime.\n */\n private makeBundleUrl(addonId: string, bundle: string): string {\n const bundlePath = this.resolveBundlePath(addonId, bundle)\n let mtime = Date.now()\n if (bundlePath !== null) {\n try { mtime = fs.statSync(bundlePath).mtimeMs }\n catch { /* remote addon — no local file */ }\n }\n const v = Math.floor(mtime)\n return `/api/addon-pages/${addonId}/${bundle}?v=${v}`\n }\n\n /**\n * Resolve the local filesystem path for an addon's bundle. Mirrors\n * `AddonPagesService.resolveBundle` (server-side), but without the\n * existence / traversal checks — those still live on the server's\n * static file route. We only need a stat-able path here for the\n * `mtime` cache-buster.\n */\n private resolveBundlePath(addonId: string, bundle: string): string | null {\n const paths = this.resolvedPaths\n if (!paths) return null\n const addonDistPath = path.join(paths.addonsDir, '@camstack', `addon-${addonId}`, 'dist')\n const resolvedBase = path.resolve(addonDistPath)\n const resolvedFile = path.resolve(addonDistPath, bundle)\n if (!resolvedFile.startsWith(resolvedBase + path.sep) && resolvedFile !== resolvedBase) {\n return null\n }\n return resolvedFile\n }\n\n // ── Path resolution ──────────────────────────────────────────────\n\n /**\n * Read `server.dataPath` from the cluster yml-backed sections (same\n * source the server uses at boot), then derive the addons directory\n * from it. Falls back to `camstack-data/addons` when no settings API\n * is available — agents and isolated tests don't see this addon, so\n * the fallback is purely defensive.\n */\n private async resolvePaths(): Promise<ResolvedPaths> {\n const fallback: ResolvedPaths = { addonsDir: path.resolve('camstack-data', 'addons') }\n if (!this.ctx.settings) return fallback\n try {\n const server = await this.ctx.settings.getSection('server')\n const dataPath = typeof server['dataPath'] === 'string' && server['dataPath']\n ? server['dataPath']\n : 'camstack-data'\n return { addonsDir: path.resolve(dataPath, 'addons') }\n } catch (err: unknown) {\n this.ctx.logger.debug('Failed to read server.dataPath — falling back', {\n meta: { error: errMsg(err) },\n })\n return fallback\n }\n }\n}\n\nexport default AddonPagesAggregatorAddon\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/builtins/addon-widgets-aggregator/index.ts","../../../src/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.ts"],"sourcesContent":["export { AddonWidgetsAggregatorAddon, default } from './addon-widgets-aggregator.addon.js'\n","/**\n * Addon Widgets Aggregator — hub-local builtin that owns the singleton\n * `addon-widgets` cap.\n *\n * Mirrors `addon-pages-aggregator` exactly: walks every registered\n * `addon-widgets-source` (collection) provider and emits an enriched\n * widget metadata list with versioned `bundleUrl`s pointing at\n * `/api/addon-widgets/<addonId>/<bundle>?v=<mtime>`. The filesystem\n * `mtime` cache-buster lets the browser pick up addon rebuilds without\n * manual reload.\n *\n * The static file endpoint (`/api/addon-widgets/:addonId/*`) is served\n * by `AddonWidgetsService.resolveBundle()` on the server side; this\n * addon only owns the listing surface.\n *\n * Why a builtin: same reasoning as `addon-pages-aggregator`. The\n * aggregator is the de-facto \"addon-widgets provider\" — addons own caps,\n * not the server. Living in `@camstack/core/builtins` keeps the surface\n * symmetrical with `system-config`, `local-auth`, etc.\n */\nimport * as path from 'node:path'\nimport * as fs from 'node:fs'\nimport { randomUUID } from 'node:crypto'\nimport {\n BaseAddon,\n EventCategory,\n addonWidgetsCapability,\n errMsg,\n type IAddonWidgetsAggregatorProvider,\n type IAddonWidgetsSourceProvider,\n type ProviderRegistration,\n} from '@camstack/types'\n\ninterface ResolvedPaths {\n readonly addonsDir: string\n}\n\n/**\n * Inferred from the cap definition — equivalent to:\n * `z.infer<typeof EnrichedWidgetMetadataSchema>` but reuses the\n * provider's return type so the aggregator stays in lockstep with the\n * cap if its shape evolves.\n */\ntype EnrichedWidget = Awaited<ReturnType<IAddonWidgetsAggregatorProvider['listWidgets']>>[number]\ntype RawWidget = Awaited<ReturnType<IAddonWidgetsSourceProvider['listWidgets']>>[number]\n\n/**\n * Backoff schedule (ms) used to retry sources that failed during a\n * `listWidgets()` round-trip — typically because the cap was just\n * registered (provider connected via Moleculer) but the worker-side\n * action registration hadn't propagated yet, so `Service '...listWidgets'\n * is not found on '<node>'` raced ahead of the call.\n *\n * On success we re-emit `AddonWidgetReady` so admin-ui invalidates its\n * `addonWidgets.listWidgets` query and the registry populates without a\n * page reload.\n */\nconst RETRY_BACKOFF_MS: readonly number[] = [500, 1500, 4000]\n\nexport class AddonWidgetsAggregatorAddon extends BaseAddon {\n readonly id = 'addon-widgets-aggregator'\n\n private resolvedPaths: ResolvedPaths | null = null\n\n /**\n * Last successful `listWidgets()` snapshot per source. Used as the\n * \"stale-but-valid\" fallback when a source transiently fails — drops\n * happen often enough during boot (Moleculer service-discovery\n * window) that swallowing the error and returning empty would leave\n * the dashboard with nothing for several seconds. Keeping the\n * previous good entry means a flake is invisible to the operator.\n */\n private readonly lastGood = new Map<string, readonly EnrichedWidget[]>()\n\n /** In-flight retry guards keyed by sourceAddonId. Avoids double-scheduling. */\n private readonly retryTimers = new Map<string, NodeJS.Timeout>()\n\n constructor() { super({}) }\n\n protected async onInitialize(): Promise<ProviderRegistration[]> {\n this.resolvedPaths = await this.resolvePaths()\n\n const provider: IAddonWidgetsAggregatorProvider = {\n listWidgets: async (): Promise<readonly EnrichedWidget[]> => this.aggregate(),\n }\n\n this.ctx.logger.info('Initialized — aggregating addon-widgets-source providers')\n return [{ capability: addonWidgetsCapability, provider }]\n }\n\n protected async onShutdown(): Promise<void> {\n for (const t of this.retryTimers.values()) clearTimeout(t)\n this.retryTimers.clear()\n this.lastGood.clear()\n }\n\n // ── Aggregation ───────────────────────────────────────────────────\n\n private async aggregate(): Promise<readonly EnrichedWidget[]> {\n // `getCollectionEntries` returns `[addonId, provider]` tuples — the\n // raw `addon-widgets-source` cap doesn't carry an `id` on the\n // provider (unlike the legacy `IAddonPageProvider`), so we lean on\n // the registry to attribute each contribution back to its addon.\n const entries = this.capabilities?.getCollectionEntries<IAddonWidgetsSourceProvider>('addon-widgets-source') ?? []\n const out: EnrichedWidget[] = []\n const seenIds = new Set<string>()\n\n for (const [addonId, source] of entries) {\n seenIds.add(addonId)\n try {\n const widgets = await Promise.resolve(source.listWidgets())\n const enriched: EnrichedWidget[] = widgets.map((w: RawWidget) => ({\n ...w,\n addonId,\n bundleUrl: this.makeBundleUrl(addonId, w.bundle),\n }))\n for (const item of enriched) out.push(item)\n // Cache successful snapshot — used as fallback on next failure.\n this.lastGood.set(addonId, enriched)\n } catch (err: unknown) {\n const message = errMsg(err)\n this.ctx.logger.warn('addon-widgets-source provider failed', {\n meta: { sourceId: addonId, error: message },\n })\n // Fall back to the last-good snapshot for this source so a\n // transient Moleculer service-discovery race doesn't blank\n // the dashboard.\n const cached = this.lastGood.get(addonId)\n if (cached !== undefined) {\n for (const item of cached) out.push(item)\n this.ctx.logger.info('addon-widgets-source falling back to cached snapshot', {\n meta: { sourceId: addonId, cachedWidgets: cached.length },\n })\n }\n // Schedule a background retry. On success we re-emit\n // `AddonWidgetReady` so admin-ui's queryClient invalidates and\n // any newly-loaded widgets show up without a manual reload.\n this.scheduleRetry(addonId)\n }\n }\n\n // Drop cache entries for sources that have disappeared from the\n // registry — keeps the fallback aligned with the live collection.\n for (const cachedId of this.lastGood.keys()) {\n if (!seenIds.has(cachedId)) this.lastGood.delete(cachedId)\n }\n\n return out\n }\n\n // ── Retry on transient Moleculer race ─────────────────────────────\n\n private scheduleRetry(sourceId: string, attempt = 0): void {\n if (attempt >= RETRY_BACKOFF_MS.length) return\n if (this.retryTimers.has(sourceId)) return // already pending\n\n const delayMs = RETRY_BACKOFF_MS[attempt] ?? RETRY_BACKOFF_MS[RETRY_BACKOFF_MS.length - 1]!\n const timer = setTimeout(() => {\n this.retryTimers.delete(sourceId)\n void this.retrySource(sourceId, attempt)\n }, delayMs)\n this.retryTimers.set(sourceId, timer)\n }\n\n private async retrySource(sourceId: string, attempt: number): Promise<void> {\n const entries = this.capabilities?.getCollectionEntries<IAddonWidgetsSourceProvider>('addon-widgets-source') ?? []\n const found = entries.find(([id]) => id === sourceId)\n if (!found) return // provider went away; nothing to retry\n const [addonId, source] = found\n\n try {\n const widgets = await Promise.resolve(source.listWidgets())\n const enriched: EnrichedWidget[] = widgets.map((w: RawWidget) => ({\n ...w,\n addonId,\n bundleUrl: this.makeBundleUrl(addonId, w.bundle),\n }))\n this.lastGood.set(addonId, enriched)\n this.ctx.logger.info('addon-widgets-source recovered after retry', {\n meta: { sourceId: addonId, attempt: attempt + 1, widgets: enriched.length },\n })\n // Re-emit AddonWidgetReady so admin-ui invalidates and refetches.\n this.ctx.eventBus.emit({\n id: randomUUID(),\n timestamp: new Date(),\n source: { type: 'addon', id: this.id },\n category: EventCategory.AddonWidgetReady,\n data: { addonId, recovered: true },\n })\n } catch (err: unknown) {\n this.ctx.logger.debug('addon-widgets-source retry failed', {\n meta: { sourceId, attempt: attempt + 1, error: errMsg(err) },\n })\n this.scheduleRetry(sourceId, attempt + 1)\n }\n }\n\n // ── Bundle URL stamping ──────────────────────────────────────────\n\n /**\n * Build `/api/addon-widgets/<addonId>/<bundle>?v=<mtime>`. Falls back\n * to `Date.now()` when the bundle path can't be stat'd (remote addon\n * with no local file, addon not yet on disk, etc.) — the browser\n * just gets a fresh URL on each call instead of cache-friendly mtime.\n */\n private makeBundleUrl(addonId: string, bundle: string): string {\n const bundlePath = this.resolveBundlePath(addonId, bundle)\n let mtime = Date.now()\n if (bundlePath !== null) {\n try { mtime = fs.statSync(bundlePath).mtimeMs }\n catch { /* remote addon — no local file */ }\n }\n const v = Math.floor(mtime)\n return `/api/addon-widgets/${addonId}/${bundle}?v=${v}`\n }\n\n private resolveBundlePath(addonId: string, bundle: string): string | null {\n const paths = this.resolvedPaths\n if (!paths) return null\n const addonDistPath = path.join(paths.addonsDir, '@camstack', `addon-${addonId}`, 'dist')\n const resolvedBase = path.resolve(addonDistPath)\n const resolvedFile = path.resolve(addonDistPath, bundle)\n if (!resolvedFile.startsWith(resolvedBase + path.sep) && resolvedFile !== resolvedBase) {\n return null\n }\n return resolvedFile\n }\n\n // ── Path resolution ──────────────────────────────────────────────\n\n private async resolvePaths(): Promise<ResolvedPaths> {\n const fallback: ResolvedPaths = { addonsDir: path.resolve('camstack-data', 'addons') }\n if (!this.ctx.settings) return fallback\n try {\n const server = await this.ctx.settings.getSection('server')\n const dataPath = typeof server['dataPath'] === 'string' && server['dataPath']\n ? server['dataPath']\n : 'camstack-data'\n return { addonsDir: path.resolve(dataPath, 'addons') }\n } catch (err: unknown) {\n this.ctx.logger.debug('Failed to read server.dataPath — falling back', {\n meta: { error: errMsg(err) },\n })\n return fallback\n }\n }\n}\n\nexport default AddonWidgetsAggregatorAddon\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/builtins/alerts/index.ts","../../../src/builtins/alerts/alerts.addon.ts"],"sourcesContent":["export { AlertCenterAddon } from './alerts.addon.js'\n","import {\n EventCategory,\n type KnownEventCategory,\n type SystemEvent,\n type ProviderRegistration,\n} from '@camstack/types'\nimport type { Alert, AlertSeverity, AlertStatus } from '@camstack/types'\nimport { BaseAddon, AlertSchema, alertsCapability, createEvent , errMsg } from '@camstack/types'\n\n// ── Category → severity mapping ─────────────────────────────────────\n\ninterface CategoryMapping {\n readonly severity: AlertSeverity\n readonly titleTemplate: string\n}\n\nconst CATEGORY_MAPPINGS: Readonly<Record<string, CategoryMapping>> = {\n // ── Critical — always surface ──────────────────────────────────────\n 'addon.crashed': { severity: 'error', titleTemplate: 'Addon crashed' },\n 'addon.error': { severity: 'error', titleTemplate: 'Addon error' },\n 'process.crashed': { severity: 'error', titleTemplate: 'Process crashed' },\n 'recording.error': { severity: 'error', titleTemplate: 'Recording error' },\n 'recording.storage.critical': { severity: 'warning', titleTemplate: 'Storage critical' },\n 'notification.failed': { severity: 'error', titleTemplate: 'Notification failed' },\n\n // ── Cluster — agent connect/disconnect ─────────────────────────────\n 'agent.online': { severity: 'info', titleTemplate: 'Agent connected' },\n 'agent.offline': { severity: 'warning', titleTemplate: 'Agent disconnected' },\n\n // ── System lifecycle ──────────────────────────────────────────────\n 'system.boot': { severity: 'info', titleTemplate: 'System boot' },\n 'system.restarting': { severity: 'warning', titleTemplate: 'System restarting' },\n\n // ── Device lifecycle (add/remove only, not settings tweaks) ───────\n 'device.registered': { severity: 'info', titleTemplate: 'Device registered' },\n 'device.unregistered': { severity: 'warning', titleTemplate: 'Device unregistered' },\n\n // ── Package management ────────────────────────────────────────────\n 'addon.installed': { severity: 'info', titleTemplate: 'Addon installed' },\n 'addon.updated': { severity: 'info', titleTemplate: 'Addon updated' },\n 'addon.uninstalled': { severity: 'info', titleTemplate: 'Addon uninstalled' },\n\n // ── Backup (rare, important) ──────────────────────────────────────\n 'backup.completed': { severity: 'info', titleTemplate: 'Backup completed' },\n 'backup.restored': { severity: 'info', titleTemplate: 'Backup restored' },\n\n // ── Model downloads (in-progress merging path) ────────────────────\n 'model.download.progress': { severity: 'info', titleTemplate: 'Model download' },\n}\n\nconst TRACKED_CATEGORIES = Object.keys(CATEGORY_MAPPINGS)\n\n/**\n * `[ALERT-CENTER-EVENTS]` — rate limiting. Events that fire thousands of\n * times a minute (flaky cam reconnecting, chatty integration, …) would\n * flood the alert feed and push genuinely important alerts off the\n * visible page. We collapse bursts into a single throttled summary per\n * `(category, source.id)` tuple: the first N events within the window\n * still surface as individual alerts, but once the source crosses the\n * threshold we stop emitting alerts for it and wait out the window.\n *\n * A standalone category-count map is cleared on every window rollover.\n * Keep the threshold generous enough that legitimate bursts of ~a few\n * per minute still get through, but strict enough that a reconnect loop\n * firing every second gets muted.\n */\nconst RATE_LIMIT_WINDOW_MS = 60_000\nconst RATE_LIMIT_MAX_PER_SOURCE = 5\n\n/** Parse a raw settings record into a validated Alert. */\nfunction parseAlert(record: { id: string; data: Record<string, unknown> }): Alert {\n return AlertSchema.parse({ id: record.id, ...record.data })\n}\n\n// ── Alert Center Addon ─────────────────────────────────────────────\n\ninterface AlertCenterConfig {\n readonly maxAlerts: number\n readonly retentionDays: number\n}\n\nconst DEFAULT_CONFIG: AlertCenterConfig = {\n maxAlerts: 500,\n retentionDays: 30,\n}\n\nconst ALERTS_COLLECTION = 'alerts'\nconst EVENT_SOURCE = { type: 'addon', id: 'alert-center' } as const\n\n/**\n * Alert Center addon — core builtin that persists alerts in a\n * structured SQLite table and serves them to the admin UI.\n *\n * Registers as an `alerts` collection provider and subscribes to\n * important EventBus categories to create/update alerts automatically.\n */\nexport class AlertCenterAddon extends BaseAddon<AlertCenterConfig> {\n private unsubscribers: readonly (() => void)[] = []\n\n constructor() {\n super({ ...DEFAULT_CONFIG })\n }\n\n /**\n * Per `(category, source.id)` counter used to rate-limit chatty\n * events. Entries are pruned lazily when they age out of\n * `RATE_LIMIT_WINDOW_MS`; see `shouldSuppressByRate()` below.\n */\n private readonly rateLimitCounters = new Map<string, { firstAt: number; count: number; suppressedLogged: boolean }>()\n\n protected async onInitialize(): Promise<ProviderRegistration[]> {\n const alertsProvider = {\n emit: (alert: Alert) => this.emitAlert(alert),\n update: (input: { alertId: string; patch: Partial<Alert> }) =>\n this.updateAlert(input.alertId, input.patch),\n list: (filter?: { unreadOnly?: boolean; limit?: number }) =>\n this.listAlerts(filter),\n getUnreadCount: () => this.getUnreadCount(),\n markRead: (input: { alertId: string }) => this.markRead(input.alertId),\n markAllRead: () => this.markAllRead(),\n dismiss: (input: { alertId: string }) => this.dismiss(input.alertId),\n }\n\n const unsubs: (() => void)[] = []\n for (const category of TRACKED_CATEGORIES) {\n const unsub = this.ctx.eventBus.subscribe(\n { category: category as KnownEventCategory },\n (event: SystemEvent) => { void this.handleEvent(category, event) },\n )\n unsubs.push(unsub)\n }\n this.unsubscribers = unsubs\n\n this.ctx.logger.info('Initialized', { meta: { trackedCategoriesCount: TRACKED_CATEGORIES.length } })\n return [{ capability: alertsCapability, provider: alertsProvider }]\n }\n\n protected async onShutdown(): Promise<void> {\n for (const unsub of this.unsubscribers) {\n unsub()\n }\n this.unsubscribers = []\n }\n\n protected globalSettingsSchema() {\n return this.schema({\n sections: [{\n id: 'alerts',\n title: 'Alert Center',\n description: 'Configure alert storage and retention.',\n columns: 1,\n fields: [\n this.field({\n type: 'number', key: 'maxAlerts', label: 'Maximum stored alerts',\n description: 'Oldest read alerts are deleted when this limit is exceeded.',\n min: 50, max: 5000, step: 50, default: 500,\n }),\n this.field({\n type: 'number', key: 'retentionDays', label: 'Alert retention (days)',\n description: 'Alerts older than this are automatically removed.',\n min: 1, max: 365, step: 1, default: 30,\n }),\n ],\n }],\n })\n }\n\n // ── Public methods (called by the tRPC router) ────────────────────\n\n async listAlerts(filter?: { unreadOnly?: boolean; limit?: number }): Promise<readonly Alert[]> {\n const backend = this.ctx.api.settingsStore\n if (!backend) return []\n\n const whereClause: Record<string, unknown> = {}\n if (filter?.unreadOnly) {\n whereClause.read = false\n }\n\n const records = await backend.query.query({ collection: ALERTS_COLLECTION, filter: {\n where: Object.keys(whereClause).length > 0 ? whereClause : undefined,\n orderBy: { field: 'updatedAt', direction: 'desc' },\n limit: filter?.limit ?? 100,\n } })\n\n return records.map(parseAlert)\n }\n\n async getUnreadCount(): Promise<number> {\n const backend = this.ctx.api.settingsStore\n if (!backend) return 0\n\n return backend.count.query({ collection: ALERTS_COLLECTION, filter: { where: { read: false } } })\n }\n\n async markRead(alertId: string): Promise<void> {\n await this.mergeUpdate(alertId, { read: true, updatedAt: Date.now() })\n }\n\n async markAllRead(): Promise<void> {\n const backend = this.ctx.api.settingsStore\n if (!backend) return\n\n const unread = await backend.query.query({ collection: ALERTS_COLLECTION, filter: { where: { read: false } } })\n const now = Date.now()\n for (const record of unread) {\n await this.mergeUpdate(record.id, { read: true, updatedAt: now })\n }\n }\n\n async dismiss(alertId: string): Promise<void> {\n await this.mergeUpdate(alertId, {\n status: 'dismissed' satisfies AlertStatus,\n read: true,\n updatedAt: Date.now(),\n })\n }\n\n // ── Private: event handling ──────────────────────────────────────\n\n private async handleEvent(category: string, event: SystemEvent): Promise<void> {\n try {\n if (category === 'model.download.progress') {\n // Model download progress has its own in-progress merging path\n // that intentionally overwrites a single alert per model, so\n // rate limiting does not apply here — the merger itself is the\n // collapse mechanism.\n await this.handleModelDownload(event)\n return\n }\n\n const mapping = CATEGORY_MAPPINGS[category]\n if (!mapping) return\n\n if (this.shouldSuppressByRate(category, event)) return\n\n const message = this.buildMessage(category, event.data)\n const alert: Alert = {\n id: crypto.randomUUID(),\n category,\n severity: mapping.severity,\n title: mapping.titleTemplate,\n message,\n status: 'active',\n read: false,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n source: event.source ? { type: event.source.type, id: String(event.source.id) } : undefined,\n metadata: event.data,\n }\n\n await this.emitAlert(alert)\n } catch (err) {\n this.ctx.logger?.warn(\n 'Failed to handle event',\n { meta: { category, error: errMsg(err) } },\n )\n }\n }\n\n private async handleModelDownload(event: SystemEvent): Promise<void> {\n const data = event.data\n const modelId = (data.modelId as string | undefined) ?? 'unknown'\n const progress = (data.progress as number | undefined) ?? 0\n const stableId = `model-download:${modelId}`\n\n const backend = this.ctx.api.settingsStore\n if (!backend) return\n\n // Check if an in-progress alert already exists for this model\n const existing = await backend.query.query({ collection: ALERTS_COLLECTION, filter: {\n where: { id: stableId },\n } })\n\n if (existing.length > 0) {\n // Update existing alert (read-merge-write)\n const now = Date.now()\n if (progress >= 100) {\n await this.mergeUpdate(stableId, {\n status: 'completed' satisfies AlertStatus,\n progress: 100,\n message: `Model \"${modelId}\" download completed`,\n updatedAt: now,\n })\n this.emitAlertUpdatedEvent(stableId, { status: 'completed', progress: 100 })\n } else if (progress < 0) {\n await this.mergeUpdate(stableId, {\n status: 'failed' satisfies AlertStatus,\n message: `Model \"${modelId}\" download failed`,\n updatedAt: now,\n })\n this.emitAlertUpdatedEvent(stableId, { status: 'failed' })\n } else {\n await this.mergeUpdate(stableId, {\n progress,\n message: `Downloading model \"${modelId}\" — ${String(Math.round(progress))}%`,\n updatedAt: now,\n })\n this.emitAlertUpdatedEvent(stableId, { progress })\n }\n } else {\n // Create new in-progress alert\n const alert: Alert = {\n id: stableId,\n category: EventCategory.ModelDownloadProgress,\n severity: 'info',\n title: 'Model download',\n message: `Downloading model \"${modelId}\" — ${String(Math.round(progress))}%`,\n status: 'in-progress',\n progress,\n read: false,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n source: event.source ? { type: event.source.type, id: String(event.source.id) } : undefined,\n metadata: { modelId },\n }\n\n await this.persistAlert(alert)\n this.emitAlertCreatedEvent(alert)\n }\n }\n\n /**\n * `[ALERT-CENTER-EVENTS]` — rate limit a `(category, source.id)`\n * tuple. Returns `true` when the caller should DROP this event\n * without persisting an alert, and `false` when the alert should\n * proceed normally.\n *\n * Heuristic: the first `RATE_LIMIT_MAX_PER_SOURCE` events within a\n * `RATE_LIMIT_WINDOW_MS` window go through. Once the threshold is\n * crossed, subsequent events are suppressed until the window rolls\n * over. When the threshold is first crossed, the suppression is\n * logged once so operators know why they're not seeing the follow-\n * up alerts; after the window rolls over the next event is\n * un-suppressed and starts a new window.\n */\n private shouldSuppressByRate(category: string, event: SystemEvent): boolean {\n const sourceId = event.source?.id ?? 'unknown'\n const key = `${category}::${sourceId}`\n const now = Date.now()\n const entry = this.rateLimitCounters.get(key)\n\n if (!entry || now - entry.firstAt > RATE_LIMIT_WINDOW_MS) {\n // First event of a new window — always allow, start the counter.\n this.rateLimitCounters.set(key, { firstAt: now, count: 1, suppressedLogged: false })\n return false\n }\n\n entry.count += 1\n if (entry.count <= RATE_LIMIT_MAX_PER_SOURCE) return false\n\n // Over threshold — suppress the rest of this window.\n if (!entry.suppressedLogged) {\n entry.suppressedLogged = true\n this.ctx.logger?.info(\n 'rate-limiting suppressing remainder of window',\n { meta: { category, sourceId, maxPerSource: RATE_LIMIT_MAX_PER_SOURCE, windowSeconds: RATE_LIMIT_WINDOW_MS / 1000 } },\n )\n }\n return true\n }\n\n private buildMessage(category: string, data: Record<string, unknown>): string {\n const addonId = data.addonId as string | undefined\n const deviceId = data.deviceId as string | undefined\n const error = data.error as string | undefined\n const processId = data.processId as string | undefined\n\n switch (category) {\n case 'addon.crashed':\n return `Addon \"${addonId ?? 'unknown'}\" crashed${error ? `: ${error}` : ''}`\n case 'addon.error':\n return `Addon \"${addonId ?? 'unknown'}\" error${error ? `: ${error}` : ''}`\n case 'addon.installed':\n return `Addon \"${addonId ?? 'unknown'}\" installed`\n case 'addon.updated': {\n const from = data.fromVersion as string | undefined\n const to = data.toVersion as string | undefined\n return `Addon \"${addonId ?? 'unknown'}\" updated${from && to ? ` from ${from} to ${to}` : ''}`\n }\n case 'addon.uninstalled':\n return `Addon \"${addonId ?? 'unknown'}\" uninstalled`\n case 'device.registered':\n return `Device \"${data.name as string | undefined ?? deviceId ?? 'unknown'}\" registered`\n case 'device.unregistered':\n return `Device \"${deviceId ?? 'unknown'}\" unregistered`\n case 'agent.online':\n return `Agent \"${data.agentId as string | undefined ?? data.nodeId as string | undefined ?? 'unknown'}\" connected`\n case 'agent.offline':\n return `Agent \"${data.agentId as string | undefined ?? data.nodeId as string | undefined ?? 'unknown'}\" disconnected${data.reason ? `: ${String(data.reason)}` : ''}`\n case 'backup.completed':\n return `Backup completed${data.targetId ? ` (${String(data.targetId)})` : ''}`\n case 'backup.restored':\n return `Backup restored${data.source ? ` from ${String(data.source)}` : ''}`\n case 'notification.failed':\n return `Notification failed${error ? `: ${error}` : ''}`\n case 'system.restarting':\n return `System restarting${data.reason ? ` — ${String(data.reason)}` : ''}`\n case 'recording.error':\n return `Recording error on device \"${deviceId ?? 'unknown'}\"${error ? `: ${error}` : ''}`\n case 'recording.storage.critical':\n return `Storage critical for device \"${deviceId ?? 'unknown'}\"`\n case 'system.boot':\n return `System booted in \"${data.mode as string | undefined ?? 'unknown'}\" mode`\n case 'process.crashed':\n return `Process \"${processId ?? 'unknown'}\" crashed`\n default:\n return `Event: ${category}`\n }\n }\n\n // ── Private: persistence ─────────────────────────────────────────\n\n private async emitAlert(alert: Alert): Promise<void> {\n await this.persistAlert(alert)\n this.emitAlertCreatedEvent(alert)\n await this.enforceMaxAlerts()\n await this.enforceRetention()\n }\n\n private async updateAlert(alertId: string, patch: Partial<Alert>): Promise<void> {\n await this.mergeUpdate(alertId, { ...patch, updatedAt: Date.now() })\n this.emitAlertUpdatedEvent(alertId, patch)\n }\n\n /**\n * Read-merge-write: SettingsBackend.update() replaces the entire `data` blob,\n * so we must read the existing record, merge the patch, and write back.\n */\n private async mergeUpdate(id: string, patch: Record<string, unknown>): Promise<void> {\n const backend = this.ctx.api.settingsStore\n if (!backend) return\n\n const raw = await backend.get.query({ collection: ALERTS_COLLECTION, key: id })\n if (raw === null || raw === undefined || typeof raw !== 'object') return\n const existing: Record<string, unknown> = Object.fromEntries(Object.entries(raw))\n await backend.set.mutate({ collection: ALERTS_COLLECTION, key: id, value: { ...existing, ...patch } })\n }\n\n private async persistAlert(alert: Alert): Promise<void> {\n const backend = this.ctx.api.settingsStore\n if (!backend) return\n\n // Serialize alert to a plain Record for SQLite JSON storage\n const data: Record<string, unknown> = {\n id: alert.id,\n category: alert.category,\n severity: alert.severity,\n title: alert.title,\n message: alert.message,\n status: alert.status,\n read: alert.read,\n createdAt: alert.createdAt,\n updatedAt: alert.updatedAt,\n ...(alert.progress !== undefined ? { progress: alert.progress } : {}),\n ...(alert.source ? { source: alert.source } : {}),\n ...(alert.metadata ? { metadata: alert.metadata } : {}),\n }\n await backend.set.mutate({ collection: ALERTS_COLLECTION, key: alert.id, value: data })\n }\n\n private emitAlertCreatedEvent(alert: Alert): void {\n this.ctx.eventBus?.emit(createEvent('alert.created', EVENT_SOURCE, {\n id: alert.id,\n category: alert.category,\n severity: alert.severity,\n title: alert.title,\n status: alert.status,\n }))\n }\n\n private emitAlertUpdatedEvent(alertId: string, patch: Partial<Alert>): void {\n const patchRecord: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(patch)) {\n patchRecord[key] = value\n }\n this.ctx.eventBus?.emit(createEvent('alert.updated', EVENT_SOURCE, {\n alertId,\n patch: patchRecord,\n }))\n }\n\n private async enforceMaxAlerts(): Promise<void> {\n const backend = this.ctx.api.settingsStore\n if (!backend) return\n\n const total = await backend.count.query({ collection: ALERTS_COLLECTION })\n if (total <= this.config.maxAlerts) return\n\n // Delete oldest read alerts\n const excess = total - this.config.maxAlerts\n const oldest = await backend.query.query({ collection: ALERTS_COLLECTION, filter: {\n where: { read: true },\n orderBy: { field: 'createdAt', direction: 'asc' },\n limit: excess,\n } })\n\n for (const record of oldest) {\n await backend.delete.mutate({ collection: ALERTS_COLLECTION, key: record.id })\n }\n }\n\n private async enforceRetention(): Promise<void> {\n const backend = this.ctx.api.settingsStore\n if (!backend) return\n\n const cutoff = Date.now() - this.config.retentionDays * 24 * 60 * 60 * 1000\n const expired = await backend.query.query({ collection: ALERTS_COLLECTION, filter: {\n where: { read: true },\n orderBy: { field: 'createdAt', direction: 'asc' },\n } })\n\n for (const record of expired) {\n if (Number(record.data['createdAt'] ?? 0) < cutoff) {\n await backend.delete.mutate({ collection: ALERTS_COLLECTION, key: record.id })\n }\n }\n }\n}\n\nexport default AlertCenterAddon\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAKO;AAEP,IAAAA,gBAA+E;AAS/E,IAAM,oBAA+D;AAAA;AAAA,EAEnE,iBAAgC,EAAE,UAAU,SAAW,eAAe,gBAAgB;AAAA,EACtF,eAAgC,EAAE,UAAU,SAAW,eAAe,cAAc;AAAA,EACpF,mBAAgC,EAAE,UAAU,SAAW,eAAe,kBAAkB;AAAA,EACxF,mBAAgC,EAAE,UAAU,SAAW,eAAe,kBAAkB;AAAA,EACxF,8BAAgC,EAAE,UAAU,WAAW,eAAe,mBAAmB;AAAA,EACzF,uBAAgC,EAAE,UAAU,SAAW,eAAe,sBAAsB;AAAA;AAAA,EAG5F,gBAAgC,EAAE,UAAU,QAAW,eAAe,kBAAkB;AAAA,EACxF,iBAAgC,EAAE,UAAU,WAAW,eAAe,qBAAqB;AAAA;AAAA,EAG3F,eAAgC,EAAE,UAAU,QAAW,eAAe,cAAc;AAAA,EACpF,qBAAgC,EAAE,UAAU,WAAW,eAAe,oBAAoB;AAAA;AAAA,EAG1F,qBAAgC,EAAE,UAAU,QAAW,eAAe,oBAAoB;AAAA,EAC1F,uBAAgC,EAAE,UAAU,WAAW,eAAe,sBAAsB;AAAA;AAAA,EAG5F,mBAAgC,EAAE,UAAU,QAAW,eAAe,kBAAkB;AAAA,EACxF,iBAAgC,EAAE,UAAU,QAAW,eAAe,gBAAgB;AAAA,EACtF,qBAAgC,EAAE,UAAU,QAAW,eAAe,oBAAoB;AAAA;AAAA,EAG1F,oBAAgC,EAAE,UAAU,QAAW,eAAe,mBAAmB;AAAA,EACzF,mBAAgC,EAAE,UAAU,QAAW,eAAe,kBAAkB;AAAA;AAAA,EAGxF,2BAAgC,EAAE,UAAU,QAAW,eAAe,iBAAiB;AACzF;AAEA,IAAM,qBAAqB,OAAO,KAAK,iBAAiB;AAgBxD,IAAM,uBAAuB;AAC7B,IAAM,4BAA4B;AAGlC,SAAS,WAAW,QAA8D;AAChF,SAAO,0BAAY,MAAM,EAAE,IAAI,OAAO,IAAI,GAAG,OAAO,KAAK,CAAC;AAC5D;AASA,IAAM,iBAAoC;AAAA,EACxC,WAAW;AAAA,EACX,eAAe;AACjB;AAEA,IAAM,oBAAoB;AAC1B,IAAM,eAAe,EAAE,MAAM,SAAS,IAAI,eAAe;AASlD,IAAM,mBAAN,cAA+B,wBAA6B;AAAA,EACzD,gBAAyC,CAAC;AAAA,EAElD,cAAc;AACZ,UAAM,EAAE,GAAG,eAAe,CAAC;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOiB,oBAAoB,oBAAI,IAA2E;AAAA,EAEpH,MAAgB,eAAgD;AAC9D,UAAM,iBAAiB;AAAA,MACrB,MAAM,CAAC,UAAiB,KAAK,UAAU,KAAK;AAAA,MAC5C,QAAQ,CAAC,UACP,KAAK,YAAY,MAAM,SAAS,MAAM,KAAK;AAAA,MAC7C,MAAM,CAAC,WACL,KAAK,WAAW,MAAM;AAAA,MACxB,gBAAgB,MAAM,KAAK,eAAe;AAAA,MAC1C,UAAU,CAAC,UAA+B,KAAK,SAAS,MAAM,OAAO;AAAA,MACrE,aAAa,MAAM,KAAK,YAAY;AAAA,MACpC,SAAS,CAAC,UAA+B,KAAK,QAAQ,MAAM,OAAO;AAAA,IACrE;AAEA,UAAM,SAAyB,CAAC;AAChC,eAAW,YAAY,oBAAoB;AACzC,YAAM,QAAQ,KAAK,IAAI,SAAS;AAAA,QAC9B,EAAE,SAAyC;AAAA,QAC3C,CAAC,UAAuB;AAAE,eAAK,KAAK,YAAY,UAAU,KAAK;AAAA,QAAE;AAAA,MACnE;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,SAAK,gBAAgB;AAErB,SAAK,IAAI,OAAO,KAAK,eAAe,EAAE,MAAM,EAAE,wBAAwB,mBAAmB,OAAO,EAAE,CAAC;AACnG,WAAO,CAAC,EAAE,YAAY,gCAAkB,UAAU,eAAe,CAAC;AAAA,EACpE;AAAA,EAEA,MAAgB,aAA4B;AAC1C,eAAW,SAAS,KAAK,eAAe;AACtC,YAAM;AAAA,IACR;AACA,SAAK,gBAAgB,CAAC;AAAA,EACxB;AAAA,EAEU,uBAAuB;AAC/B,WAAO,KAAK,OAAO;AAAA,MACjB,UAAU,CAAC;AAAA,QACT,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,SAAS;AAAA,QACT,QAAQ;AAAA,UACN,KAAK,MAAM;AAAA,YACT,MAAM;AAAA,YAAU,KAAK;AAAA,YAAa,OAAO;AAAA,YACzC,aAAa;AAAA,YACb,KAAK;AAAA,YAAI,KAAK;AAAA,YAAM,MAAM;AAAA,YAAI,SAAS;AAAA,UACzC,CAAC;AAAA,UACD,KAAK,MAAM;AAAA,YACT,MAAM;AAAA,YAAU,KAAK;AAAA,YAAiB,OAAO;AAAA,YAC7C,aAAa;AAAA,YACb,KAAK;AAAA,YAAG,KAAK;AAAA,YAAK,MAAM;AAAA,YAAG,SAAS;AAAA,UACtC,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,MAAM,WAAW,QAA8E;AAC7F,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,UAAM,cAAuC,CAAC;AAC9C,QAAI,QAAQ,YAAY;AACtB,kBAAY,OAAO;AAAA,IACrB;AAEA,UAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,EAAE,YAAY,mBAAmB,QAAQ;AAAA,MACjF,OAAO,OAAO,KAAK,WAAW,EAAE,SAAS,IAAI,cAAc;AAAA,MAC3D,SAAS,EAAE,OAAO,aAAa,WAAW,OAAO;AAAA,MACjD,OAAO,QAAQ,SAAS;AAAA,IAC1B,EAAE,CAAC;AAEH,WAAO,QAAQ,IAAI,UAAU;AAAA,EAC/B;AAAA,EAEA,MAAM,iBAAkC;AACtC,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAI,CAAC,QAAS,QAAO;AAErB,WAAO,QAAQ,MAAM,MAAM,EAAE,YAAY,mBAAmB,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,EAAE,EAAE,CAAC;AAAA,EAClG;AAAA,EAEA,MAAM,SAAS,SAAgC;AAC7C,UAAM,KAAK,YAAY,SAAS,EAAE,MAAM,MAAM,WAAW,KAAK,IAAI,EAAE,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,cAA6B;AACjC,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAI,CAAC,QAAS;AAEd,UAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,EAAE,YAAY,mBAAmB,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,EAAE,EAAE,CAAC;AAC9G,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,UAAU,QAAQ;AAC3B,YAAM,KAAK,YAAY,OAAO,IAAI,EAAE,MAAM,MAAM,WAAW,IAAI,CAAC;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,SAAgC;AAC5C,UAAM,KAAK,YAAY,SAAS;AAAA,MAC9B,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,WAAW,KAAK,IAAI;AAAA,IACtB,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,MAAc,YAAY,UAAkB,OAAmC;AAC7E,QAAI;AACF,UAAI,aAAa,2BAA2B;AAK1C,cAAM,KAAK,oBAAoB,KAAK;AACpC;AAAA,MACF;AAEA,YAAM,UAAU,kBAAkB,QAAQ;AAC1C,UAAI,CAAC,QAAS;AAEd,UAAI,KAAK,qBAAqB,UAAU,KAAK,EAAG;AAEhD,YAAM,UAAU,KAAK,aAAa,UAAU,MAAM,IAAI;AACtD,YAAM,QAAe;AAAA,QACnB,IAAI,OAAO,WAAW;AAAA,QACtB;AAAA,QACA,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,WAAW,KAAK,IAAI;AAAA,QACpB,WAAW,KAAK,IAAI;AAAA,QACpB,QAAQ,MAAM,SAAS,EAAE,MAAM,MAAM,OAAO,MAAM,IAAI,OAAO,MAAM,OAAO,EAAE,EAAE,IAAI;AAAA,QAClF,UAAU,MAAM;AAAA,MAClB;AAEA,YAAM,KAAK,UAAU,KAAK;AAAA,IAC5B,SAAS,KAAK;AACZ,WAAK,IAAI,QAAQ;AAAA,QACf;AAAA,QACA,EAAE,MAAM,EAAE,UAAU,WAAO,sBAAO,GAAG,EAAE,EAAE;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,OAAmC;AACnE,UAAM,OAAO,MAAM;AACnB,UAAM,UAAW,KAAK,WAAkC;AACxD,UAAM,WAAY,KAAK,YAAmC;AAC1D,UAAM,WAAW,kBAAkB,OAAO;AAE1C,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAI,CAAC,QAAS;AAGd,UAAM,WAAW,MAAM,QAAQ,MAAM,MAAM,EAAE,YAAY,mBAAmB,QAAQ;AAAA,MAClF,OAAO,EAAE,IAAI,SAAS;AAAA,IACxB,EAAE,CAAC;AAEH,QAAI,SAAS,SAAS,GAAG;AAEvB,YAAM,MAAM,KAAK,IAAI;AACrB,UAAI,YAAY,KAAK;AACnB,cAAM,KAAK,YAAY,UAAU;AAAA,UAC/B,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,SAAS,UAAU,OAAO;AAAA,UAC1B,WAAW;AAAA,QACb,CAAC;AACD,aAAK,sBAAsB,UAAU,EAAE,QAAQ,aAAa,UAAU,IAAI,CAAC;AAAA,MAC7E,WAAW,WAAW,GAAG;AACvB,cAAM,KAAK,YAAY,UAAU;AAAA,UAC/B,QAAQ;AAAA,UACR,SAAS,UAAU,OAAO;AAAA,UAC1B,WAAW;AAAA,QACb,CAAC;AACD,aAAK,sBAAsB,UAAU,EAAE,QAAQ,SAAS,CAAC;AAAA,MAC3D,OAAO;AACL,cAAM,KAAK,YAAY,UAAU;AAAA,UAC/B;AAAA,UACA,SAAS,sBAAsB,OAAO,YAAO,OAAO,KAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,UACzE,WAAW;AAAA,QACb,CAAC;AACD,aAAK,sBAAsB,UAAU,EAAE,SAAS,CAAC;AAAA,MACnD;AAAA,IACF,OAAO;AAEL,YAAM,QAAe;AAAA,QACnB,IAAI;AAAA,QACJ,UAAU,2BAAc;AAAA,QACxB,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS,sBAAsB,OAAO,YAAO,OAAO,KAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,QACzE,QAAQ;AAAA,QACR;AAAA,QACA,MAAM;AAAA,QACN,WAAW,KAAK,IAAI;AAAA,QACpB,WAAW,KAAK,IAAI;AAAA,QACpB,QAAQ,MAAM,SAAS,EAAE,MAAM,MAAM,OAAO,MAAM,IAAI,OAAO,MAAM,OAAO,EAAE,EAAE,IAAI;AAAA,QAClF,UAAU,EAAE,QAAQ;AAAA,MACtB;AAEA,YAAM,KAAK,aAAa,KAAK;AAC7B,WAAK,sBAAsB,KAAK;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBQ,qBAAqB,UAAkB,OAA6B;AAC1E,UAAM,WAAW,MAAM,QAAQ,MAAM;AACrC,UAAM,MAAM,GAAG,QAAQ,KAAK,QAAQ;AACpC,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,QAAQ,KAAK,kBAAkB,IAAI,GAAG;AAE5C,QAAI,CAAC,SAAS,MAAM,MAAM,UAAU,sBAAsB;AAExD,WAAK,kBAAkB,IAAI,KAAK,EAAE,SAAS,KAAK,OAAO,GAAG,kBAAkB,MAAM,CAAC;AACnF,aAAO;AAAA,IACT;AAEA,UAAM,SAAS;AACf,QAAI,MAAM,SAAS,0BAA2B,QAAO;AAGrD,QAAI,CAAC,MAAM,kBAAkB;AAC3B,YAAM,mBAAmB;AACzB,WAAK,IAAI,QAAQ;AAAA,QACf;AAAA,QACA,EAAE,MAAM,EAAE,UAAU,UAAU,cAAc,2BAA2B,eAAe,uBAAuB,IAAK,EAAE;AAAA,MACtH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,UAAkB,MAAuC;AAC5E,UAAM,UAAU,KAAK;AACrB,UAAM,WAAW,KAAK;AACtB,UAAM,QAAQ,KAAK;AACnB,UAAM,YAAY,KAAK;AAEvB,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,eAAO,UAAU,WAAW,SAAS,YAAY,QAAQ,KAAK,KAAK,KAAK,EAAE;AAAA,MAC5E,KAAK;AACH,eAAO,UAAU,WAAW,SAAS,UAAU,QAAQ,KAAK,KAAK,KAAK,EAAE;AAAA,MAC1E,KAAK;AACH,eAAO,UAAU,WAAW,SAAS;AAAA,MACvC,KAAK,iBAAiB;AACpB,cAAM,OAAO,KAAK;AAClB,cAAM,KAAK,KAAK;AAChB,eAAO,UAAU,WAAW,SAAS,YAAY,QAAQ,KAAK,SAAS,IAAI,OAAO,EAAE,KAAK,EAAE;AAAA,MAC7F;AAAA,MACA,KAAK;AACH,eAAO,UAAU,WAAW,SAAS;AAAA,MACvC,KAAK;AACH,eAAO,WAAW,KAAK,QAA8B,YAAY,SAAS;AAAA,MAC5E,KAAK;AACH,eAAO,WAAW,YAAY,SAAS;AAAA,MACzC,KAAK;AACH,eAAO,UAAU,KAAK,WAAiC,KAAK,UAAgC,SAAS;AAAA,MACvG,KAAK;AACH,eAAO,UAAU,KAAK,WAAiC,KAAK,UAAgC,SAAS,iBAAiB,KAAK,SAAS,KAAK,OAAO,KAAK,MAAM,CAAC,KAAK,EAAE;AAAA,MACrK,KAAK;AACH,eAAO,mBAAmB,KAAK,WAAW,KAAK,OAAO,KAAK,QAAQ,CAAC,MAAM,EAAE;AAAA,MAC9E,KAAK;AACH,eAAO,kBAAkB,KAAK,SAAS,SAAS,OAAO,KAAK,MAAM,CAAC,KAAK,EAAE;AAAA,MAC5E,KAAK;AACH,eAAO,sBAAsB,QAAQ,KAAK,KAAK,KAAK,EAAE;AAAA,MACxD,KAAK;AACH,eAAO,oBAAoB,KAAK,SAAS,WAAM,OAAO,KAAK,MAAM,CAAC,KAAK,EAAE;AAAA,MAC3E,KAAK;AACH,eAAO,8BAA8B,YAAY,SAAS,IAAI,QAAQ,KAAK,KAAK,KAAK,EAAE;AAAA,MACzF,KAAK;AACH,eAAO,gCAAgC,YAAY,SAAS;AAAA,MAC9D,KAAK;AACH,eAAO,qBAAqB,KAAK,QAA8B,SAAS;AAAA,MAC1E,KAAK;AACH,eAAO,YAAY,aAAa,SAAS;AAAA,MAC3C;AACE,eAAO,UAAU,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA,EAIA,MAAc,UAAU,OAA6B;AACnD,UAAM,KAAK,aAAa,KAAK;AAC7B,SAAK,sBAAsB,KAAK;AAChC,UAAM,KAAK,iBAAiB;AAC5B,UAAM,KAAK,iBAAiB;AAAA,EAC9B;AAAA,EAEA,MAAc,YAAY,SAAiB,OAAsC;AAC/E,UAAM,KAAK,YAAY,SAAS,EAAE,GAAG,OAAO,WAAW,KAAK,IAAI,EAAE,CAAC;AACnE,SAAK,sBAAsB,SAAS,KAAK;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAAY,IAAY,OAA+C;AACnF,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAI,CAAC,QAAS;AAEd,UAAM,MAAM,MAAM,QAAQ,IAAI,MAAM,EAAE,YAAY,mBAAmB,KAAK,GAAG,CAAC;AAC9E,QAAI,QAAQ,QAAQ,QAAQ,UAAa,OAAO,QAAQ,SAAU;AAClE,UAAM,WAAoC,OAAO,YAAY,OAAO,QAAQ,GAAG,CAAC;AAChF,UAAM,QAAQ,IAAI,OAAO,EAAE,YAAY,mBAAmB,KAAK,IAAI,OAAO,EAAE,GAAG,UAAU,GAAG,MAAM,EAAE,CAAC;AAAA,EACvG;AAAA,EAEA,MAAc,aAAa,OAA6B;AACtD,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAI,CAAC,QAAS;AAGd,UAAM,OAAgC;AAAA,MACpC,IAAI,MAAM;AAAA,MACV,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,SAAS,MAAM;AAAA,MACf,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,WAAW,MAAM;AAAA,MACjB,WAAW,MAAM;AAAA,MACjB,GAAI,MAAM,aAAa,SAAY,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,MACnE,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC/C,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,IACvD;AACA,UAAM,QAAQ,IAAI,OAAO,EAAE,YAAY,mBAAmB,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC;AAAA,EACxF;AAAA,EAEQ,sBAAsB,OAAoB;AAChD,SAAK,IAAI,UAAU,SAAK,2BAAY,iBAAiB,cAAc;AAAA,MACjE,IAAI,MAAM;AAAA,MACV,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC,CAAC;AAAA,EACJ;AAAA,EAEQ,sBAAsB,SAAiB,OAA6B;AAC1E,UAAM,cAAuC,CAAC;AAC9C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,kBAAY,GAAG,IAAI;AAAA,IACrB;AACA,SAAK,IAAI,UAAU,SAAK,2BAAY,iBAAiB,cAAc;AAAA,MACjE;AAAA,MACA,OAAO;AAAA,IACT,CAAC,CAAC;AAAA,EACJ;AAAA,EAEA,MAAc,mBAAkC;AAC9C,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAI,CAAC,QAAS;AAEd,UAAM,QAAQ,MAAM,QAAQ,MAAM,MAAM,EAAE,YAAY,kBAAkB,CAAC;AACzE,QAAI,SAAS,KAAK,OAAO,UAAW;AAGpC,UAAM,SAAS,QAAQ,KAAK,OAAO;AACnC,UAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,EAAE,YAAY,mBAAmB,QAAQ;AAAA,MAChF,OAAO,EAAE,MAAM,KAAK;AAAA,MACpB,SAAS,EAAE,OAAO,aAAa,WAAW,MAAM;AAAA,MAChD,OAAO;AAAA,IACT,EAAE,CAAC;AAEH,eAAW,UAAU,QAAQ;AAC3B,YAAM,QAAQ,OAAO,OAAO,EAAE,YAAY,mBAAmB,KAAK,OAAO,GAAG,CAAC;AAAA,IAC/E;AAAA,EACF;AAAA,EAEA,MAAc,mBAAkC;AAC9C,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAI,CAAC,QAAS;AAEd,UAAM,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO,gBAAgB,KAAK,KAAK,KAAK;AACvE,UAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,EAAE,YAAY,mBAAmB,QAAQ;AAAA,MACjF,OAAO,EAAE,MAAM,KAAK;AAAA,MACpB,SAAS,EAAE,OAAO,aAAa,WAAW,MAAM;AAAA,IAClD,EAAE,CAAC;AAEH,eAAW,UAAU,SAAS;AAC5B,UAAI,OAAO,OAAO,KAAK,WAAW,KAAK,CAAC,IAAI,QAAQ;AAClD,cAAM,QAAQ,OAAO,OAAO,EAAE,YAAY,mBAAmB,KAAK,OAAO,GAAG,CAAC;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AACF;","names":["import_types"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}