gloomberb 0.5.1 → 0.6.1

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 (506) hide show
  1. package/README.md +91 -11
  2. package/package.json +13 -5
  3. package/src/app.tsx +414 -191
  4. package/src/architecture/import-boundaries.test.ts +118 -0
  5. package/src/assets/gloomberb-logo.png +0 -0
  6. package/src/assets/gloomberb-logo.svg +73 -0
  7. package/src/brokers/account-cache.ts +157 -0
  8. package/src/brokers/profile-form.test.ts +73 -0
  9. package/src/brokers/profile-form.ts +109 -0
  10. package/src/brokers/remote-broker-adapter.ts +91 -0
  11. package/src/brokers/sync-broker-instance.test.ts +124 -1
  12. package/src/brokers/sync-broker-instance.ts +113 -17
  13. package/src/capabilities/factories.ts +100 -0
  14. package/src/capabilities/index.ts +4 -0
  15. package/src/capabilities/registry.test.ts +137 -0
  16. package/src/capabilities/registry.ts +131 -0
  17. package/src/capabilities/service-capabilities.ts +27 -0
  18. package/src/capabilities/types.ts +84 -0
  19. package/src/cli/commands/ticker.ts +11 -3
  20. package/src/cli/context.ts +19 -13
  21. package/src/cli/helpers.ts +1 -0
  22. package/src/cli/types.ts +2 -2
  23. package/src/components/chart/chart-controller.ts +4 -24
  24. package/src/components/chart/chart-data.ts +3 -14
  25. package/src/components/chart/chart-indicator-selector.tsx +28 -6
  26. package/src/components/chart/chart-pane-settings.ts +15 -28
  27. package/src/components/chart/chart-renderer.ts +74 -99
  28. package/src/components/chart/chart-resolution.ts +10 -10
  29. package/src/components/chart/chart-scroll.test.ts +6 -5
  30. package/src/components/chart/chart-scroll.ts +2 -2
  31. package/src/components/chart/chart-types.ts +0 -1
  32. package/src/components/chart/chart-viewport.ts +2 -1
  33. package/src/components/chart/chart.test.ts +37 -0
  34. package/src/components/chart/comparison-chart-data.ts +3 -17
  35. package/src/components/chart/comparison-chart-renderer.test.ts +27 -4
  36. package/src/components/chart/comparison-chart-renderer.ts +1 -1
  37. package/src/components/chart/comparison-stock-chart.tsx +318 -158
  38. package/src/components/chart/cursor-motion.ts +3 -2
  39. package/src/components/chart/indicators/bands.test.ts +0 -14
  40. package/src/components/chart/indicators/moving-averages.test.ts +0 -15
  41. package/src/components/chart/indicators/options.ts +3 -3
  42. package/src/components/chart/indicators/oscillators.test.ts +0 -21
  43. package/src/components/chart/indicators/types.ts +1 -2
  44. package/src/components/chart/native/chart-rasterizer.ts +37 -44
  45. package/src/components/chart/native/kitty-adapter.ts +2 -5
  46. package/src/components/chart/native/kitty-manager.ts +1 -1
  47. package/src/components/chart/native/kitty-protocol.ts +0 -1
  48. package/src/components/chart/native/kitty-support.ts +1 -1
  49. package/src/components/chart/native/kitty.test.ts +53 -13
  50. package/src/components/chart/native/renderer-selection.ts +1 -1
  51. package/src/components/chart/native/surface-manager.ts +1 -1
  52. package/src/components/chart/native/surface-visibility.ts +48 -0
  53. package/src/components/chart/static-chart-surface.test.tsx +51 -0
  54. package/src/components/chart/static-chart-surface.tsx +191 -0
  55. package/src/components/chart/stock-chart-renderer-switch.test.tsx +242 -35
  56. package/src/components/chart/stock-chart.tsx +452 -191
  57. package/src/components/command-bar/__snapshots__/command-bar.test.tsx.snap +4 -4
  58. package/src/components/command-bar/command-bar.test.tsx +269 -20
  59. package/src/components/command-bar/command-bar.tsx +830 -353
  60. package/src/components/command-bar/command-registry.ts +10 -20
  61. package/src/components/command-bar/helpers.test.ts +1 -1
  62. package/src/components/command-bar/helpers.ts +9 -11
  63. package/src/components/command-bar/pane-template-display.ts +4 -8
  64. package/src/components/command-bar/root-shortcuts.ts +12 -11
  65. package/src/components/command-bar/view-model.test.ts +8 -42
  66. package/src/components/command-bar/view-model.ts +8 -36
  67. package/src/components/command-bar/workflow-ops.test.ts +76 -2
  68. package/src/components/command-bar/workflow-ops.ts +40 -9
  69. package/src/components/command-bar/workflow-types.ts +2 -1
  70. package/src/components/data-table-stack-view.test.tsx +206 -0
  71. package/src/components/data-table-stack-view.tsx +152 -0
  72. package/src/components/data-table-view.test.tsx +188 -0
  73. package/src/components/data-table-view.tsx +279 -0
  74. package/src/components/feed-data-table-stack-view.test.tsx +225 -0
  75. package/src/components/feed-data-table-stack-view.tsx +365 -0
  76. package/src/components/index.ts +26 -31
  77. package/src/components/layout/detached-pane-shell.tsx +185 -0
  78. package/src/components/layout/floating-pane.tsx +87 -14
  79. package/src/components/layout/header.tsx +139 -49
  80. package/src/components/layout/pane-content.tsx +42 -0
  81. package/src/components/layout/pane-footer.test.tsx +195 -0
  82. package/src/components/layout/pane-footer.tsx +425 -0
  83. package/src/components/layout/pane-header.test.tsx +39 -0
  84. package/src/components/layout/pane-header.tsx +192 -14
  85. package/src/components/layout/pane-keyboard-scroll.test.tsx +226 -0
  86. package/src/components/layout/pane-sizing.ts +9 -10
  87. package/src/components/layout/pane-title.ts +35 -0
  88. package/src/components/layout/pane.tsx +52 -11
  89. package/src/components/layout/shell.test.tsx +315 -107
  90. package/src/components/layout/shell.tsx +1010 -368
  91. package/src/components/layout/status-bar.test.tsx +17 -10
  92. package/src/components/layout/status-bar.tsx +367 -100
  93. package/src/components/layout/titlebar-overlay.ts +2 -0
  94. package/src/components/markdown-editor.tsx +29 -14
  95. package/src/components/markdown-text.tsx +25 -24
  96. package/src/components/onboarding/onboarding-wizard.test.tsx +8 -3
  97. package/src/components/onboarding/onboarding-wizard.tsx +347 -473
  98. package/src/components/pane-settings-dialog.tsx +521 -89
  99. package/src/components/pane-template-wizard.test.tsx +1 -1
  100. package/src/components/pane-template-wizard.tsx +38 -37
  101. package/src/components/price-selector-dialog.tsx +22 -21
  102. package/src/components/ticker-badge-list.tsx +53 -0
  103. package/src/components/ticker-badge-text.test.tsx +44 -1
  104. package/src/components/ticker-badge-text.tsx +78 -38
  105. package/src/components/ticker-badge.tsx +28 -7
  106. package/src/components/ticker-list-table-view.tsx +248 -0
  107. package/src/components/ticker-list-table.test.tsx +47 -1
  108. package/src/components/ticker-list-table.tsx +212 -41
  109. package/src/components/toggle-list.tsx +114 -8
  110. package/src/components/ui/button.tsx +24 -16
  111. package/src/components/ui/choice-dialog.tsx +89 -0
  112. package/src/components/ui/data-table.tsx +313 -114
  113. package/src/components/ui/external-link.tsx +52 -13
  114. package/src/components/ui/fields.tsx +44 -30
  115. package/src/components/ui/frame.tsx +24 -57
  116. package/src/components/ui/index.ts +15 -50
  117. package/src/components/ui/list-view.tsx +65 -25
  118. package/src/components/ui/loading.tsx +5 -60
  119. package/src/components/ui/message-composer.test.tsx +81 -0
  120. package/src/components/ui/message-composer.tsx +139 -0
  121. package/src/components/ui/multi-select-dialog.tsx +100 -32
  122. package/src/components/ui/multi-select.ts +112 -0
  123. package/src/components/ui/native-select.tsx +120 -0
  124. package/src/components/ui/page-stack-view.tsx +49 -19
  125. package/src/components/ui/remote-image.tsx +50 -0
  126. package/src/components/ui/row-value-cache.test.ts +17 -0
  127. package/src/components/ui/row-value-cache.ts +41 -0
  128. package/src/components/ui/shortcut-hint.tsx +55 -0
  129. package/src/components/ui/status.tsx +12 -67
  130. package/src/components/ui/table-layout.ts +59 -0
  131. package/src/components/ui/tabs.tsx +249 -27
  132. package/src/components/ui/toggle.tsx +19 -127
  133. package/src/components/ui/ui.test.tsx +266 -53
  134. package/src/components/use-double-click-activation.ts +7 -2
  135. package/src/components/use-external-link-footer.ts +79 -0
  136. package/src/core/app-services.ts +95 -0
  137. package/src/core/state/app-state.ts +886 -0
  138. package/src/{state → core/state}/session-persistence.ts +7 -6
  139. package/src/data/config-layout.ts +225 -0
  140. package/src/data/config-store-node.ts +390 -0
  141. package/src/data/config-store.test.ts +72 -0
  142. package/src/data/config-store.ts +35 -478
  143. package/src/data/sqlite-json.ts +2 -5
  144. package/src/data/sqlite-retry.ts +1 -0
  145. package/src/index.tsx +2 -68
  146. package/src/market-data/coordinator-subscriptions.test.ts +125 -0
  147. package/src/market-data/coordinator.test.ts +73 -4
  148. package/src/market-data/coordinator.ts +190 -24
  149. package/src/market-data/hooks.test.tsx +1 -1
  150. package/src/market-data/hooks.tsx +109 -87
  151. package/src/market-data/query-store.ts +3 -3
  152. package/src/market-data/request-types.test.ts +0 -14
  153. package/src/market-data/result-types.ts +1 -0
  154. package/src/news/aggregator.test.ts +267 -0
  155. package/src/news/aggregator.ts +452 -0
  156. package/src/news/hooks.ts +39 -0
  157. package/src/news/ticker-symbols.ts +21 -0
  158. package/src/news/types.ts +77 -0
  159. package/src/notifications/app-notifier.ts +21 -10
  160. package/src/pane-settings.test.ts +0 -2
  161. package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +124 -134
  162. package/src/plugins/builtin/ai/gloomberb-cli.ts +14 -13
  163. package/src/plugins/builtin/ai/providers.ts +1 -9
  164. package/src/plugins/builtin/ai/runner.ts +41 -5
  165. package/src/plugins/builtin/ai/screener-pane.test.tsx +37 -55
  166. package/src/plugins/builtin/ai/screener-pane.tsx +231 -276
  167. package/src/plugins/builtin/ai/settings.ts +0 -1
  168. package/src/plugins/builtin/ai/utils.ts +1 -71
  169. package/src/plugins/builtin/alerts/alert-engine.test.ts +1 -38
  170. package/src/plugins/builtin/alerts/index.test.tsx +61 -82
  171. package/src/plugins/builtin/alerts/index.tsx +263 -155
  172. package/src/plugins/builtin/alerts/types.ts +7 -0
  173. package/src/plugins/builtin/analytics/index.test.tsx +13 -8
  174. package/src/plugins/builtin/analytics/index.tsx +78 -120
  175. package/src/plugins/builtin/analytics/metrics.test.ts +0 -4
  176. package/src/plugins/builtin/ask-ai.test.tsx +55 -54
  177. package/src/plugins/builtin/broker-manager/index.test.tsx +168 -0
  178. package/src/plugins/builtin/broker-manager/index.tsx +759 -0
  179. package/src/plugins/builtin/broker-manager/model.test.ts +107 -0
  180. package/src/plugins/builtin/broker-manager/model.ts +142 -0
  181. package/src/plugins/builtin/chat-controller.test.ts +129 -0
  182. package/src/plugins/builtin/chat-controller.ts +85 -14
  183. package/src/plugins/builtin/chat.test.tsx +283 -36
  184. package/src/plugins/builtin/chat.tsx +363 -170
  185. package/src/plugins/builtin/cloud-auth-actions.tsx +72 -0
  186. package/src/plugins/builtin/cloud-tweets.tsx +896 -0
  187. package/src/plugins/builtin/comparison-chart.test.tsx +46 -57
  188. package/src/plugins/builtin/comparison-chart.tsx +11 -11
  189. package/src/plugins/builtin/correlation/compute.test.ts +0 -17
  190. package/src/plugins/builtin/correlation/index.tsx +51 -46
  191. package/src/plugins/builtin/correlation/settings.ts +1 -2
  192. package/src/plugins/builtin/debug.tsx +99 -70
  193. package/src/plugins/builtin/earnings/earnings-cache.test.ts +2 -2
  194. package/src/plugins/builtin/earnings/earnings-cache.ts +12 -3
  195. package/src/plugins/builtin/earnings/earnings-data.test.ts +42 -11
  196. package/src/plugins/builtin/earnings/earnings-data.ts +70 -5
  197. package/src/plugins/builtin/earnings/index.tsx +187 -94
  198. package/src/plugins/builtin/econ/calendar-source.ts +9 -116
  199. package/src/plugins/builtin/econ/fred-client.test.ts +1 -14
  200. package/src/plugins/builtin/econ/fred-series-map.ts +1 -0
  201. package/src/plugins/builtin/econ/index.tsx +236 -421
  202. package/src/plugins/builtin/econ/types.ts +1 -0
  203. package/src/plugins/builtin/fx-matrix/index.tsx +43 -45
  204. package/src/plugins/builtin/fx-matrix/pairs.ts +1 -0
  205. package/src/plugins/builtin/help.test.tsx +120 -60
  206. package/src/plugins/builtin/help.tsx +266 -82
  207. package/src/plugins/builtin/holders/index.test.ts +45 -0
  208. package/src/plugins/builtin/holders/index.tsx +949 -0
  209. package/src/plugins/builtin/insider/index.tsx +207 -253
  210. package/src/plugins/builtin/insider/insider-data.test.ts +1 -11
  211. package/src/plugins/builtin/insider/insider-data.ts +1 -0
  212. package/src/plugins/builtin/layout-manager.tsx +12 -40
  213. package/src/plugins/builtin/market-movers/index.tsx +70 -144
  214. package/src/plugins/builtin/market-movers/screener.test.ts +0 -18
  215. package/src/plugins/builtin/news-wire/breaking-notifications.test.ts +98 -0
  216. package/src/plugins/builtin/news-wire/breaking-notifications.ts +110 -0
  217. package/src/plugins/builtin/news-wire/breaking-pane.tsx +157 -0
  218. package/src/plugins/builtin/news-wire/categories.ts +114 -0
  219. package/src/plugins/builtin/news-wire/default-feeds.ts +3 -0
  220. package/src/plugins/builtin/news-wire/digest-store.ts +44 -0
  221. package/src/plugins/builtin/news-wire/feed-config.test.ts +90 -0
  222. package/src/plugins/builtin/news-wire/feed-config.ts +216 -0
  223. package/src/plugins/builtin/news-wire/feed-pane.tsx +21 -0
  224. package/src/plugins/builtin/news-wire/hash.ts +9 -0
  225. package/src/plugins/builtin/news-wire/index.tsx +92 -0
  226. package/src/plugins/builtin/news-wire/industry-pane.tsx +140 -0
  227. package/src/plugins/builtin/news-wire/news-detail-view.tsx +256 -0
  228. package/src/plugins/builtin/news-wire/news-footer.ts +28 -0
  229. package/src/plugins/builtin/news-wire/news-preset-pane.tsx +94 -0
  230. package/src/plugins/builtin/news-wire/news-query-presets.ts +40 -0
  231. package/src/plugins/builtin/news-wire/news-table.test.tsx +206 -0
  232. package/src/plugins/builtin/news-wire/news-table.tsx +296 -0
  233. package/src/plugins/builtin/news-wire/persisted-articles.ts +92 -0
  234. package/src/plugins/builtin/news-wire/read-state.test.ts +30 -0
  235. package/src/plugins/builtin/news-wire/read-state.ts +76 -0
  236. package/src/plugins/builtin/news-wire/rss-parser.test.ts +184 -0
  237. package/src/plugins/builtin/news-wire/rss-parser.ts +213 -0
  238. package/src/plugins/builtin/news-wire/rss-source.test.ts +159 -0
  239. package/src/plugins/builtin/news-wire/rss-source.ts +181 -0
  240. package/src/plugins/builtin/news-wire/top-pane.tsx +21 -0
  241. package/src/plugins/builtin/news.tsx +98 -25
  242. package/src/plugins/builtin/notes-files.ts +51 -10
  243. package/src/plugins/builtin/notes.tsx +332 -131
  244. package/src/plugins/builtin/options.test.tsx +185 -0
  245. package/src/plugins/builtin/options.tsx +346 -206
  246. package/src/plugins/builtin/plugin-groups.ts +92 -0
  247. package/src/plugins/builtin/portfolio-list/header.tsx +72 -37
  248. package/src/plugins/builtin/portfolio-list/index.tsx +25 -42
  249. package/src/plugins/builtin/portfolio-list/metrics.ts +1 -1
  250. package/src/plugins/builtin/portfolio-list/pane.tsx +246 -164
  251. package/src/plugins/builtin/portfolio-list/settings.ts +19 -51
  252. package/src/plugins/builtin/portfolio-list/summary.tsx +21 -16
  253. package/src/plugins/builtin/portfolio-list/table.tsx +66 -25
  254. package/src/plugins/builtin/portfolio-list/use-throttled-cursor-symbol.test.tsx +1 -1
  255. package/src/plugins/builtin/portfolio-list/use-throttled-cursor-symbol.ts +1 -1
  256. package/src/plugins/builtin/portfolio-list.test.ts +60 -1
  257. package/src/plugins/builtin/portfolio-list.test.tsx +122 -55
  258. package/src/plugins/builtin/quote-monitor.test.tsx +2 -27
  259. package/src/plugins/builtin/research/index.tsx +724 -0
  260. package/src/plugins/builtin/sec.tsx +67 -19
  261. package/src/plugins/builtin/sectors/index.tsx +42 -80
  262. package/src/plugins/builtin/sectors/sector-data.ts +1 -0
  263. package/src/plugins/builtin/ticker-detail/chart-tab.tsx +25 -39
  264. package/src/plugins/builtin/ticker-detail/financials-tab.tsx +108 -58
  265. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +383 -271
  266. package/src/plugins/builtin/ticker-detail/pane.tsx +143 -49
  267. package/src/plugins/builtin/ticker-detail/quote-monitor.tsx +43 -27
  268. package/src/plugins/builtin/ticker-detail/settings.ts +3 -6
  269. package/src/plugins/builtin/ticker-detail-chart-tab-switch.test.tsx +82 -10
  270. package/src/plugins/builtin/ticker-detail.test.tsx +258 -33
  271. package/src/plugins/builtin/ticker-surface.ts +68 -0
  272. package/src/plugins/builtin/world-indices/index.tsx +44 -82
  273. package/src/plugins/builtin/world-indices/indices.ts +1 -0
  274. package/src/plugins/builtin/yahoo.ts +55 -1
  275. package/src/plugins/builtin/yield-curve/index.tsx +87 -145
  276. package/src/plugins/builtin/yield-curve/treasury-data.ts +6 -77
  277. package/src/plugins/catalog-ui.test.ts +24 -0
  278. package/src/plugins/catalog-ui.ts +44 -0
  279. package/src/plugins/catalog.ts +2 -50
  280. package/src/plugins/ibkr/__snapshots__/trade-tab.test.tsx.snap +5 -5
  281. package/src/plugins/ibkr/account-cache.test.ts +15 -14
  282. package/src/plugins/ibkr/account-cache.ts +15 -120
  283. package/src/plugins/ibkr/broker-adapter.ts +67 -0
  284. package/src/plugins/ibkr/config.test.ts +0 -18
  285. package/src/plugins/ibkr/dialogs.tsx +14 -56
  286. package/src/plugins/ibkr/flex.test.ts +57 -2
  287. package/src/plugins/ibkr/flex.ts +116 -12
  288. package/src/plugins/ibkr/gateway-helpers.ts +8 -3
  289. package/src/plugins/ibkr/gateway-service-native.ts +2381 -0
  290. package/src/plugins/ibkr/gateway-service.test.ts +47 -9
  291. package/src/plugins/ibkr/gateway-service.ts +264 -2235
  292. package/src/plugins/ibkr/gateway-types.ts +27 -0
  293. package/src/plugins/ibkr/index.test.tsx +3 -11
  294. package/src/plugins/ibkr/index.tsx +1 -0
  295. package/src/plugins/ibkr/price-normalization.test.ts +1 -6
  296. package/src/plugins/ibkr/price-normalization.ts +1 -0
  297. package/src/plugins/ibkr/trade-badge.tsx +6 -5
  298. package/src/plugins/ibkr/trade-tab.test.tsx +55 -3
  299. package/src/plugins/ibkr/trade-tab.tsx +166 -117
  300. package/src/plugins/ibkr/trading-pane.tsx +117 -83
  301. package/src/plugins/pane-manager.test.ts +3 -1
  302. package/src/plugins/pane-manager.ts +93 -19
  303. package/src/plugins/plugin-runtime.test.tsx +176 -74
  304. package/src/plugins/plugin-runtime.tsx +228 -10
  305. package/src/plugins/prediction-markets/cache.ts +49 -0
  306. package/src/plugins/prediction-markets/categories.ts +0 -10
  307. package/src/plugins/prediction-markets/chart.test.tsx +1 -1
  308. package/src/plugins/prediction-markets/chart.tsx +21 -20
  309. package/src/plugins/prediction-markets/cli.ts +1 -0
  310. package/src/plugins/prediction-markets/controller-data.ts +135 -89
  311. package/src/plugins/prediction-markets/controller.ts +37 -108
  312. package/src/plugins/prediction-markets/detail/book.tsx +23 -22
  313. package/src/plugins/prediction-markets/detail/outcomes.tsx +33 -32
  314. package/src/plugins/prediction-markets/detail/overview.tsx +17 -12
  315. package/src/plugins/prediction-markets/detail/pane.tsx +59 -45
  316. package/src/plugins/prediction-markets/detail/rules.tsx +22 -7
  317. package/src/plugins/prediction-markets/detail/shared.tsx +3 -2
  318. package/src/plugins/prediction-markets/detail/trades.tsx +12 -11
  319. package/src/plugins/prediction-markets/detail.test.tsx +1 -1
  320. package/src/plugins/prediction-markets/keyboard.ts +1 -0
  321. package/src/plugins/prediction-markets/launch.test.ts +1 -1
  322. package/src/plugins/prediction-markets/launch.ts +1 -1
  323. package/src/plugins/prediction-markets/metrics.ts +25 -12
  324. package/src/plugins/prediction-markets/pane.test.tsx +16 -7
  325. package/src/plugins/prediction-markets/pane.tsx +180 -82
  326. package/src/plugins/prediction-markets/plugin.test.tsx +37 -45
  327. package/src/plugins/prediction-markets/services/fetch.ts +27 -10
  328. package/src/plugins/prediction-markets/services/kalshi-adapter.ts +20 -3
  329. package/src/plugins/prediction-markets/services/polymarket-adapter.ts +29 -11
  330. package/src/plugins/prediction-markets/settings.ts +0 -5
  331. package/src/plugins/prediction-markets/test-helpers.tsx +19 -44
  332. package/src/plugins/registry.test.ts +307 -0
  333. package/src/plugins/registry.ts +293 -82
  334. package/src/react/input.ts +61 -0
  335. package/src/react/plugins/plugin-slot.tsx +21 -0
  336. package/src/react/use-raf-callback.ts +44 -0
  337. package/src/renderers/electrobun/bun/application-menu-click.test.ts +41 -0
  338. package/src/renderers/electrobun/bun/application-menu-click.ts +55 -0
  339. package/src/renderers/electrobun/bun/application-menu.ts +118 -0
  340. package/src/renderers/electrobun/bun/context-menu-click.test.ts +67 -0
  341. package/src/renderers/electrobun/bun/context-menu-click.ts +61 -0
  342. package/src/renderers/electrobun/bun/context-menu-normalize.test.ts +52 -0
  343. package/src/renderers/electrobun/bun/context-menu-normalize.ts +67 -0
  344. package/src/renderers/electrobun/bun/core-capabilities.ts +328 -0
  345. package/src/renderers/electrobun/bun/desktop-workspace.test.ts +63 -0
  346. package/src/renderers/electrobun/bun/desktop-workspace.ts +162 -0
  347. package/src/renderers/electrobun/bun/index.ts +1149 -0
  348. package/src/renderers/electrobun/bun/window-frame.test.ts +40 -0
  349. package/src/renderers/electrobun/bun/window-frame.ts +46 -0
  350. package/src/renderers/electrobun/shared/protocol.ts +72 -0
  351. package/src/renderers/electrobun/view/ai-host.ts +93 -0
  352. package/src/renderers/electrobun/view/app-services.ts +348 -0
  353. package/src/renderers/electrobun/view/application-menu-bridge.ts +12 -0
  354. package/src/renderers/electrobun/view/backend-rpc.ts +173 -0
  355. package/src/renderers/electrobun/view/broker-remote-client.ts +154 -0
  356. package/src/renderers/electrobun/view/config-host.ts +35 -0
  357. package/src/renderers/electrobun/view/context-menu.test.ts +140 -0
  358. package/src/renderers/electrobun/view/context-menu.ts +164 -0
  359. package/src/renderers/electrobun/view/data-table.tsx +773 -0
  360. package/src/renderers/electrobun/view/desktop-controls.tsx +651 -0
  361. package/src/renderers/electrobun/view/desktop-window-bridge.ts +59 -0
  362. package/src/renderers/electrobun/view/desktop-window-snapshot.test.ts +57 -0
  363. package/src/renderers/electrobun/view/desktop-window-snapshot.ts +41 -0
  364. package/src/renderers/electrobun/view/dialog-host.tsx +62 -0
  365. package/src/renderers/electrobun/view/http-fetch.ts +113 -0
  366. package/src/renderers/electrobun/view/input-host.tsx +112 -0
  367. package/src/renderers/electrobun/view/key-event.test.ts +34 -0
  368. package/src/renderers/electrobun/view/key-event.ts +134 -0
  369. package/src/renderers/electrobun/view/main.tsx +104 -0
  370. package/src/renderers/electrobun/view/native-renderer.ts +110 -0
  371. package/src/renderers/electrobun/view/native-stubs/chart-kitty-support.ts +9 -0
  372. package/src/renderers/electrobun/view/native-stubs/chart-surface-manager.ts +25 -0
  373. package/src/renderers/electrobun/view/native-stubs/chart-surface-sync.ts +1 -0
  374. package/src/renderers/electrobun/view/notes-files.ts +56 -0
  375. package/src/renderers/electrobun/view/resource-store.test.ts +44 -0
  376. package/src/renderers/electrobun/view/resource-store.ts +106 -0
  377. package/src/renderers/electrobun/view/rpc-codec.ts +42 -0
  378. package/src/renderers/electrobun/view/scrollbar-activity.ts +23 -0
  379. package/src/renderers/electrobun/view/toast-host.tsx +65 -0
  380. package/src/renderers/electrobun/view/ui-host.tsx +1509 -0
  381. package/src/renderers/electrobun/view/update-host.ts +38 -0
  382. package/src/renderers/opentui/dialog-host.test.tsx +44 -0
  383. package/src/renderers/opentui/dialog-host.tsx +56 -0
  384. package/src/renderers/opentui/host.tsx +140 -0
  385. package/src/renderers/opentui/image-loader.test.ts +25 -0
  386. package/src/renderers/opentui/image-loader.ts +105 -0
  387. package/src/renderers/opentui/image-surface.tsx +266 -0
  388. package/src/renderers/opentui/input-host.tsx +63 -0
  389. package/src/renderers/opentui/start.tsx +71 -0
  390. package/src/renderers/opentui/test-utils.tsx +76 -0
  391. package/src/renderers/opentui/toast-host.tsx +10 -0
  392. package/src/renderers/opentui/ui-host.tsx +98 -0
  393. package/src/sources/gloomberb-cloud.test.ts +288 -17
  394. package/src/sources/gloomberb-cloud.ts +176 -9
  395. package/src/sources/provider-errors.ts +1 -0
  396. package/src/sources/provider-router.test.ts +220 -81
  397. package/src/sources/provider-router.ts +294 -111
  398. package/src/sources/sec-edgar.ts +19 -6
  399. package/src/sources/yahoo-finance.test.ts +0 -5
  400. package/src/sources/yahoo-finance.ts +420 -11
  401. package/src/state/app-activity.ts +7 -7
  402. package/src/state/app-bootstrap.ts +114 -40
  403. package/src/state/app-context-selector.test.tsx +70 -1
  404. package/src/state/app-context.test.ts +71 -3
  405. package/src/state/app-context.test.tsx +14 -7
  406. package/src/state/app-context.tsx +209 -869
  407. package/src/state/config-save-scheduler.ts +35 -0
  408. package/src/state/pane-scroll-registry.tsx +254 -0
  409. package/src/state/persist-scheduler.test.ts +67 -0
  410. package/src/state/persist-scheduler.ts +69 -0
  411. package/src/state/selectors-ui.ts +55 -0
  412. package/src/state/selectors.ts +15 -71
  413. package/src/state/session-persistence.test.ts +1 -1
  414. package/src/state/ticker-refresh-queue.ts +52 -3
  415. package/src/state/use-inline-tickers.ts +18 -16
  416. package/src/state/use-quote-streaming.test.ts +0 -6
  417. package/src/state/use-quote-streaming.test.tsx +1 -1
  418. package/src/state/use-quote-streaming.ts +3 -2
  419. package/src/state/use-session-snapshot.ts +32 -17
  420. package/src/test-support/plugin-runtime.ts +149 -0
  421. package/src/theme/color-utils.ts +1 -0
  422. package/src/theme/colors.ts +16 -0
  423. package/src/types/broker.ts +16 -1
  424. package/src/types/capability-route-source.ts +23 -0
  425. package/src/types/config.test.ts +23 -0
  426. package/src/types/config.ts +145 -10
  427. package/src/types/context-menu.ts +95 -0
  428. package/src/types/data-provider.ts +34 -3
  429. package/src/types/desktop-menu.ts +13 -0
  430. package/src/types/desktop-window.ts +29 -0
  431. package/src/types/financials.ts +123 -2
  432. package/src/types/instrument.ts +1 -0
  433. package/src/types/news-source.ts +9 -0
  434. package/src/types/persistence.ts +1 -0
  435. package/src/types/plugin.ts +32 -8
  436. package/src/ui/ascii-font.ts +85 -0
  437. package/src/ui/context-menu.test.ts +94 -0
  438. package/src/ui/context-menu.tsx +433 -0
  439. package/src/ui/dialog.tsx +55 -0
  440. package/src/ui/host.tsx +364 -0
  441. package/src/ui/index.tsx +134 -0
  442. package/src/ui/toast.tsx +40 -0
  443. package/src/updater.test.ts +69 -0
  444. package/src/updater.ts +61 -18
  445. package/src/utils/api-client.test.ts +99 -9
  446. package/src/utils/api-client.ts +378 -18
  447. package/src/utils/back-navigation.ts +6 -0
  448. package/src/utils/cli-output.ts +1 -0
  449. package/src/utils/currency-units.test.ts +1 -6
  450. package/src/utils/currency-units.ts +1 -0
  451. package/src/utils/debug-log.ts +68 -0
  452. package/src/utils/dom-screenshot.ts +326 -0
  453. package/src/utils/exchange-rate-map.ts +1 -0
  454. package/src/utils/exchanges.ts +214 -0
  455. package/src/utils/format.test.ts +7 -0
  456. package/src/utils/format.ts +1 -0
  457. package/src/utils/fuzzy-search.ts +1 -0
  458. package/src/utils/html-entities.test.ts +8 -0
  459. package/src/utils/html-entities.ts +32 -0
  460. package/src/utils/http-transport.ts +11 -0
  461. package/src/utils/main-thread-monitor.ts +127 -0
  462. package/src/utils/perf-marks.ts +54 -0
  463. package/src/utils/quote-freshness.ts +27 -50
  464. package/src/utils/quote-resolution.test.ts +5 -5
  465. package/src/utils/quote-resolution.ts +0 -1
  466. package/src/utils/quote-time.ts +1 -5
  467. package/src/utils/sec.test.ts +0 -12
  468. package/src/utils/selection-clipboard.ts +14 -6
  469. package/src/utils/shortcut-labels.test.ts +20 -0
  470. package/src/utils/shortcut-labels.ts +67 -0
  471. package/src/utils/slugify.ts +1 -0
  472. package/src/utils/terminal-input-reset.ts +1 -0
  473. package/src/utils/text-wrap.ts +82 -0
  474. package/src/utils/throttled-fetch.test.ts +19 -0
  475. package/src/utils/throttled-fetch.ts +11 -9
  476. package/src/utils/ticker-list.test.ts +1 -7
  477. package/src/utils/ticker-list.ts +1 -0
  478. package/src/utils/timestamp.ts +29 -0
  479. package/src/utils/tweet-text.test.ts +13 -0
  480. package/src/utils/tweet-text.ts +18 -0
  481. package/src/utils/url.ts +11 -0
  482. package/src/version.ts +1 -1
  483. package/src/components/chart/chart-control-hint.tsx +0 -39
  484. package/src/components/detail-feed-view.test.tsx +0 -180
  485. package/src/components/detail-feed-view.tsx +0 -531
  486. package/src/components/layout/pixel-mouse-mode.test.ts +0 -122
  487. package/src/components/layout/pixel-mouse.test.ts +0 -40
  488. package/src/components/spinner.tsx +0 -2
  489. package/src/components/tab-bar.tsx +0 -17
  490. package/src/components/ui/multi-select-chips.tsx +0 -69
  491. package/src/plugins/builtin/ai/index.test.tsx +0 -139
  492. package/src/plugins/builtin/ask-ai.tsx +0 -9
  493. package/src/plugins/builtin/correlation/plugin.test.ts +0 -44
  494. package/src/plugins/builtin/correlation/settings.test.ts +0 -34
  495. package/src/plugins/builtin/econ/calendar-source.test.ts +0 -219
  496. package/src/plugins/builtin/econ/fred-client.ts +0 -79
  497. package/src/plugins/builtin/fred-settings.ts +0 -10
  498. package/src/plugins/builtin/options-availability.test.tsx +0 -179
  499. package/src/plugins/builtin/options-availability.ts +0 -158
  500. package/src/plugins/builtin/portfolio-list/metrics.test.ts +0 -61
  501. package/src/plugins/builtin/yield-curve/treasury-data.test.ts +0 -212
  502. package/src/plugins/prediction-markets/status.ts +0 -24
  503. package/src/plugins/prediction-markets/table.tsx +0 -87
  504. package/src/utils/quote-time.test.ts +0 -22
  505. package/src/utils/selection-clipboard.test.ts +0 -43
  506. package/src/utils/terminal-input-reset.test.ts +0 -50
