@hot-updater/console 1.0.0-rc.4 → 1.0.0-rc.41

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 (330) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/ConsoleFeatureUnavailable-DRzeMGRM.js +1 -0
  3. package/.output/public/assets/EventDetails-SB5ygJzS.js +1 -0
  4. package/.output/public/assets/HashValueDisplay-BFX_kY3-.js +1 -0
  5. package/.output/public/assets/InsightsInfo-btYppp0B.js +1 -0
  6. package/.output/public/assets/InsightsPageHeader-Ba8psD8t.js +1 -0
  7. package/.output/public/assets/NotFoundPage-CyRG2eca.js +1 -0
  8. package/.output/public/assets/alert-dialog-Bbk_4-WJ.js +1 -0
  9. package/.output/public/assets/api-DUgI6yOI.js +1 -0
  10. package/.output/public/assets/api-keys-CIO9L_wu.js +1 -0
  11. package/.output/public/assets/api-keys-CmkNKOhS.js +1 -0
  12. package/.output/public/assets/arrow-left-CnMYpqB7.js +1 -0
  13. package/.output/public/assets/arrow-up-right-BtffZA6e.js +1 -0
  14. package/.output/public/assets/chevron-right-BqD5wtFb.js +1 -0
  15. package/.output/public/assets/clipboard-DS9ucUQL.js +1 -0
  16. package/.output/public/assets/console-features-api-BMsI3Bj8.js +1 -0
  17. package/.output/public/assets/dialog-Bqbb7B0N.js +1 -0
  18. package/.output/public/assets/dist-LxKJB-Vu.js +1 -0
  19. package/.output/public/assets/empty-CuT2UhFp.js +1 -0
  20. package/.output/public/assets/field-BBDpjIqu.js +1 -0
  21. package/.output/public/assets/index-BEfQ2_7f.js +11 -0
  22. package/.output/public/assets/input-group-ja_30qaF.js +1 -0
  23. package/.output/public/assets/insights-B0ib9qOE.js +2 -0
  24. package/.output/public/assets/insights-BIMJx-0p.js +1 -0
  25. package/.output/public/assets/insights-CndqcWEj.js +42 -0
  26. package/.output/public/assets/insights-api-B6Ewc-OG.js +1 -0
  27. package/.output/public/assets/insights-usage-rpc-DYEhsCKT.js +1 -0
  28. package/.output/public/assets/insights_.distribution-B26PMy4k.js +2 -0
  29. package/.output/public/assets/insights_.distribution-BBDtqqYS.js +1 -0
  30. package/.output/public/assets/insights_.distribution-DhHmYS8k.js +1 -0
  31. package/.output/public/assets/installations-C3cMuwRx.js +1 -0
  32. package/.output/public/assets/installations-C3yrjwDh.js +2 -0
  33. package/.output/public/assets/installations-D3edlN75.js +1 -0
  34. package/.output/public/assets/key-round-wS_SIZ6b.js +1 -0
  35. package/.output/public/assets/list-CgrYiadM.js +1 -0
  36. package/.output/public/assets/refresh-cw-BYgoNCco.js +1 -0
  37. package/.output/public/assets/remote-config-0i-gDkeU.js +1 -0
  38. package/.output/public/assets/remote-config-An1ROIOQ.js +6 -0
  39. package/.output/public/assets/remote-config-CoeWgA9i.js +1 -0
  40. package/.output/public/assets/routes-DNoaJIQV.js +2 -0
  41. package/.output/public/assets/routes-cWBDtghZ.js +1 -0
  42. package/.output/public/assets/search-DaTDPW25.js +1 -0
  43. package/.output/public/assets/select-CZMQKT7F.js +1 -0
  44. package/.output/public/assets/sidebar-DNVyJPfX.js +3 -0
  45. package/.output/public/assets/smartphone-DpTFgtKf.js +1 -0
  46. package/.output/public/assets/styles-D8mxMvCB.css +2 -0
  47. package/.output/public/assets/switch-CU4-fupc.js +1 -0
  48. package/.output/public/assets/table-Gm4qRWwE.js +1 -0
  49. package/.output/public/assets/tabs-R1I8CRjR.js +1 -0
  50. package/.output/public/assets/undo-2-CmrHjwFc.js +1 -0
  51. package/.output/public/assets/useCompositeListItem-BaPeC9ZO.js +1 -0
  52. package/.output/public/assets/valueToPercent-CH8GCHaL.js +1 -0
  53. package/.output/server/__23tanstack-start-server-fn-resolver-DTAqlLRd.mjs +178 -0
  54. package/.output/server/_libs/@base-ui/react+[...].mjs +6450 -2741
  55. package/.output/server/_libs/@tanstack/react-router+[...].mjs +3802 -4022
  56. package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +140 -97
  57. package/.output/server/_libs/lucide-react.mjs +235 -31
  58. package/.output/server/_libs/next-themes.mjs +1 -1
  59. package/.output/server/_libs/react-redux+[...].mjs +1 -1
  60. package/.output/server/_libs/recharts+[...].mjs +483 -901
  61. package/.output/server/_libs/sonner.mjs +1 -1
  62. package/.output/server/_libs/tanstack__history.mjs +68 -41
  63. package/.output/server/_libs/tanstack__query-core.mjs +2010 -309
  64. package/.output/server/_libs/tanstack__react-query.mjs +448 -21
  65. package/.output/server/_libs/verkit.mjs +102 -1
  66. package/.output/server/_ssr/BundleIdDisplay-BNoVW3Dv.mjs +13 -0
  67. package/.output/server/_ssr/ConsoleFeatureUnavailable-BPFa-cmJ.mjs +58 -0
  68. package/.output/server/_ssr/EventDetails-9CeshfdR.mjs +344 -0
  69. package/.output/server/_ssr/HashValueDisplay-DXZlkcps.mjs +55 -0
  70. package/.output/server/_ssr/InsightsInfo-DLNdJQ0m.mjs +75 -0
  71. package/.output/server/_ssr/InsightsPageHeader-DZGVDgvv.mjs +145 -0
  72. package/.output/server/_ssr/NotFoundPage-mYHHg-2s.mjs +37 -0
  73. package/.output/server/_ssr/{dialog-DUaIgpgd.mjs → alert-dialog-Chkim7vZ.mjs} +6 -83
  74. package/.output/server/_ssr/api-C-Il5-sa.mjs +203 -0
  75. package/.output/server/_ssr/api-keys-01FGqj4d.mjs +5 -0
  76. package/.output/server/_ssr/{api-keys-DJml_XoK.mjs → api-keys-B_f9h7ln.mjs} +48 -10
  77. package/.output/server/_ssr/api-keys-rpc-Cf4YCyFc.mjs +52 -0
  78. package/.output/server/_ssr/api-rpc-DRqwxxT_.mjs +296 -0
  79. package/.output/server/_ssr/{auth-BF8mbAgF.mjs → auth-UP0wXs4i.mjs} +1 -1
  80. package/.output/server/_ssr/{auth-rpc-D_hv52-J.mjs → auth-rpc-D8nFpU9C.mjs} +6 -6
  81. package/.output/server/_ssr/auth.server-COZoXu4i.mjs +5425 -0
  82. package/.output/server/_ssr/bundleActivity-M5gzBFNg.mjs +18 -0
  83. package/.output/server/_ssr/config-WVX4IxSR.mjs +15 -0
  84. package/.output/server/_ssr/config.server-Dm2l7w0O.mjs +36 -0
  85. package/.output/server/_ssr/console-access--o9FXikU.mjs +17 -0
  86. package/.output/server/_ssr/console-features-BftSkf3f.mjs +60 -0
  87. package/.output/server/_ssr/console-features-api-CYclUQ4h.mjs +43 -0
  88. package/.output/server/_ssr/console-features-rpc-1WaAkPM_.mjs +19 -0
  89. package/.output/server/_ssr/{createServerFn-B2hcXoPM.mjs → createMiddleware-Cm6Tn0_Y.mjs} +67 -56
  90. package/.output/server/_ssr/{createServerRpc-DB29C_5p.mjs → createServerRpc-RLR4H-Fn.mjs} +2 -2
  91. package/.output/server/_ssr/databaseConfig-C5SkAyUy.mjs +5 -0
  92. package/.output/server/_ssr/{databaseJsonValue-d6I3nAS4.mjs → databaseJsonValue-Csbuzc9Q.mjs} +28 -5
  93. package/.output/server/_ssr/databaseRows-BUuNU-qt.mjs +74 -0
  94. package/.output/server/_ssr/dialog-mfSANqjC.mjs +84 -0
  95. package/.output/server/_ssr/{dist-CyzPaI5v.mjs → dist-wmnTk7w6.mjs} +140 -6
  96. package/.output/server/_ssr/{downloadBundle-B3ert-pY.mjs → downloadBundle-DViuIa9U.mjs} +10 -10
  97. package/.output/server/_ssr/empty-BPayFad3.mjs +60 -0
  98. package/.output/server/_ssr/{empty-plugin-adapters-B5QvGpEl.mjs → empty-plugin-adapters-CPtwX8a7.mjs} +1 -1
  99. package/.output/server/_ssr/failureReports-DKDhVsXA.mjs +33 -0
  100. package/.output/server/_ssr/field-DjZ5t7rH.mjs +189 -0
  101. package/.output/server/_ssr/getBundleChildren-CmjDg6Re.mjs +22 -0
  102. package/.output/server/_ssr/{input-group-Bb8ueylQ.mjs → input-group-Dx-MEkNM.mjs} +3 -52
  103. package/.output/server/_ssr/insights-BopxyJjk.mjs +14 -0
  104. package/.output/server/_ssr/insights-Bvm03d61.mjs +5 -0
  105. package/.output/server/_ssr/insights-CrLAHSDy.mjs +2315 -0
  106. package/.output/server/_ssr/insights-api-Bg8ZV_h_.mjs +122 -0
  107. package/.output/server/_ssr/insights-errors-BjnFUyZj.mjs +34 -0
  108. package/.output/server/_ssr/insights-failures-rpc-tyy5m9Cc.mjs +36 -0
  109. package/.output/server/_ssr/insights-failures-xaa41Buf.mjs +46 -0
  110. package/.output/server/_ssr/{insights-recovery-DSFM-YTL.mjs → insights-recovery-BWQhiZaF.mjs} +9 -2
  111. package/.output/server/_ssr/insights-recovery-rpc-CPJOiJAV.mjs +32 -0
  112. package/.output/server/_ssr/{insights-rpc-DrIQCjpD.mjs → insights-rpc-DoC3hla9.mjs} +22 -14
  113. package/.output/server/_ssr/insights-usage-BpBM0U0c.mjs +29 -0
  114. package/.output/server/_ssr/insights-usage-rpc-CFuTYp3T.mjs +29 -0
  115. package/.output/server/_ssr/insights-usage-rpc-O2ruP4iE.mjs +41 -0
  116. package/.output/server/_ssr/insightsUsage-CzhVjsc8.mjs +56 -0
  117. package/.output/server/_ssr/insights_.distribution-B3BVPD00.mjs +16 -0
  118. package/.output/server/_ssr/insights_.distribution-BMoisxRG.mjs +347 -0
  119. package/.output/server/_ssr/insights_.distribution-BiCcFyrG.mjs +7 -0
  120. package/.output/server/_ssr/{installations-YumqpNpa.mjs → installations-Cx3jIrwl.mjs} +280 -364
  121. package/.output/server/_ssr/installations-DTGPaKXx.mjs +69 -0
  122. package/.output/server/_ssr/installations-osiAuNKr.mjs +5 -0
  123. package/.output/server/_ssr/listReleases-BfUBlCHo.mjs +79 -0
  124. package/.output/server/_ssr/release-adoption-005tQRpo.mjs +55 -0
  125. package/.output/server/_ssr/release-adoption-rpc-BVySDR0L.mjs +41 -0
  126. package/.output/server/_ssr/releaseAdoption-2PJPA09N.mjs +114 -0
  127. package/.output/server/_ssr/releaseManagement-BTCWEY8-.mjs +11 -0
  128. package/.output/server/_ssr/remote-config-CUoAxUMy.mjs +430 -0
  129. package/.output/server/_ssr/remote-config-Cc5P4J-r.mjs +17 -0
  130. package/.output/server/_ssr/remote-config-CjdxcZ9B.mjs +5 -0
  131. package/.output/server/_ssr/remote-config-D2GmbGwI.mjs +2594 -0
  132. package/.output/server/_ssr/remote-config-rpc-kjoZ9PRS.mjs +115 -0
  133. package/.output/server/_ssr/rolldown-runtime-rSIU-vHC.mjs +13 -0
  134. package/.output/server/_ssr/{router-iP95Vqi2.mjs → router-DwGVewL-.mjs} +141 -139
  135. package/.output/server/_ssr/{routes-ivsV2TDu.mjs → routes-C4yxv3JU.mjs} +192 -685
  136. package/.output/server/_ssr/routes-D3_aegLY.mjs +409 -0
  137. package/.output/server/_ssr/runtime.server-BoWf4QhU.mjs +1716 -0
  138. package/.output/server/_ssr/schema-DrOtkRVD.mjs +361 -0
  139. package/.output/server/_ssr/select-DkzM2miy.mjs +107 -0
  140. package/.output/server/_ssr/server-BW0gzB0p.mjs +8325 -0
  141. package/.output/server/_ssr/{createSsrRpc-NHF2PxuK.mjs → sidebar-DPcOijvL.mjs} +107 -47
  142. package/.output/server/_ssr/ssr.mjs +1 -1
  143. package/.output/server/_ssr/start-BfFbHKMK.mjs +4 -0
  144. package/.output/server/_ssr/switch-BqJ2mAwC.mjs +17 -0
  145. package/.output/server/_ssr/{table-D1mL8fJu.mjs → table-R7RY92q9.mjs} +2 -2
  146. package/.output/server/_ssr/tabs-trDcbRkT.mjs +45 -0
  147. package/.output/server/_ssr/updateFailures-H6pnnYK4.mjs +40 -0
  148. package/.output/server/_ssr/{uuidv7-D0QFkPL_.mjs → uuidv7-ctA_XVZA.mjs} +2 -2
  149. package/.output/server/_tanstack-start-manifest_v-BwInaUTw.mjs +139 -0
  150. package/.output/server/index.mjs +315 -154
  151. package/LICENSE +13 -14
  152. package/README.md +82 -72
  153. package/lib/index.d.mts +23 -11
  154. package/lib/vite-internal.mjs +13 -3
  155. package/lib/vite.d.mts +2 -0
  156. package/package.json +14 -14
  157. package/src/components/AppSidebar.tsx +100 -71
  158. package/src/components/ConsoleAccessPage.tsx +5 -1
  159. package/src/components/ConsoleFeatureUnavailable.tsx +80 -0
  160. package/src/components/NotFoundPage.tsx +7 -7
  161. package/src/components/features/FeatureSlots.tsx +103 -0
  162. package/src/components/features/api-keys/apiKeysFeatureUi.tsx +15 -0
  163. package/src/components/features/bundles/BundleMetadata.tsx +8 -5
  164. package/src/components/features/bundles/RolloutCohortsDialog.tsx +1 -1
  165. package/src/components/features/channels/ChannelManagementDialog.tsx +2 -5
  166. package/src/components/features/insights/AppUsage.tsx +366 -0
  167. package/src/components/features/insights/BuiltinBundle.tsx +36 -0
  168. package/src/components/features/insights/ComparedBundlesChart.tsx +310 -0
  169. package/src/components/features/insights/EstimatedCount.tsx +18 -0
  170. package/src/components/features/insights/EventDetails.tsx +400 -39
  171. package/src/components/features/insights/EventHistoryCard.tsx +112 -26
  172. package/src/components/features/insights/EventHistoryList.tsx +2 -2
  173. package/src/components/features/insights/FailureReports.tsx +407 -0
  174. package/src/components/features/insights/InsightsControls.tsx +265 -88
  175. package/src/components/features/insights/InsightsErrorAlert.tsx +14 -1
  176. package/src/components/features/insights/InsightsInfo.tsx +48 -0
  177. package/src/components/features/insights/InsightsOverview.tsx +604 -355
  178. package/src/components/features/insights/InsightsPageHeader.tsx +35 -20
  179. package/src/components/features/insights/InsightsPeriodSelector.tsx +89 -0
  180. package/src/components/features/insights/InstallationHistoryCard.tsx +66 -11
  181. package/src/components/features/insights/InstallationMatchesCard.tsx +1 -1
  182. package/src/components/features/insights/ReleaseActivity.tsx +308 -0
  183. package/src/components/features/insights/ReportingDevicesSummary.tsx +48 -0
  184. package/src/components/features/insights/RollbackButton.tsx +118 -0
  185. package/src/components/features/insights/UpdateFailures.tsx +382 -0
  186. package/src/components/features/insights/insightsFeatureUi.tsx +35 -0
  187. package/src/components/features/releases/ReleaseEditorSheet.tsx +26 -12
  188. package/src/components/features/remote-config/ConditionDialog.tsx +581 -0
  189. package/src/components/features/remote-config/ConditionsCard.tsx +244 -0
  190. package/src/components/features/remote-config/ParameterDialog.tsx +407 -0
  191. package/src/components/features/remote-config/ParametersCard.tsx +244 -0
  192. package/src/components/features/remote-config/PreviewCard.tsx +284 -0
  193. package/src/components/features/remote-config/PublishDialog.tsx +319 -0
  194. package/src/components/features/remote-config/RemoteConfigPage.tsx +353 -0
  195. package/src/components/features/remote-config/RuleSummary.tsx +21 -0
  196. package/src/components/features/remote-config/ValueInput.tsx +148 -0
  197. package/src/components/features/remote-config/VersionsCard.tsx +361 -0
  198. package/src/components/features/remote-config/remoteConfigFeatureUi.tsx +15 -0
  199. package/src/components/features/remote-config/useDateTimeText.ts +16 -0
  200. package/src/components/ui/card.tsx +1 -1
  201. package/src/components/ui/scroll-area.tsx +52 -0
  202. package/src/components/ui/sidebar.tsx +22 -29
  203. package/src/components/ui/tabs.tsx +81 -0
  204. package/src/index.ts +26 -19
  205. package/src/lib/api-keys-api.ts +0 -28
  206. package/src/lib/api-keys-rpc.ts +27 -38
  207. package/src/lib/api-rpc.ts +189 -266
  208. package/src/lib/api.ts +19 -102
  209. package/src/lib/bundle-activity.ts +24 -4
  210. package/src/lib/console-access.ts +20 -0
  211. package/src/lib/console-features-api.ts +68 -0
  212. package/src/lib/console-features-rpc.ts +13 -0
  213. package/src/lib/console-features.ts +97 -0
  214. package/src/lib/insights-api.ts +56 -2
  215. package/src/lib/insights-errors.ts +64 -0
  216. package/src/lib/insights-failures-rpc.ts +36 -0
  217. package/src/lib/insights-failures.ts +130 -0
  218. package/src/lib/insights-recovery-rpc.ts +13 -17
  219. package/src/lib/insights-recovery.ts +10 -27
  220. package/src/lib/insights-retention.ts +21 -0
  221. package/src/lib/insights-rpc.ts +30 -12
  222. package/src/lib/insights-search.ts +93 -0
  223. package/src/lib/insights-usage-rpc.ts +29 -0
  224. package/src/lib/insights-usage.ts +76 -0
  225. package/src/lib/insights-view.ts +34 -5
  226. package/src/lib/release-adoption-api.ts +214 -0
  227. package/src/lib/release-adoption-rpc.ts +49 -0
  228. package/src/lib/release-adoption.ts +164 -0
  229. package/src/lib/remote-config-api.ts +119 -0
  230. package/src/lib/remote-config-draft.ts +652 -0
  231. package/src/lib/remote-config-rpc.ts +196 -0
  232. package/src/lib/scroll-restoration.ts +21 -0
  233. package/src/lib/server/adminInsights.ts +124 -0
  234. package/src/lib/server/auth.server.ts +13 -5
  235. package/src/lib/server/bundleActivity.ts +27 -28
  236. package/src/lib/server/config.server.ts +21 -74
  237. package/src/lib/server/console-feature-apis.ts +70 -0
  238. package/src/lib/server/console-runtime.server.ts +82 -38
  239. package/src/lib/server/downloadBundle.ts +16 -15
  240. package/src/lib/server/failureReports.ts +49 -0
  241. package/src/lib/server/getBundleChildren.ts +31 -122
  242. package/src/lib/server/insightsUsage.ts +63 -0
  243. package/src/lib/server/listReleases.ts +109 -44
  244. package/src/lib/server/releaseAdoption.ts +154 -0
  245. package/src/lib/server/releaseReachability.ts +8 -7
  246. package/src/lib/server/remoteConfig.ts +191 -0
  247. package/src/lib/server/runtime.server.ts +120 -31
  248. package/src/lib/server/updateFailures.ts +65 -0
  249. package/src/routeTree.gen.ts +65 -44
  250. package/src/router.tsx +3 -2
  251. package/src/routes/-installations-search.ts +32 -8
  252. package/src/routes/-releases-search.ts +76 -29
  253. package/src/routes/__root.tsx +10 -4
  254. package/src/routes/api/bundles/$bundleId/download.ts +2 -5
  255. package/src/routes/api-keys.tsx +5 -2
  256. package/src/routes/index.tsx +210 -152
  257. package/src/routes/insights.tsx +133 -18
  258. package/src/routes/insights_.distribution.tsx +422 -0
  259. package/src/routes/installations.tsx +98 -41
  260. package/src/routes/remote-config.tsx +42 -0
  261. package/src/styles.css +9 -0
  262. package/src/vite-internal.ts +15 -3
  263. package/src/vite.ts +2 -0
  264. package/.output/public/assets/InsightsPageHeader-C-Xc2MB9.js +0 -1
  265. package/.output/public/assets/api-keys-C1sgC6ko.js +0 -1
  266. package/.output/public/assets/api-keys-api-LchP65vQ.js +0 -1
  267. package/.output/public/assets/badge-BuMDU0Rf.js +0 -1
  268. package/.output/public/assets/card-BEvx_QKh.js +0 -1
  269. package/.output/public/assets/chart-no-axes-combined-C0G0fQ3J.js +0 -1
  270. package/.output/public/assets/composite-CHTH1Xhh.js +0 -1
  271. package/.output/public/assets/createServerFn-DHc2erub.js +0 -3
  272. package/.output/public/assets/dialog-dyZ1SphZ.js +0 -1
  273. package/.output/public/assets/dist-Bh1gaDfB.js +0 -1
  274. package/.output/public/assets/field-79SVH26s.js +0 -1
  275. package/.output/public/assets/index-BNkxg4jz.js +0 -10
  276. package/.output/public/assets/input-group-BbHfaBzQ.js +0 -1
  277. package/.output/public/assets/insights-D_7uSKfc.js +0 -1
  278. package/.output/public/assets/installations-BzoHWuXw.js +0 -1
  279. package/.output/public/assets/installations-DvjbUqd1.js +0 -2
  280. package/.output/public/assets/lazyRouteComponent-BN0MS05o.js +0 -1
  281. package/.output/public/assets/link-BG06whwB.js +0 -1
  282. package/.output/public/assets/loader-circle-Bbp8LGVC.js +0 -1
  283. package/.output/public/assets/preload-helper-uTix4PVD.js +0 -1
  284. package/.output/public/assets/refresh-cw-DZgiAOMk.js +0 -1
  285. package/.output/public/assets/routes-BFE-oRIT.js +0 -1
  286. package/.output/public/assets/routes-DaPMY31P.js +0 -2
  287. package/.output/public/assets/shield-check-DoIiaaXU.js +0 -1
  288. package/.output/public/assets/signing-BTRhaF5D.js +0 -1
  289. package/.output/public/assets/styles-C7U0oVke.css +0 -2
  290. package/.output/public/assets/table-BBEzJ7Xl.js +0 -1
  291. package/.output/public/assets/useCompositeListItem-BkPDaqyj.js +0 -42
  292. package/.output/server/__23tanstack-start-server-fn-resolver-Dr2ixDgQ.mjs +0 -146
  293. package/.output/server/_ssr/InsightsPageHeader-C5Has8Ry.mjs +0 -60
  294. package/.output/server/_ssr/api-keys-api-CrCZyvnl.mjs +0 -60
  295. package/.output/server/_ssr/api-keys-rpc-CFaNf-q0.mjs +0 -136
  296. package/.output/server/_ssr/api-rpc-B61KL3Eo.mjs +0 -1399
  297. package/.output/server/_ssr/auth.server-DF_shCeq.mjs +0 -47
  298. package/.output/server/_ssr/badge-BgsCP9Dp.mjs +0 -28
  299. package/.output/server/_ssr/bundle-signing-rpc-BBipZnFs.mjs +0 -16
  300. package/.output/server/_ssr/bundle-signing.server-Co_zHdJx.mjs +0 -12
  301. package/.output/server/_ssr/bundleActivity-D3_fIda2.mjs +0 -27
  302. package/.output/server/_ssr/card-DrbxCPtG.mjs +0 -86
  303. package/.output/server/_ssr/chart-qxa-_30a.mjs +0 -162
  304. package/.output/server/_ssr/config-Dv8qLDZ0.mjs +0 -13
  305. package/.output/server/_ssr/config.server-CBr6PDj5.mjs +0 -368
  306. package/.output/server/_ssr/databaseRows-5bCRTxm-.mjs +0 -126
  307. package/.output/server/_ssr/deleteBundle-BAq3JuGr.mjs +0 -66
  308. package/.output/server/_ssr/field-CqNUlqUq.mjs +0 -74
  309. package/.output/server/_ssr/getBundleChildren-COMt16m_.mjs +0 -50
  310. package/.output/server/_ssr/insights-B-DUbksX.mjs +0 -502
  311. package/.output/server/_ssr/insights-recovery-rpc-P71FH66n.mjs +0 -37
  312. package/.output/server/_ssr/insightsContract-fjJDBeEE.mjs +0 -303
  313. package/.output/server/_ssr/insightsRecovery-CqcosG7B.mjs +0 -149
  314. package/.output/server/_ssr/installations-BQrppti7.mjs +0 -29
  315. package/.output/server/_ssr/routes-BDabsmc7.mjs +0 -37
  316. package/.output/server/_ssr/runtime.server-jmZOKIQM.mjs +0 -438
  317. package/.output/server/_ssr/server-p7yrVBfD.mjs +0 -7468
  318. package/.output/server/_ssr/signing-CxCbnFCt.mjs +0 -134
  319. package/.output/server/_ssr/start-DpViQGnt.mjs +0 -4
  320. package/.output/server/_tanstack-start-manifest_v-Cwpu0C9Q.mjs +0 -100
  321. package/src/components/features/bundles/BundleActivityChart.tsx +0 -95
  322. package/src/components/features/bundles/BundleInsightsSummary.tsx +0 -121
  323. package/src/components/features/signing/BundleSigningPage.tsx +0 -139
  324. package/src/lib/bundle-signing-api.ts +0 -14
  325. package/src/lib/bundle-signing-rpc.ts +0 -16
  326. package/src/lib/server/bundle-signing.server.ts +0 -23
  327. package/src/lib/server/deleteBundle.ts +0 -145
  328. package/src/lib/server/insightsHistory.ts +0 -52
  329. package/src/lib/server/insightsRecovery.ts +0 -186
  330. package/src/routes/signing.tsx +0 -37