@@ -1,5 +1,6 @@
1
+ import { Box, Text } from "../../ui";
1
2
  import { useMemo } from "react";
2
- import { TextAttributes } from "@opentui/core";
3
+ import { TextAttributes } from "../../ui";
3
4
  import { StockChart } from "../../components/chart/stock-chart";
4
5
  import { EmptyState } from "../../components/ui/status";
5
6
  import { colors } from "../../theme/colors";
@@ -43,27 +44,27 @@ function PredictionRangeTabs({
43
44
  onRangeSelect: (range: PredictionHistoryRange) => void;
44
45
  }) {
45
46
  return (
46
- <box flexDirection="row" gap={1}>
47
+ <Box flexDirection="row" gap={1}>
47
48
  {RANGES.map((entry) => {
48
49
  const active = entry === activeRange;
49
50
  return (
50
- <box
51
+ <Box
51
52
  key={entry}
52
53
  onMouseDown={(event) => {
53
54
  event.preventDefault();
54
55
  onRangeSelect(entry);
55
56
  }}
56
57
  >
57
- <text
58
+ <Text
58
59
  fg={active ? colors.textBright : colors.textDim}
59
60
  attributes={active ? TextAttributes.BOLD : 0}
60
61
  >
61
62
  {entry}
62
- </text>
63
- </box>
63
+ </Text>
64
+ </Box>
64
65
  );
65
66
  })}
66
- </box>
67
+ </Box>
67
68
  );
68
69
  }