@@ -1,33 +1,152 @@
1
1
  import {
2
2
  Activity,
3
+ ArrowRightLeft,
3
4
  Check,
4
5
  ChevronDown,
5
- PackageCheck,
6
+ CircleAlert,
7
+ Copy,
8
+ Download,
6
9
  RotateCcw,
10
+ Smartphone,
11
+ Sparkles,
7
12
  } from "lucide-react";
8
13
  import { useEffect, useState } from "react";
14
+ import { toast } from "sonner";
9
15
 
10
16
  import { HashValueDisplay } from "@/components/HashValueDisplay";
11
17
  import { Badge } from "@/components/ui/badge";
18
+ import { Button } from "@/components/ui/button";
19
+ import {
20
+ Empty,
21
+ EmptyDescription,
22
+ EmptyHeader,
23
+ EmptyTitle,
24
+ } from "@/components/ui/empty";
25
+ import {
26
+ Sheet,
27
+ SheetContent,
28
+ SheetDescription,
29
+ SheetHeader,
30
+ SheetTitle,
31
+ SheetTrigger,
32
+ } from "@/components/ui/sheet";
33
+ import { describeFailure } from "@/lib/insights-failures";
12
34
  import type { InsightsEventRow } from "@/lib/insights-view";
13
35
 
36
+ import { BuiltinBundleBadge, isBuiltinBundle } from "./BuiltinBundle";
37
+
14
38
  type EventHistoryRow = InsightsEventRow;