69
70
 
@@ -84,20 +85,20 @@ export function PredictionMarketChart({
84
85
 
85
86
  if (pricePoints.length === 0) {
86
87
  return (
87
- <box flexDirection="column" height={height}>
88
- <box flexDirection="row" height={1}>
88
+ <Box flexDirection="column" height={height}>
89
+ <Box flexDirection="row" height={1}>
89
90
  <PredictionRangeTabs
90
91
  activeRange={range}
91
92
  onRangeSelect={onRangeSelect}
92
93
  />
93
- </box>
94
- <box flexGrow={1} justifyContent="center">
94
+ </Box>
95
+ <Box flexGrow={1} justifyContent="center">
95
96
  <EmptyState
96
97
  title="No chart history."
97
98
  hint="This venue did not return price history for the selected market."
98
99
  />
99
- </box>
100
- </box>
100
+ </Box>
101
+ </Box>
101
102
  );
102
103
  }
103
104
 
@@ -108,14 +109,14 @@ export function PredictionMarketChart({
108
109
  const chartHeight = Math.max(height - 1, 2);
109
110
 
110
111
  return (
111
- <box flexDirection="column" height={height}>
112
- <box flexDirection="row" height={1}>
112
+ <Box flexDirection="column" height={height}>
113
+ <Box flexDirection="row" height={1}>
113
114
  <PredictionRangeTabs
114
115
  activeRange={range}
115
116
  onRangeSelect={onRangeSelect}
116
117
  />
117
- <box flexGrow={1} />
118
- <text
118
+ <Box flexGrow={1} />
119
+ <Text
119
120
  fg={
120
121
  delta > 0
121
122
  ? colors.positive
@@ -125,8 +126,8 @@ export function PredictionMarketChart({
125
126
  }
126
127
  >
127
128
  {`${formatNumber(last?.close ?? 0, 3)} ${formatPercentRaw(deltaPct)}`}
128
- </text>
129
- </box>
129
+ </Text>
130
+ </Box>
130
131
 
131
132
  <StockChart
132
133
  width={width}
@@ -136,6 +137,6 @@ export function PredictionMarketChart({
136
137
  historyOverride={pricePoints}
137
138
  currencyOverride="USD"
138
139
  />
139
- </box>
140
+ </Box>
140
141
  );
141
142
  }
@@ -1,3 +1,4 @@
1
+ import { Input } from "../../ui";
1
2
  import type { CliCommandDef } from "../../types/plugin";
2
3
  import { createPredictionLaunchRequest, parsePredictionCommandArgs } from "./launch";
3
4
 
@@ -1,9 +1,11 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { measurePerf } from "../../utils/perf-marks";
2
3
  import {
3
4
  buildPredictionCatalogCacheKey,
4
5
  buildPredictionCatalogResourceKey,
5
6
  buildPredictionDetailCacheKey,
6
7
  buildPredictionDetailResourceKey,
8
+ samePredictionCatalogSummaries,
7
9
  updatePredictionCatalogCacheEntries,
8
10
  updatePredictionDetailCacheEntries,
9
11
  updatePredictionErrorState,
@@ -140,6 +142,9 @@ export function usePredictionMarketsDataState({
140
142
  const [debouncedSearchQuery, setDebouncedSearchQuery] = useState(searchQuery);
141
143
 
142
144
  const selectedSummaryRef = useRef<PredictionMarketSummary | null>(null);
145
+ const activeCatalogRef = useRef<Record<string, PredictionMarketSummary[]>>(
146
+ {},
147
+ );
143
148
  const detailLoadDelayRef = useRef(0);
144
149
  const currentDetailCacheKeyRef = useRef<string | null>(null);
145
150
 
@@ -195,6 +200,10 @@ export function usePredictionMarketsDataState({
195
200
  const polymarketCatalog =
196
201
  catalogCache[polymarketCatalogKey] ?? persistedPolymarketCatalog;
197
202
  const kalshiCatalog = catalogCache[kalshiCatalogKey] ?? persistedKalshiCatalog;
203
+ activeCatalogRef.current = {
204
+ [polymarketCatalogKey]: polymarketCatalog,
205
+ [kalshiCatalogKey]: kalshiCatalog,
206
+ };
198
207
  const activeCatalogKeys = useMemo(
199
208
  () =>
200
209
  [
@@ -290,25 +299,38 @@ export function usePredictionMarketsDataState({
290
299
  }, [includeKalshi, includePolymarket, kalshiCatalog, polymarketCatalog]);
291
300
 
292
301
  const allRows = useMemo(
293
- () => buildPredictionListRows(allMarkets),
302
+ () =>
303
+ measurePerf("prediction.rows.build", () => buildPredictionListRows(allMarkets), {
304
+ marketCount: allMarkets.length,
305
+ }),
294
306
  [allMarkets],
295
307
  );
296
308
 
297
309
  const visibleRows = useMemo(() => {
298
- const filtered = filterPredictionMarkets(
299
- allRows,
310
+ return measurePerf("prediction.rows.filter-sort", () => {
311
+ const filtered = filterPredictionMarkets(
312
+ allRows,
313
+ browseTab,
314
+ effectiveVenueScope,
315
+ categoryId,
316
+ debouncedSearchQuery,
317
+ watchlistSet,
318
+ );
319
+ return sortPredictionMarkets(
320
+ filtered,
321
+ sortPreference.columnId
322
+ ? sortPreference
323
+ : getDefaultPredictionSort(browseTab),
324
+ );
325
+ }, {
300
326
  browseTab,
301
- effectiveVenueScope,
302
327
  categoryId,
303
- debouncedSearchQuery,
304
- watchlistSet,
305
- );
306
- return sortPredictionMarkets(
307
- filtered,
308
- sortPreference.columnId
309
- ? sortPreference
310
- : getDefaultPredictionSort(browseTab),
311
- );
328
+ rowCount: allRows.length,
329
+ search: debouncedSearchQuery.trim(),
330
+ sortColumnId: sortPreference.columnId,
331
+ sortDirection: sortPreference.direction,
332
+ venueScope: effectiveVenueScope,
333
+ });
312
334
  }, [
313
335
  allRows,
314
336
  browseTab,
@@ -319,28 +341,51 @@ export function usePredictionMarketsDataState({
319
341
  watchlistSet,
320
342
  ]);
321
343
 
322
- const selectedRow = useMemo(
323
- () => visibleRows.find((row) => row.key === selectedRowKey) ?? null,
324
- [selectedRowKey, visibleRows],
344
+ const visibleRowLookup = useMemo(
345
+ () =>
346
+ measurePerf("prediction.rows.index", () => {
347
+ const byKey = new Map<
348
+ string,
349
+ { row: PredictionListRow; index: number }
350
+ >();
351
+ for (let index = 0; index < visibleRows.length; index += 1) {
352
+ const row = visibleRows[index];
353
+ if (row) byKey.set(row.key, { row, index });
354
+ }
355
+ return byKey;
356
+ }, {
357
+ rowCount: visibleRows.length,
358
+ }),
359
+ [visibleRows],
325
360
  );
326
- const selectedSummary = useMemo(
327
- () => {
328
- if (!detailOpen || !selectedRow) {
329
- return null;
361
+
362
+ const selectedRowState = useMemo(() => {
363
+ if (selectedRowKey == null) {
364
+ return { row: null as PredictionListRow | null, index: -1 };
365
+ }
366
+ return (
367
+ visibleRowLookup.get(selectedRowKey) ?? {
368
+ row: null as PredictionListRow | null,
369
+ index: -1,
330
370
  }
331
- return (
332
- selectedRow?.markets.find(
371
+ );
372
+ }, [selectedRowKey, visibleRowLookup]);
373
+ const selectedRow = selectedRowState.row;
374
+ const selectedSummary = useMemo(() => {
375
+ if (!detailOpen || !selectedRow) {
376
+ return null;
377
+ }
378
+ return (
379
+ selectedRow.markets.find(
333
380
  (market) => market.key === selectedDetailMarketKey,
334
381
  ) ??
335
- selectedRow?.markets.find(
382
+ selectedRow.markets.find(
336
383
  (market) => market.key === selectedRow.focusMarketKey,
337
384
  ) ??
338
- selectedRow?.representative ??
385
+ selectedRow.representative ??
339
386
  null
340
- );
341
- },
342
- [detailOpen, selectedDetailMarketKey, selectedRow],
343
- );
387
+ );
388
+ }, [detailOpen, selectedDetailMarketKey, selectedRow]);
344
389
  const selectedSummaryKey = selectedSummary?.key ?? null;
345
390
  const selectedSummaryVenue = selectedSummary?.venue ?? null;
346
391
  const selectedYesTokenId = selectedSummary?.yesTokenId ?? null;
@@ -366,9 +411,7 @@ export function usePredictionMarketsDataState({
366
411
  : null;
367
412
  const detailLoadCount = detailCacheKey ? detailPending[detailCacheKey] ?? 0 : 0;
368
413
  const detailError = detailCacheKey ? detailErrors[detailCacheKey] ?? null : null;
369
- const selectedIndex = selectedRow
370
- ? visibleRows.findIndex((row) => row.key === selectedRow.key)
371
- : -1;
414
+ const selectedIndex = selectedRowState.index;
372
415
  const sortedOutcomeMarkets = useMemo(
373
416
  () =>
374
417
  selectedRow?.kind === "group"
@@ -378,20 +421,36 @@ export function usePredictionMarketsDataState({
378
421
  );
379
422
 
380
423
  const loadPolymarket = useCallback(
381
- async (cacheKey: string, search: string, category: PredictionCategoryId) => {
382
- setCatalogPending((current) =>
383
- updatePredictionPendingCounts(current, cacheKey, 1),
384
- );
424
+ async (
425
+ cacheKey: string,
426
+ search: string,
427
+ category: PredictionCategoryId,
428
+ options?: { showPending?: boolean },
429
+ ) => {
430
+ const showPending =
431
+ options?.showPending ??
432
+ (search.trim().length > 0 ||
433
+ (activeCatalogRef.current[cacheKey]?.length ?? 0) === 0);
434
+ if (showPending) {
435
+ setCatalogPending((current) =>
436
+ updatePredictionPendingCounts(current, cacheKey, 1),
437
+ );
438
+ }
385
439
  try {
386
440
  const next = await loadPolymarketCatalog(search, category);
387
- setCatalogCache((current) => ({
388
- ...current,
389
- [cacheKey]: next,
390
- }));
441
+ setCatalogCache((current) => {
442
+ const previous = current[cacheKey] ?? activeCatalogRef.current[cacheKey];
443
+ if (samePredictionCatalogSummaries(previous, next)) {
444
+ return current;
445
+ }
446
+ return {
447
+ ...current,
448
+ [cacheKey]: next,
449
+ };
450
+ });
391
451
  setCatalogErrors((current) =>
392
452
  updatePredictionErrorState(current, cacheKey, null),
393
453
  );
394
- setLastRefreshAt(Date.now());
395
454
  } catch (error) {
396
455
  setCatalogErrors((current) =>
397
456
  updatePredictionErrorState(
@@ -401,29 +460,47 @@ export function usePredictionMarketsDataState({
401
460
  ),
402
461
  );
403
462
  } finally {
404
- setCatalogPending((current) =>
405
- updatePredictionPendingCounts(current, cacheKey, -1),
406
- );
463
+ if (showPending) {
464
+ setCatalogPending((current) =>
465
+ updatePredictionPendingCounts(current, cacheKey, -1),
466
+ );
467
+ }
407
468
  }
408
469
  },
409
470
  [],
410
471
  );
411
472
 
412
473
  const loadKalshi = useCallback(
413
- async (cacheKey: string, search: string, category: PredictionCategoryId) => {
414
- setCatalogPending((current) =>
415
- updatePredictionPendingCounts(current, cacheKey, 1),
416
- );
474
+ async (
475
+ cacheKey: string,
476
+ search: string,
477
+ category: PredictionCategoryId,
478
+ options?: { showPending?: boolean },
479
+ ) => {
480
+ const showPending =
481
+ options?.showPending ??
482
+ (search.trim().length > 0 ||
483
+ (activeCatalogRef.current[cacheKey]?.length ?? 0) === 0);
484
+ if (showPending) {
485
+ setCatalogPending((current) =>
486
+ updatePredictionPendingCounts(current, cacheKey, 1),
487
+ );
488
+ }
417
489
  try {
418
490
  const next = await loadKalshiCatalog(search, category);
419
- setCatalogCache((current) => ({
420
- ...current,
421
- [cacheKey]: next,
422
- }));
491
+ setCatalogCache((current) => {
492
+ const previous = current[cacheKey] ?? activeCatalogRef.current[cacheKey];
493
+ if (samePredictionCatalogSummaries(previous, next)) {
494
+ return current;
495
+ }
496
+ return {
497
+ ...current,
498
+ [cacheKey]: next,
499
+ };
500
+ });
423
501
  setCatalogErrors((current) =>
424
502
  updatePredictionErrorState(current, cacheKey, null),
425
503
  );
426
- setLastRefreshAt(Date.now());
427
504
  } catch (error) {
428
505
  setCatalogErrors((current) =>
429
506
  updatePredictionErrorState(
@@ -433,9 +510,11 @@ export function usePredictionMarketsDataState({
433
510
  ),
434
511
  );
435
512
  } finally {
436
- setCatalogPending((current) =>
437
- updatePredictionPendingCounts(current, cacheKey, -1),
438
- );
513
+ if (showPending) {
514
+ setCatalogPending((current) =>
515
+ updatePredictionPendingCounts(current, cacheKey, -1),
516
+ );
517
+ }
439
518
  }
440
519
  },
441
520
  [],
@@ -597,25 +676,6 @@ export function usePredictionMarketsDataState({
597
676
  {
598
677
  onBestBidAsk: (assetId, bestBid, bestAsk, spread) => {
599
678
  setTransportState("live");
600
- setCatalogCache((current) =>
601
- updatePredictionCatalogCacheEntries(current, marketKey, (summary) => {
602
- const isYes = assetId === summary.yesTokenId;
603
- if (isYes) {
604
- return {
605
- ...summary,
606
- yesBid: bestBid,
607
- yesAsk: bestAsk,
608
- spread: spread ?? summary.spread,
609
- };
610
- }
611
- return {
612
- ...summary,
613
- noBid: bestBid,
614
- noAsk: bestAsk,
615
- spread: spread ?? summary.spread,
616
- };
617
- }),
618
- );
619
679
  setDetailCache((current) =>
620
680
  updatePredictionDetailCacheEntries(current, marketKey, (detailEntry) => {
621
681
  const isYes = assetId === detailEntry.summary.yesTokenId;
@@ -633,7 +693,7 @@ export function usePredictionMarketsDataState({
633
693
  noBid: bestBid,
634
694
  noAsk: bestAsk,
635
695
  spread: spread ?? detailEntry.summary.spread,
636
- },
696
+ },
637
697
  };
638
698
  }),
639
699
  );
@@ -691,20 +751,6 @@ export function usePredictionMarketsDataState({
691
751
  };
692
752
  }),
693
753
  );
694
- setCatalogCache((current) =>
695
- updatePredictionCatalogCacheEntries(current, marketKey, (summary) => {
696
- const isYes = assetId === summary.yesTokenId;
697
- const normalizedYesPrice = isYes
698
- ? trade.price
699
- : Math.max(0, 1 - trade.price);
700
- return {
701
- ...summary,
702
- lastTradePrice: normalizedYesPrice,
703
- yesPrice: normalizedYesPrice,
704
- noPrice: Math.max(0, 1 - normalizedYesPrice),
705
- };
706
- }),
707
- );
708
754
  },
709
755
  },
710
756
  );