15
39
 
16
40
  const eventTypes = {
17
- UPDATE_APPLIED: { label: "Bundle applied", variant: "success", icon: Check },
18
- RECOVERED: { label: "Recovered", variant: "warning", icon: RotateCcw },
19
- RELEASE_ADOPTED: {
20
- label: "Bundle adopted",
41
+ UPDATE_DOWNLOADED: {
42
+ label: "Downloaded",
43
+ description: "Downloaded. It launches when the app restarts.",
44
+ variant: "default",
45
+ icon: Download,
46
+ },
47
+ UPDATE_APPLIED: {
48
+ label: "Launched",
49
+ description: "The app restarted into the downloaded bundle.",
21
50
  variant: "success",
22
- icon: PackageCheck,
51
+ icon: Check,
52
+ },
53
+ RECOVERED: {
54
+ label: "Crashed",
55
+ description: "Crashed on the bundle and rolled back.",
56
+ variant: "warning",
57
+ icon: RotateCcw,
58
+ },
59
+ UPDATE_FAILED: {
60
+ label: "Update failed",
61
+ description: "An update check, download, or install failed.",
62
+ variant: "destructive",
63
+ icon: CircleAlert,
23
64
  },
24
65
  UNCHANGED: {
25
- label: "Activity reported",
66
+ label: "Launch",
67
+ description: "The app launched; the report changed nothing.",
26
68
  variant: "secondary",
27
69
  icon: Activity,
28
70
  },
29
71
  } as const;
30
72
 
73
+ type EventType = {
74
+ readonly label: string;
75
+ readonly description: string;
76
+ readonly variant: (typeof eventTypes)[keyof typeof eventTypes]["variant"];
77
+ readonly icon: (typeof eventTypes)[keyof typeof eventTypes]["icon"];
78
+ };
79
+
80
+ /**
81
+ * A kept UNCHANGED report, named by what it changed: an installation first
82
+ * seen, an App Store update, a launch with no apply report, an adopted
83
+ * release, or a channel switch.
84
+ */
85
+ const changeTypeOf = (
86
+ event: Pick<EventHistoryRow, "change" | "appVersion" | "channel">,
87
+ ): EventType => {
88
+ const { kinds = [], previous } = event.change ?? {};
89
+ if (kinds.includes("first_seen")) {
90
+ return {
91
+ label: "First seen",
92
+ description: "The installation's first report to this server.",
93
+ variant: "secondary",
94
+ icon: Sparkles,
95
+ };
96
+ }
97
+ if (kinds.includes("app_version") || kinds.includes("native_build")) {
98
+ return {
99
+ label: "App updated",
100
+ description:
101
+ previous && previous.appVersion !== event.appVersion
102
+ ? `From app ${previous.appVersion} to ${event.appVersion}.`
103
+ : "A new build of the same app version.",
104
+ variant: "secondary",
105
+ icon: Smartphone,
106
+ };
107
+ }
108
+ if (kinds.includes("bundle")) {
109
+ return {
110
+ label: "Launched",
111
+ description:
112
+ "Seen running this bundle; the report of the restart into it never arrived.",
113
+ variant: "success",
114
+ icon: Check,
115
+ };
116
+ }
117
+ if (kinds.includes("release")) {
118
+ return {
119
+ label: "Release adopted",
120
+ description: "The bundle it runs now ships under another release.",
121
+ variant: "secondary",
122
+ icon: ArrowRightLeft,
123
+ };
124
+ }
125
+ if (kinds.includes("channel")) {
126
+ return {
127
+ label: "Channel changed",
128
+ description: previous
129
+ ? `From ${previous.channel} to ${event.channel}.`
130
+ : "It reports on another channel.",
131
+ variant: "secondary",
132
+ icon: ArrowRightLeft,
133
+ };
134
+ }
135
+ return eventTypes.UNCHANGED;
136
+ };
137
+
138
+ /** How the console names an event's type. */
139
+ const eventTypeOf = (
140
+ event: Pick<EventHistoryRow, "type"> & Partial<EventHistoryRow>,
141
+ ): EventType =>
142
+ event.type === "UNCHANGED" && event.change
143
+ ? changeTypeOf({
144
+ change: event.change,
145
+ appVersion: event.appVersion ?? "",
146
+ channel: event.channel ?? "",
147
+ })
148
+ : eventTypes[event.type];
149
+
31
150
  export function useInsightsTimeFormat() {
32
151
  const [timeZone, setTimeZone] = useState("UTC");
33
152
  useEffect(() => {
@@ -92,28 +211,227 @@ export function EventTimestamp({
92
211
  );
93
212
  }
94
213
 
95
- export function EventTypeBadge({
96
- type,
214
+ const deliveries: Readonly<Record<string, string>> = {
215
+ patch: "A patch delivered it.",
216
+ manifest: "Only the changed files were downloaded.",
217
+ archive: "The full archive was downloaded.",
218
+ };
219
+
220
+ /** What the event's report added: where an update failed, or how a bundle arrived. */
221
+ const eventNote = (
222
+ event: Pick<
223
+ EventHistoryRow,
224
+ | "type"
225
+ | "failure"
226
+ | "delivery"
227
+ | "patchFallback"
228
+ | "httpResponse"
229
+ | "late"
230
+ | "impliedDownload"
231
+ >,
232
+ ): string | null => {
233
+ if (event.late) {
234
+ return "Counted nothing: the installation had already downloaded or run this bundle.";
235
+ }
236
+ if (event.impliedDownload) {
237
+ return "Its download report never arrived; the download counted with it.";
238
+ }
239
+ if (event.type === "UPDATE_FAILED" && event.failure) {
240
+ return describeFailure(event.failure);
241
+ }
242
+ if (event.type === "UPDATE_DOWNLOADED" && event.delivery) {
243
+ const delivered = deliveries[event.delivery] ?? null;
244
+ return event.patchFallback
245
+ ? `The patch failed. ${delivered ?? ""}`.trim()
246
+ : delivered;
247
+ }
248
+ return null;
249
+ };
250
+
251
+ type EventDetail = Pick<EventHistoryRow, "type"> & Partial<EventHistoryRow>;
252
+
253
+ export function HttpResponseBody({
254
+ response,
97
255
  }: {
98
- readonly type: EventHistoryRow["type"];
256
+ readonly response: NonNullable<EventHistoryRow["httpResponse"]>;
99
257
  }) {
100
- const eventType = eventTypes[type];
258
+ const copyBody = async () => {
259
+ try {
260
+ await navigator.clipboard.writeText(response.body!);
261
+ toast.success("Response body copied");
262
+ } catch {
263
+ toast.error("Could not copy the response body");
264
+ }
265
+ };
266
+ return (
267
+ <section aria-label="Response body" className="flex min-w-0 flex-col gap-3">
268
+ <div className="flex flex-wrap items-center justify-between gap-3">
269
+ <h3 className="text-sm font-medium">Response body</h3>
270
+ <Button
271
+ variant="outline"
272
+ className="min-h-11"
273
+ disabled={response.body === null || response.body === ""}
274
+ onClick={() => void copyBody()}
275
+ >
276
+ <Copy aria-hidden="true" data-icon="inline-start" /> Copy body
277
+ </Button>
278
+ </div>
279
+ {response.bodyTruncated ? (
280
+ <p className="text-xs text-muted-foreground">
281
+ Truncated to the 4 KiB reporting limit. Copy includes only the stored
282
+ text.
283
+ </p>
284
+ ) : null}
285
+ {response.body ? (
286
+ <pre className="rounded-md border bg-muted/30 p-4 font-mono text-xs leading-relaxed whitespace-pre-wrap wrap-anywhere">
287
+ {response.body}
288
+ </pre>
289
+ ) : (
290
+ <Empty>
291
+ <EmptyHeader>
292
+ <EmptyTitle>
293
+ {response.body === null
294
+ ? "Response body unavailable"
295
+ : "Empty response body"}
296
+ </EmptyTitle>
297
+ <EmptyDescription>
298
+ {response.body === null
299
+ ? "The client received the HTTP status but could not read the body."
300
+ : response.status === 304
301
+ ? "The server returned no body. The client can reuse its cached catalog."
302
+ : "The server returned no text in this response."}
303
+ </EmptyDescription>
304
+ </EmptyHeader>
305
+ </Empty>
306
+ )}
307
+ </section>
308
+ );
309
+ }
310
+
311
+ export function HttpResponseDetails({
312
+ event,
313
+ }: {
314
+ readonly event: Partial<EventHistoryRow>;
315
+ }) {
316
+ const response = event.httpResponse!;
317
+ const formatter = useInsightsTimeFormat();
318
+ const status =
319
+ response.status === 304
320
+ ? "Not modified"
321
+ : response.status >= 500
322
+ ? "Server error"
323
+ : response.status >= 400
324
+ ? "Request error"
325
+ : response.status >= 300
326
+ ? "Redirect"
327
+ : "Success";
328
+ const resource = response.resource === "catalog" ? "Catalog" : "Artifact";
329
+ const context = [
330
+ [
331
+ "App",
332
+ event.platform &&
333
+ `${event.platform === "ios" ? "iOS" : "Android"} ${event.appVersion}`,
334
+ ],
335
+ ["Channel", event.channel],
336
+ ["SDK", event.sdkVersion],
337
+ ["Installation", event.installId],
338
+ ].filter(([, value]) => value != null);
339
+ return (
340
+ <Sheet>
341
+ <SheetTrigger
342
+ aria-label={`View ${resource.toLowerCase()} response: HTTP ${response.status}`}
343
+ render={
344
+ <Button
345
+ variant="ghost"
346
+ className="-ml-2 h-auto min-h-11 justify-start"
347
+ />
348
+ }
349
+ >
350
+ <Badge variant={response.status >= 400 ? "destructive" : "secondary"}>
351
+ HTTP {response.status}
352
+ </Badge>
353
+ <span>{resource} response</span>
354
+ </SheetTrigger>
355
+ <SheetContent className="data-[side=right]:w-full data-[side=right]:sm:max-w-2xl">
356
+ <SheetHeader className="border-b pr-14">
357
+ <SheetTitle>HTTP response</SheetTitle>
358
+ <SheetDescription>
359
+ {resource} · HTTP {response.status} · {status}. Most recent response
360
+ available when this report was created.
361
+ </SheetDescription>
362
+ </SheetHeader>
363
+ <div className="flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto p-6">
364
+ <section aria-label="Request" className="flex min-w-0 flex-col gap-2">
365
+ <h3 className="text-sm font-medium">Request</h3>
366
+ <p className="font-mono text-xs leading-relaxed whitespace-pre-wrap wrap-anywhere">
367
+ GET {response.path}
368
+ </p>
369
+ {response.receivedAtMs != null ? (
370
+ <div className="text-xs text-muted-foreground">
371
+ Response received{" "}
372
+ <EventTimestamp
373
+ value={response.receivedAtMs}
374
+ formatter={formatter}
375
+ />
376
+ </div>
377
+ ) : null}
378
+ </section>
379
+ <HttpResponseBody response={response} />
380
+ {context.length ? (
381
+ <section
382
+ aria-label="Response context"
383
+ className="flex flex-col gap-3"
384
+ >
385
+ <h3 className="text-sm font-medium">Response context</h3>
386
+ <dl className="grid grid-cols-2 gap-x-6 gap-y-4">
387
+ {context.map(([label, value]) => (
388
+ <div key={label} className="min-w-0">
389
+ <dt className="text-xs text-muted-foreground">{label}</dt>
390
+ <dd className="mt-1 text-sm wrap-anywhere">{value}</dd>
391
+ </div>
392
+ ))}
393
+ </dl>
394
+ </section>
395
+ ) : null}
396
+ </div>
397
+ </SheetContent>
398
+ </Sheet>
399
+ );
400
+ }
401
+
402
+ export function EventTypeDetails({ event }: { readonly event: EventDetail }) {
403
+ const eventType = eventTypeOf(event);
101
404
  const Icon = eventType.icon;
405
+ const note = eventNote(event);
102
406
  return (
103
- <Badge
104
- variant={eventType.variant}
105
- className="gap-1 whitespace-nowrap [&_svg]:size-3"
106
- title={
107
- type === "UNCHANGED"
108
- ? "App activity reported on the current bundle without a bundle transition."
109
- : type === "RELEASE_ADOPTED"
110
- ? "A different release was adopted without changing the bundle."
111
- : undefined
112
- }
113
- >
114
- <Icon aria-hidden="true" />
115
- {eventType.label}
116
- </Badge>
407
+ <div className="flex min-w-0 flex-col items-start gap-2">
408
+ <Badge
409
+ variant={eventType.variant}
410
+ className="gap-1 whitespace-nowrap [&_svg]:size-3"
411
+ >
412
+ <Icon aria-hidden="true" />
413
+ {eventType.label}
414
+ </Badge>
415
+ <p className="max-w-56 whitespace-pre-wrap wrap-anywhere text-xs text-muted-foreground">
416
+ {event.type === "UPDATE_FAILED" && note ? note : eventType.description}
417
+ </p>
418
+ {event.httpResponse ? <HttpResponseDetails event={event} /> : null}
419
+ {event.type === "UPDATE_FAILED" && event.failure?.errorStack ? (
420
+ <details className="w-full max-w-56 text-xs">
421
+ <summary className="cursor-pointer text-muted-foreground">
422
+ Stack trace
423
+ </summary>
424
+ <pre className="mt-2 max-h-64 overflow-auto whitespace-pre-wrap wrap-anywhere font-mono">
425
+ {event.failure.errorStack}
426
+ </pre>
427
+ </details>
428
+ ) : null}
429
+ {event.type !== "UPDATE_FAILED" && note ? (
430
+ <p className="max-w-56 whitespace-normal text-xs text-muted-foreground">
431
+ {note}
432
+ </p>
433
+ ) : null}
434
+ </div>
117
435
  );
118
436
  }
119
437
 
@@ -121,31 +439,74 @@ export function EventBundleTransition({
121
439
  event,
122
440
  touch = false,
123
441
  }: {
124
- readonly event: Pick<EventHistoryRow, "type" | "fromBundleId" | "toBundleId">;
442
+ readonly event: Pick<
443
+ EventHistoryRow,
444
+ "type" | "fromBundleId" | "toBundleId" | "failure" | "minBundleId"
445
+ > &
446
+ Partial<Pick<EventHistoryRow, "change">>;
125
447
  readonly touch?: boolean;
126
448
  }) {
449
+ const downloaded = event.type === "UPDATE_DOWNLOADED";
450
+ const failed = event.type === "UPDATE_FAILED";
451
+ // A failed check targets no bundle: it names the one running.
452
+ const targeted = !failed || event.failure?.stage !== "check";
453
+ // A kept UNCHANGED report that moved bundles names the one before it.
454
+ const moved =
455
+ event.type === "UNCHANGED" &&
456
+ event.change?.kinds.includes("bundle") === true &&
457
+ event.change.previous !== undefined;
458
+ const fromBundleId = moved
459
+ ? event.change!.previous!.bundleId
460
+ : event.fromBundleId;
461
+ const changed =
462
+ downloaded ||
463
+ failed ||
464
+ moved ||
465
+ event.type === "UPDATE_APPLIED" ||
466
+ event.type === "RECOVERED";
127
467
  return (
128
468
  <dl className="grid grid-cols-[auto_minmax(0,1fr)] items-center gap-x-2 gap-y-2">
129
- {event.fromBundleId ? (
469
+ {fromBundleId && changed ? (
470
+ <>
471
+ <dt className="text-muted-foreground">
472
+ {downloaded || failed ? "Running" : "From"}
473
+ </dt>
474
+ <dd className="flex min-w-0 flex-wrap items-center gap-2">
475
+ <HashValueDisplay
476
+ value={fromBundleId}
477
+ buttonClassName={touch ? "min-h-11 px-3" : undefined}
478
+ />
479
+ {isBuiltinBundle(
480
+ fromBundleId,
481
+ moved ? event.change!.previous!.minBundleId : event.minBundleId,
482
+ ) ? (
483
+ <BuiltinBundleBadge />
484
+ ) : null}
485
+ </dd>
486
+ </>
487
+ ) : null}
488
+ {targeted ? (
130
489
  <>
131
- <dt className="text-muted-foreground">From</dt>
132
- <dd>
490
+ <dt className="text-muted-foreground">
491
+ {downloaded
492
+ ? "Pending"
493
+ : failed
494
+ ? "Target"
495
+ : changed
496
+ ? "To"
497
+ : "Current"}
498
+ </dt>
499
+ <dd className="flex min-w-0 flex-wrap items-center gap-2">
133
500
  <HashValueDisplay
134
- value={event.fromBundleId}
501
+ value={event.toBundleId}
135
502
  buttonClassName={touch ? "min-h-11 px-3" : undefined}
136
503
  />
504
+ {isBuiltinBundle(event.toBundleId, event.minBundleId) ? (
505
+ <BuiltinBundleBadge />
506
+ ) : null}
137
507
  </dd>
138
508
  </>
139
509
  ) : null}
140
- <dt className="text-muted-foreground">
141
- {event.type === "UNCHANGED" ? "Current" : "To"}
142
- </dt>
143
- <dd>
144
- <HashValueDisplay
145
- value={event.toBundleId}
146
- buttonClassName={touch ? "min-h-11 px-3" : undefined}
147
- />
148
- </dd>
149
510
  </dl>
150
511
  );
151
512
  }