gloomberb 0.10.0 → 0.10.2

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 (353) hide show
  1. package/package.json +8 -1
  2. package/src/api-client/auth.ts +1 -0
  3. package/src/api-client/index.test.ts +359 -108
  4. package/src/api-client/index.ts +24 -13
  5. package/src/api-client/socket.ts +70 -35
  6. package/src/api-client/types.ts +1 -1
  7. package/src/app/language-observer.test.tsx +82 -0
  8. package/src/app/language-observer.tsx +13 -0
  9. package/src/app/pane-runtime/index.tsx +2 -2
  10. package/src/app/pane-runtime/pane-settings-runtime.tsx +2 -2
  11. package/src/app/pane-runtime/pane-template-runtime.ts +2 -2
  12. package/src/app/pane-runtime/plugin-bindings.ts +2 -2
  13. package/src/app/pane-runtime/ticker-open-runtime.ts +2 -2
  14. package/src/app/runtime/broker-import.ts +2 -2
  15. package/src/app/runtime/plugin-bindings.ts +2 -2
  16. package/src/app/runtime/startup.ts +2 -2
  17. package/src/app.tsx +16 -7
  18. package/src/brokers/account-cache.ts +6 -6
  19. package/src/brokers/broker-ticker-sync.ts +3 -3
  20. package/src/brokers/remote-broker-adapter.ts +2 -2
  21. package/src/brokers/sync-broker-instance.ts +5 -6
  22. package/src/cli/commands/api.ts +3 -6
  23. package/src/cli/commands/automation.ts +7 -15
  24. package/src/cli/commands/market.ts +26 -61
  25. package/src/cli/commands/overview.ts +34 -45
  26. package/src/cli/commands/search.ts +25 -27
  27. package/src/cli/commands/system.ts +27 -57
  28. package/src/cli/commands/ticker.ts +62 -63
  29. package/src/cli/context.test.ts +63 -0
  30. package/src/cli/context.ts +15 -1
  31. package/src/cli/index.ts +1 -1
  32. package/src/cli/pane-functions/data.ts +2 -19
  33. package/src/cli/pane-functions/index.ts +26 -25
  34. package/src/cli/pane-functions/report.ts +1 -1
  35. package/src/cli/pane-functions/screenshot.ts +3 -3
  36. package/src/cli/scoped-context.ts +41 -0
  37. package/src/components/chart/composite/composite-chart.test.tsx +615 -18
  38. package/src/components/chart/composite/composite-chart.tsx +179 -79
  39. package/src/components/chart/composite/format.test.ts +20 -7
  40. package/src/components/chart/composite/index.ts +0 -21
  41. package/src/components/chart/composite/interactions.test.ts +90 -3
  42. package/src/components/chart/composite/interactions.ts +189 -24
  43. package/src/components/chart/composite/price-series.ts +0 -2
  44. package/src/components/chart/composite/rasterizer.ts +10 -9
  45. package/src/components/chart/composite/renderers.test.ts +108 -2
  46. package/src/components/chart/composite/scene.test.ts +36 -0
  47. package/src/components/chart/composite/scene.ts +5 -2
  48. package/src/components/chart/composite/text-renderer.ts +37 -25
  49. package/src/components/chart/composite/time-axis.test.ts +243 -0
  50. package/src/components/chart/composite/time-axis.ts +608 -0
  51. package/src/components/chart/composite/types.ts +12 -1
  52. package/src/components/chart/core/data.ts +2 -159
  53. package/src/components/chart/core/date-window.ts +6 -225
  54. package/src/components/chart/core/palette.ts +1 -12
  55. package/src/components/chart/core/pointer.ts +0 -142
  56. package/src/components/chart/core/types.ts +1 -58
  57. package/src/components/chart/cursor-motion.ts +2 -4
  58. package/src/components/chart/indicators/types.ts +0 -9
  59. package/src/components/chart/market-session.ts +0 -11
  60. package/src/components/chart/native/kitty/protocol.ts +1 -1
  61. package/src/components/chart/native/raster/layout.ts +3 -10
  62. package/src/components/chart/static/chart/axis-overlays.test.tsx +64 -0
  63. package/src/components/chart/static/chart/axis-overlays.tsx +59 -14
  64. package/src/components/chart/static/chart/surface.tsx +1 -2
  65. package/src/components/command-bar/action-runtime.ts +2 -2
  66. package/src/components/command-bar/commands/direct/index.ts +1 -1
  67. package/src/components/command-bar/panel/body.tsx +2 -2
  68. package/src/components/command-bar/panel/index.tsx +11 -9
  69. package/src/components/command-bar/routes/ticker-search/actions.ts +2 -2
  70. package/src/components/command-bar/surface/index.tsx +2 -2
  71. package/src/components/command-bar/workflow/body.tsx +3 -3
  72. package/src/components/command-bar/workflow/collection-actions.ts +2 -2
  73. package/src/components/command-bar/workflow/coordinator.ts +2 -2
  74. package/src/components/command-bar/workflow/field-row.tsx +25 -11
  75. package/src/components/command-bar/workflow/tickers.ts +2 -2
  76. package/src/components/feed-data-table/stack-view.test.tsx +28 -36
  77. package/src/components/feed-data-table/stack-view.tsx +3 -1
  78. package/src/components/layout/detached-pane-shell.tsx +6 -6
  79. package/src/components/layout/header.tsx +13 -9
  80. package/src/components/layout/pane/content.test.tsx +42 -3
  81. package/src/components/layout/pane/content.tsx +3 -1
  82. package/src/components/layout/pane/footer/index.test.tsx +45 -2
  83. package/src/components/layout/pane/footer/registration.tsx +3 -1
  84. package/src/components/layout/shell/index.tsx +1 -2
  85. package/src/components/layout/shell/native/surfaces.ts +1 -1
  86. package/src/components/layout/shell/native/window-state.ts +1 -1
  87. package/src/components/layout/status-bar.tsx +12 -8
  88. package/src/components/layout/window-controls.tsx +8 -6
  89. package/src/components/onboarding/onboarding-wizard.tsx +3 -1
  90. package/src/components/pane-settings-dialog/desktop.tsx +0 -2
  91. package/src/components/pane-settings-dialog.tsx +0 -2
  92. package/src/components/pane-template-wizard.tsx +10 -9
  93. package/src/components/price-performance.tsx +2 -113
  94. package/src/components/price-sparkline/model.ts +15 -17
  95. package/src/components/price-sparkline/view.tsx +8 -7
  96. package/src/components/speedometer-gauge/desktop.tsx +2 -1
  97. package/src/components/speedometer-gauge/index.tsx +0 -2
  98. package/src/components/speedometer-gauge/terminal.tsx +24 -5
  99. package/src/components/ticker/badge/index.tsx +1 -18
  100. package/src/components/ui/data-table/opentui/index.tsx +3 -3
  101. package/src/components/ui/frame.tsx +1 -2
  102. package/src/components/ui/page-stack-view.test.tsx +126 -0
  103. package/src/components/ui/page-stack-view.tsx +24 -12
  104. package/src/components/ui/tabs.tsx +7 -3
  105. package/src/components/ui/ui.test.tsx +23 -2
  106. package/src/components/use-external-link-footer.ts +4 -2
  107. package/src/core/app-service-ports.ts +46 -0
  108. package/src/core/app-services.test.ts +66 -0
  109. package/src/core/app-services.ts +17 -15
  110. package/src/data/config/chart-settings.ts +3 -10
  111. package/src/data/config/store/index.test.ts +99 -2
  112. package/src/data/config/store/migrations.ts +278 -0
  113. package/src/data/config/store/normalize.ts +44 -186
  114. package/src/data/resource-store.ts +73 -12
  115. package/src/data/sqlite/cache.test.ts +104 -15
  116. package/src/i18n/index.test.ts +17 -0
  117. package/src/i18n/index.ts +23 -6
  118. package/src/i18n/ja.ts +13 -0
  119. package/src/i18n/ko.ts +13 -0
  120. package/src/i18n/react.ts +6 -0
  121. package/src/i18n/zh-cn.ts +13 -0
  122. package/src/i18n/zh-tw.ts +13 -0
  123. package/src/market-data/coordinator/auxiliary.ts +7 -3
  124. package/src/market-data/coordinator/chart.ts +1 -1
  125. package/src/market-data/coordinator/index.test.ts +26 -0
  126. package/src/market-data/coordinator/index.ts +11 -5
  127. package/src/market-data/coordinator/quotes.ts +4 -40
  128. package/src/market-data/coordinator/subscriptions.test.ts +89 -1
  129. package/src/market-data/hooks.tsx +47 -1
  130. package/src/market-data/market/status.ts +6 -6
  131. package/src/market-data/performance.ts +1 -1
  132. package/src/market-data/quote-subscription-target.test.ts +37 -0
  133. package/src/market-data/quote-subscription-target.ts +60 -0
  134. package/src/market-data/quotes/freshness.ts +1 -0
  135. package/src/market-data/quotes/resolution.ts +4 -0
  136. package/src/market-data/request-types.ts +3 -3
  137. package/src/news/aggregator.test.ts +97 -1
  138. package/src/news/aggregator.ts +100 -57
  139. package/src/news/hooks.test.tsx +64 -0
  140. package/src/news/hooks.ts +18 -25
  141. package/src/plugins/builtin/account-management/footer.ts +4 -2
  142. package/src/plugins/builtin/account-management/pane.tsx +9 -4
  143. package/src/plugins/builtin/ai/agent-history.ts +11 -7
  144. package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +0 -5
  145. package/src/plugins/builtin/ai/ask-ai.test.tsx +3 -4
  146. package/src/plugins/builtin/ai/index.test.ts +2 -2
  147. package/src/plugins/builtin/ai/index.tsx +10 -11
  148. package/src/plugins/builtin/ai/pane-settings.ts +1 -1
  149. package/src/plugins/builtin/ai/pi/runtime.ts +6 -5
  150. package/src/plugins/builtin/ai/providers.ts +1 -9
  151. package/src/plugins/builtin/ai/runner.ts +0 -6
  152. package/src/plugins/builtin/ai/screener/footer.ts +4 -1
  153. package/src/plugins/builtin/ai/screener/pane.test.tsx +9 -9
  154. package/src/plugins/builtin/ai/workspace/model.ts +2 -27
  155. package/src/plugins/builtin/ai/workspace/pane.tsx +2 -2
  156. package/src/plugins/builtin/analytics/metrics.ts +1 -7
  157. package/src/plugins/builtin/broker-manager/detail.tsx +3 -2
  158. package/src/plugins/builtin/broker-manager/index.tsx +4 -2
  159. package/src/plugins/builtin/chart-composer/editor/controller.ts +643 -0
  160. package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +134 -0
  161. package/src/plugins/builtin/chart-composer/editor/model.test.ts +85 -0
  162. package/src/plugins/builtin/chart-composer/editor/model.ts +292 -0
  163. package/src/plugins/builtin/chart-composer/editor/opentui-view.tsx +108 -0
  164. package/src/plugins/builtin/chart-composer/editor.tsx +65 -947
  165. package/src/plugins/builtin/chart-composer/index.tsx +0 -6
  166. package/src/plugins/builtin/chart-composer/pane.tsx +69 -36
  167. package/src/plugins/builtin/chart-composer/presets.ts +1 -19
  168. package/src/plugins/builtin/chart-composer/settings.ts +1 -1
  169. package/src/plugins/builtin/chat/content/composer-runtime.ts +1 -1
  170. package/src/plugins/builtin/chat/content/shortcuts.ts +0 -1
  171. package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
  172. package/src/plugins/builtin/chat/controller/persistence.ts +2 -0
  173. package/src/plugins/builtin/chat/controller/session.test.ts +25 -0
  174. package/src/plugins/builtin/chat/controller/session.ts +2 -0
  175. package/src/plugins/builtin/chat/controller/state.ts +7 -0
  176. package/src/plugins/builtin/chat/controller.test.ts +73 -20
  177. package/src/plugins/builtin/chat/message/desktop.tsx +2 -0
  178. package/src/plugins/builtin/cloud-tweets/footer.ts +9 -28
  179. package/src/plugins/builtin/cloud-tweets/pane.tsx +0 -5
  180. package/src/plugins/builtin/cloud-tweets/table.tsx +12 -17
  181. package/src/plugins/builtin/correlation/compute.ts +4 -10
  182. package/src/plugins/builtin/econ/index.tsx +17 -19
  183. package/src/plugins/builtin/holders/types.ts +0 -1
  184. package/src/plugins/builtin/insider/index.tsx +6 -31
  185. package/src/plugins/builtin/news/index.tsx +5 -7
  186. package/src/plugins/builtin/news/wire/breaking/pane.test.tsx +6 -8
  187. package/src/plugins/builtin/news/wire/news/footer.ts +10 -11
  188. package/src/plugins/builtin/news/wire/read-state.test.ts +7 -0
  189. package/src/plugins/builtin/news/wire/read-state.ts +18 -28
  190. package/src/plugins/builtin/news/wire/rss/parser.ts +1 -11
  191. package/src/plugins/builtin/options/footer.test.ts +115 -0
  192. package/src/plugins/builtin/options/footer.ts +110 -0
  193. package/src/plugins/builtin/options/live-quotes.test.ts +238 -0
  194. package/src/plugins/builtin/options/live-quotes.ts +147 -0
  195. package/src/plugins/builtin/options/view.test.tsx +71 -1
  196. package/src/plugins/builtin/options/view.tsx +39 -24
  197. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +103 -117
  198. package/src/plugins/builtin/portfolio-list/cli/render.ts +11 -5
  199. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -135
  200. package/src/plugins/builtin/portfolio-list/header.tsx +9 -4
  201. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +6 -1
  202. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +4 -2
  203. package/src/plugins/builtin/research/corporate-actions-pane.tsx +24 -52
  204. package/src/plugins/builtin/sec/filing-content.test.ts +41 -0
  205. package/src/plugins/builtin/sec/filing-content.ts +94 -0
  206. package/src/plugins/builtin/sec/index.tsx +21 -104
  207. package/src/plugins/builtin/sectors/sector-model.ts +1 -7
  208. package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -0
  209. package/src/plugins/builtin/shared/pane-footer.ts +82 -0
  210. package/src/plugins/builtin/shared/read-state.ts +64 -3
  211. package/src/plugins/builtin/substack/read-state.ts +16 -41
  212. package/src/plugins/builtin/thirteenf/pane.tsx +24 -73
  213. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +10 -10
  214. package/src/plugins/builtin/yield-curve/index.tsx +11 -9
  215. package/src/plugins/ibkr/dialogs.tsx +3 -3
  216. package/src/plugins/ibkr/gateway/fundamentals.ts +1 -1
  217. package/src/plugins/ibkr/gateway/history-requests.ts +2 -2
  218. package/src/plugins/ibkr/gateway/history.ts +2 -2
  219. package/src/plugins/ibkr/gateway/selection.ts +2 -2
  220. package/src/plugins/ibkr/gateway/service/index.ts +2 -2
  221. package/src/plugins/ibkr/gateway/service/native.ts +2 -2
  222. package/src/plugins/plugin-persistence.ts +3 -4
  223. package/src/plugins/prediction-markets/controller/keyboard.ts +1 -1
  224. package/src/plugins/prediction-markets/controller/live-updates.ts +6 -5
  225. package/src/plugins/prediction-markets/detail/book.tsx +2 -2
  226. package/src/plugins/prediction-markets/detail/outcomes.tsx +3 -1
  227. package/src/plugins/prediction-markets/detail/pane.tsx +3 -1
  228. package/src/plugins/prediction-markets/detail/trades.tsx +3 -3
  229. package/src/plugins/registry/context.ts +3 -4
  230. package/src/plugins/registry/index.ts +5 -6
  231. package/src/react/input.test.ts +126 -3
  232. package/src/react/input.ts +120 -1
  233. package/src/remote/app-host.tsx +2 -13
  234. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +44 -60
  235. package/src/renderers/electrobun/bun/desktop/capability-bridge.ts +15 -13
  236. package/src/renderers/electrobun/bun/desktop/host-requests.ts +26 -22
  237. package/src/renderers/electrobun/bun/desktop/http-fetch.ts +5 -1
  238. package/src/renderers/electrobun/bun/desktop/initialization.ts +11 -6
  239. package/src/renderers/electrobun/bun/desktop/media.ts +5 -3
  240. package/src/renderers/electrobun/bun/desktop/plugin-state.ts +21 -22
  241. package/src/renderers/electrobun/bun/desktop/window-controls.ts +3 -1
  242. package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +18 -18
  243. package/src/renderers/electrobun/bun/index.ts +123 -83
  244. package/src/renderers/electrobun/shared/protocol.ts +146 -7
  245. package/src/renderers/electrobun/view/app-services.ts +5 -8
  246. package/src/renderers/electrobun/view/backend-rpc.ts +18 -8
  247. package/src/renderers/electrobun/view/broker-remote-client.ts +2 -2
  248. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +5 -22
  249. package/src/renderers/electrobun/view/config-host.ts +1 -1
  250. package/src/renderers/electrobun/view/context-menu.ts +1 -17
  251. package/src/renderers/electrobun/view/data-table/index.tsx +0 -1
  252. package/src/renderers/electrobun/view/data-table/row.tsx +0 -4
  253. package/src/renderers/electrobun/view/desktop/control-styles.ts +37 -34
  254. package/src/renderers/electrobun/view/desktop/controls.tsx +36 -33
  255. package/src/renderers/electrobun/view/desktop/list-view.tsx +15 -12
  256. package/src/renderers/electrobun/view/desktop/popover.tsx +2 -3
  257. package/src/renderers/electrobun/view/dialog-host.tsx +2 -3
  258. package/src/renderers/electrobun/view/fatal-screen.tsx +0 -1
  259. package/src/renderers/electrobun/view/host/box.tsx +0 -1
  260. package/src/renderers/electrobun/view/host/chart-surface.tsx +0 -1
  261. package/src/renderers/electrobun/view/host/input.tsx +0 -1
  262. package/src/renderers/electrobun/view/host/media-surface.tsx +0 -1
  263. package/src/renderers/electrobun/view/host/native.ts +0 -1
  264. package/src/renderers/electrobun/view/host/scroll-box.tsx +0 -1
  265. package/src/renderers/electrobun/view/host/tabs.tsx +0 -1
  266. package/src/renderers/electrobun/view/host/text.tsx +0 -1
  267. package/src/renderers/electrobun/view/http-fetch.ts +3 -11
  268. package/src/renderers/electrobun/view/input-host.tsx +10 -53
  269. package/src/renderers/electrobun/view/key-event.ts +0 -1
  270. package/src/renderers/electrobun/view/main.tsx +3 -3
  271. package/src/renderers/electrobun/view/native-renderer.ts +0 -1
  272. package/src/renderers/electrobun/view/native-stubs/backend-rpc.ts +13 -1
  273. package/src/renderers/electrobun/view/native-stubs/chart/surface-manager.ts +11 -0
  274. package/src/renderers/electrobun/view/native-stubs/native-stubs.test.ts +47 -0
  275. package/src/renderers/electrobun/view/remote/asset-data-client.ts +6 -44
  276. package/src/renderers/electrobun/view/remote/persistence.ts +6 -2
  277. package/src/renderers/electrobun/view/remote/quote-subscription-registry.test.ts +86 -0
  278. package/src/renderers/electrobun/view/remote/quote-subscription-registry.ts +72 -0
  279. package/src/renderers/electrobun/view/remote/ticker-repository.ts +2 -2
  280. package/src/renderers/electrobun/view/toast-host.tsx +0 -1
  281. package/src/renderers/electrobun/view/ui-host.tsx +1 -2
  282. package/src/renderers/electrobun/view/update-host.ts +1 -1
  283. package/src/renderers/opentui/chart-surface.tsx +2 -1
  284. package/src/renderers/opentui/dialog-host.tsx +20 -4
  285. package/src/renderers/opentui/image/loader.ts +12 -2
  286. package/src/renderers/opentui/input-host.tsx +7 -49
  287. package/src/renderers/opentui/start.tsx +2 -0
  288. package/src/sources/gloomberb-cloud/history-quality.ts +44 -0
  289. package/src/sources/gloomberb-cloud/index.test.ts +173 -0
  290. package/src/sources/gloomberb-cloud/index.ts +42 -20
  291. package/src/sources/gloomberb-cloud/normalizers.ts +9 -3
  292. package/src/sources/provider-router/cache.ts +1 -1
  293. package/src/sources/provider-router/document-routes.ts +10 -5
  294. package/src/sources/provider-router/financials.test.ts +14 -0
  295. package/src/sources/provider-router/financials.ts +6 -1
  296. package/src/sources/provider-router/history.test.ts +163 -1
  297. package/src/sources/provider-router/history.ts +278 -347
  298. package/src/sources/provider-router/index.ts +2 -2
  299. package/src/sources/provider-router/routing.test.ts +39 -0
  300. package/src/sources/provider-router/routing.ts +24 -11
  301. package/src/sources/provider-router/supplemental.ts +37 -17
  302. package/src/sources/sec-edgar/content.ts +2 -12
  303. package/src/sources/sec-edgar.ts +2 -13
  304. package/src/sources/yahoo-finance/history.ts +2 -2
  305. package/src/sources/yahoo-finance/options.ts +5 -0
  306. package/src/sources/yahoo-finance.ts +2 -2
  307. package/src/state/app/bootstrap.ts +2 -2
  308. package/src/state/app/context/index.tsx +2 -2
  309. package/src/state/hooks/quote-streaming.ts +66 -1
  310. package/src/state/hooks/session-snapshot.ts +2 -2
  311. package/src/state/selectors.ts +0 -9
  312. package/src/sync/controller.test.ts +98 -0
  313. package/src/sync/controller.ts +29 -5
  314. package/src/sync/react.ts +2 -2
  315. package/src/sync/types.ts +2 -2
  316. package/src/theme/colors.test.ts +10 -0
  317. package/src/theme/colors.ts +75 -78
  318. package/src/theme/theme-context.test.tsx +67 -0
  319. package/src/theme/theme-context.tsx +9 -5
  320. package/src/tickers/open-target.ts +2 -2
  321. package/src/tickers/search/upsert.ts +2 -2
  322. package/src/time-series/alignment.ts +0 -7
  323. package/src/time-series/chart-data.ts +145 -0
  324. package/src/time-series/date-window.ts +44 -0
  325. package/src/time-series/history-window.ts +21 -0
  326. package/src/time-series/hooks.test.ts +59 -0
  327. package/src/time-series/hooks.ts +33 -12
  328. package/src/time-series/market-resolution.ts +2 -2
  329. package/src/time-series/market.ts +1 -1
  330. package/src/time-series/range.ts +9 -0
  331. package/src/{components/chart/core → time-series}/resolution.ts +3 -102
  332. package/src/time-series/resolve.test.ts +203 -1
  333. package/src/time-series/resolve.ts +96 -18
  334. package/src/time-series/spec-studies.test.ts +15 -0
  335. package/src/time-series/spec.ts +2 -2
  336. package/src/time-series/studies.ts +5 -2
  337. package/src/time-series/types.ts +3 -1
  338. package/src/time-series/use-chart-resolution.test.tsx +358 -0
  339. package/src/time-series/use-chart-resolution.ts +46 -4
  340. package/src/types/broker.ts +2 -2
  341. package/src/types/data-provider.ts +3 -3
  342. package/src/types/financials.ts +12 -0
  343. package/src/types/plugin.ts +2 -2
  344. package/src/ui/context-menu.tsx +3 -2
  345. package/src/ui/dialog.tsx +2 -2
  346. package/src/utils/html-entities.ts +3 -5
  347. package/src/utils/main-thread-monitor.ts +1 -1
  348. package/src/utils/price-history.ts +5 -5
  349. package/src/version.ts +3 -1
  350. package/src/components/chart/core/viewport.test.ts +0 -8
  351. package/src/components/chart/core/viewport.ts +0 -24
  352. package/src/time-series/index.ts +0 -14
  353. /package/src/{components/chart/core → time-series}/resolution.test.ts +0 -0
@@ -1,13 +1,10 @@
1
- import { useCallback, useMemo } from "react";
2
- import { usePluginState } from "../../runtime";
3
1
  import {
4
2
  DEFAULT_MAX_READ_IDS,
5
- markReadId,
6
- normalizeReadIds,
7
- sameStringArray,
3
+ usePersistedReadIds,
4
+ type PersistedReadIdAdapter,
8
5
  } from "../shared/read-state";
9
6
 
10
- export interface SubstackReadState {
7
+ interface SubstackReadState {
11
8
  articleIds: string[];
12
9
  }
13
10
 
@@ -15,41 +12,19 @@ const SUBSTACK_READ_STATE_SCHEMA_VERSION = 1;
15
12
  const READ_STATE_KEY = "read-articles";
16
13
  const EMPTY_READ_STATE: SubstackReadState = { articleIds: [] };
17
14
 
18
- export const MAX_READ_SUBSTACK_ARTICLE_IDS = DEFAULT_MAX_READ_IDS;
19
-
20
- export function normalizeSubstackReadState(state: SubstackReadState): SubstackReadState {
21
- return {
22
- articleIds: normalizeReadIds(state.articleIds, MAX_READ_SUBSTACK_ARTICLE_IDS),
23
- };
24
- }
25
-
26
- export function markSubstackArticleRead(
27
- state: SubstackReadState,
28
- articleId: string,
29
- ): SubstackReadState {
30
- const current = normalizeSubstackReadState(state).articleIds;
31
- const articleIds = markReadId(current, articleId, MAX_READ_SUBSTACK_ARTICLE_IDS);
32
-
33
- return sameStringArray(articleIds, state.articleIds) ? state : { articleIds };
34
- }
15
+ const MAX_READ_SUBSTACK_ARTICLE_IDS = DEFAULT_MAX_READ_IDS;
16
+ const SUBSTACK_READ_STATE_ADAPTER: PersistedReadIdAdapter<SubstackReadState> = {
17
+ getIds: (state) => state.articleIds,
18
+ withIds: (_state, articleIds) => ({ articleIds }),
19
+ maxIds: MAX_READ_SUBSTACK_ARTICLE_IDS,
20
+ };
35
21
 
36
22
  export function useSubstackReadState() {
37
- const [readState, setReadState] = usePluginState<SubstackReadState>(
38
- READ_STATE_KEY,
39
- EMPTY_READ_STATE,
40
- { schemaVersion: SUBSTACK_READ_STATE_SCHEMA_VERSION },
41
- );
42
- const normalizedReadState = useMemo(
43
- () => normalizeSubstackReadState(readState),
44
- [readState],
45
- );
46
- const readArticleIds = useMemo(
47
- () => new Set(normalizedReadState.articleIds),
48
- [normalizedReadState],
49
- );
50
- const markArticleRead = useCallback((articleId: string) => {
51
- setReadState((current) => markSubstackArticleRead(current, articleId));
52
- }, [setReadState]);
53
-
54
- return { readArticleIds, markArticleRead };
23
+ const { readIds, markRead } = usePersistedReadIds({
24
+ key: READ_STATE_KEY,
25
+ fallback: EMPTY_READ_STATE,
26
+ schemaVersion: SUBSTACK_READ_STATE_SCHEMA_VERSION,
27
+ adapter: SUBSTACK_READ_STATE_ADAPTER,
28
+ });
29
+ return { readArticleIds: readIds, markArticleRead: markRead };
55
30
  }
@@ -13,7 +13,7 @@ import {
13
13
  InputSearchBar,
14
14
  Spinner,
15
15
  Tabs,
16
- usePaneFooter,
16
+ type PaneFooterSegment,
17
17
  type DataTableKeyEvent,
18
18
  type DataTableRootKeyContext,
19
19
  } from "../../../components";
@@ -50,11 +50,6 @@ import {
50
50
  sortHoldingRows,
51
51
  sortTimelineRows,
52
52
  } from "./model";
53
- import {
54
- formatMoneyCompact,
55
- formatPercentMaybe,
56
- formatRawPercentMaybe,
57
- } from "./format";
58
53
  import {
59
54
  renderFilingPositionCell,
60
55
  renderBrowserCell,
@@ -80,6 +75,7 @@ import type {
80
75
  ThirteenFDetailTab,
81
76
  ThirteenFHoldingRecord,
82
77
  } from "./types";
78
+ import { usePaneStatusFooter, usePaneStatusLinkFooter } from "../shared/pane-footer";
83
79
 
84
80
  interface FundSeed {
85
81
  cik: string;
@@ -271,24 +267,17 @@ export function ThirteenFPane({ focused, width, height }: PaneProps) {
271
267
  setDetailSeed({ cik: row.cik, name: row.name });
272
268
  }, []);
273
269
 
274
- usePaneFooter(THIRTEENF_PANE_ID, () => {
275
- if (detailSeed) return null;
276
- return {
277
- info: [
278
- ...(status === "loading" ? [{ id: "loading", parts: [{ text: "loading", tone: "muted" as const }] }] : []),
270
+ const browserStatusInfo = useMemo<PaneFooterSegment[]>(() => [
279
271
  ...(loadingMore ? [{ id: "loading-more", parts: [{ text: "loading more", tone: "muted" as const }] }] : []),
280
- ...(error ? [{ id: "error", parts: [{ text: "error", tone: "warning" as const }] }] : []),
281
272
  ...(warning ? [{ id: "warning", parts: [{ text: warning, tone: "warning" as const }] }] : []),
282
- ...(browserMode === "byTicker" && query ? [{ id: "ticker", parts: [{ text: query.toUpperCase(), tone: "value" as const }] }] : []),
283
- ...(period ? [{ id: "period", parts: [{ text: period, tone: "value" as const }] }] : []),
284
- ...(quarter && !period ? [{ id: "quarter", parts: [{ text: quarter, tone: "value" as const }] }] : []),
285
- ],
286
- hints: [
287
- { id: "refresh", key: "r", label: "efresh", onPress: refresh },
288
- { id: "search", key: "/", label: searchFocused ? "done" : "search", onPress: searchFocused ? blurSearch : focusSearch },
289
- ],
290
- };
291
- }, [blurSearch, browserMode, detailSeed, error, focusSearch, loadingMore, period, quarter, query, refresh, searchFocused, status, warning]);
273
+ ], [loadingMore, warning]);
274
+ usePaneStatusFooter({
275
+ registrationId: THIRTEENF_PANE_ID,
276
+ enabled: !detailSeed,
277
+ loading: status === "loading",
278
+ error,
279
+ info: browserStatusInfo,
280
+ });
292
281
 
293
282
  const rootBefore = (
294
283
  <Box flexDirection="column">
@@ -466,18 +455,6 @@ function FundDetailView({
466
455
  ? openFiling?.url ?? selectedFiling?.url
467
456
  : latestForm?.url;
468
457
  const statusFiling = openFiling ?? latestForm;
469
- const openFilingIndex = openFiling
470
- ? filingRows.findIndex((row) => row.id === openFiling.id)
471
- : -1;
472
- const statusPreviousPeriod = openFiling
473
- ? filingRows[openFilingIndex + 1]?.periodOfReport
474
- : data?.previousForm?.periodOfReport;
475
- const valueChangeText = openFiling?.valueChangePercent != null
476
- ? `value chg ${formatPercentMaybe(openFiling.valueChangePercent)}`
477
- : latestForm?.tableValueTotal && data?.previousForm?.tableValueTotal
478
- ? `value chg ${formatRawPercentMaybe(((latestForm.tableValueTotal - data.previousForm.tableValueTotal) / data.previousForm.tableValueTotal) * 100)}`
479
- : "";
480
-
481
458
  useEffect(() => {
482
459
  if (holdingSelectedId && visibleHoldingRows.some((row) => row.id === holdingSelectedId)) return;
483
460
  setHoldingSelectedId(visibleHoldingRows[0]?.id ?? null);
@@ -495,9 +472,6 @@ function FundDetailView({
495
472
  }, [filingRows, openFilingId]);
496
473
 
497
474
  const refresh = useCallback(() => load(true), [load]);
498
- const openSource = useCallback(() => {
499
- if (currentSourceUrl) void rendererHost.openExternal(currentSourceUrl);
500
- }, [currentSourceUrl, rendererHost]);
501
475
  const openTicker = useCallback(() => {
502
476
  if (selectedHolding?.ticker) pinTicker(selectedHolding.ticker, { floating: true, paneType: TICKER_RESEARCH_PANE_ID });
503
477
  }, [pinTicker, selectedHolding?.ticker]);
@@ -555,43 +529,20 @@ function FundDetailView({
555
529
  }
556
530
  });
557
531
 
558
- usePaneFooter("thirteenf-detail", () => ({
559
- info: [
560
- ...(status === "loading" ? [{ id: "loading", parts: [{ text: "loading", tone: "muted" as const }] }] : []),
561
- ...(error ? [{ id: "error", parts: [{ text: "error", tone: "warning" as const }] }] : []),
562
- ...(statusFiling?.periodOfReport ? [{ id: "period", parts: [{ text: `${statusFiling.periodOfReport} report`, tone: "value" as const }] }] : []),
563
- ...(statusFiling?.filedAsOfDate ? [{ id: "filed", parts: [{ text: `filed ${statusFiling.filedAsOfDate}`, tone: "muted" as const }] }] : []),
564
- ...(statusFiling?.tableValueTotal != null ? [{ id: "value", parts: [{ text: formatMoneyCompact(statusFiling.tableValueTotal), tone: "value" as const }] }] : []),
565
- ...(statusFiling?.tableEntryTotal != null ? [{ id: "rows", parts: [{ text: `${statusFiling.tableEntryTotal} rows`, tone: "muted" as const }] }] : []),
566
- ...(statusPreviousPeriod ? [{ id: "prev", parts: [{ text: `prev ${statusPreviousPeriod}`, tone: "muted" as const }] }] : []),
567
- ...(valueChangeText ? [{ id: "value-change", parts: [{ text: valueChangeText, tone: "value" as const }] }] : []),
568
- ...(statusFiling?.isAmendment ? [{ id: "amended", parts: [{ text: "amended", tone: "warning" as const }] }] : []),
569
- ],
570
- hints: [
571
- { id: "refresh", key: "r", label: "efresh", onPress: refresh },
572
- ...(selectedHolding?.ticker ? [{ id: "ticker", key: "t", label: "icker", onPress: openTicker }] : []),
573
- ...(filingTarget ? [{ id: "filing", key: "f", label: "iling", onPress: openSelectedFilingInPane }] : []),
574
- ...(openFiling && currentSourceUrl ? [{ id: "source", key: "o", label: "pen", onPress: openSource }] : []),
575
- ],
576
- }), [
577
- currentSourceUrl,
532
+ const detailStatusInfo = useMemo<PaneFooterSegment[]>(() => (
533
+ statusFiling?.isAmendment
534
+ ? [{ id: "amended", parts: [{ text: "amended", tone: "warning" }] }]
535
+ : []
536
+ ), [statusFiling?.isAmendment]);
537
+ usePaneStatusLinkFooter({
538
+ registrationId: "thirteenf-detail",
539
+ focused,
540
+ url: openFiling ? currentSourceUrl : null,
541
+ source: openFiling ? "SEC 13F" : null,
542
+ loading: status === "loading",
578
543
  error,
579
- filingTarget,
580
- statusFiling?.filedAsOfDate,
581
- statusFiling?.isAmendment,
582
- statusFiling?.periodOfReport,
583
- statusFiling?.tableEntryTotal,
584
- statusFiling?.tableValueTotal,
585
- statusPreviousPeriod,
586
- openSource,
587
- openSelectedFilingInPane,
588
- openTicker,
589
- openFiling,
590
- refresh,
591
- selectedHolding?.ticker,
592
- status,
593
- valueChangeText,
594
- ]);
544
+ info: detailStatusInfo,
545
+ });
595
546
 
596
547
  if ((status === "loading" || status === "idle") && !data) {
597
548
  return (
@@ -66,17 +66,17 @@ export function QuoteMonitorPane({ paneId, focused, width, height }: PaneProps)
66
66
  const financialsBySymbol = useAppSelector((state) => state.financials);
67
67
  const tickersBySymbol = useAppSelector((state) => state.tickers);
68
68
  const valueFlashingEnabled = useAppSelector((state) => state.config.valueFlashingEnabled);
69
- const streamingTargets = useMemo(() => (
70
- symbols
71
- .map((symbol) => {
69
+ const streamingTargets = useMemo<QuoteSubscriptionTarget[]>(() => {
70
+ const targets: QuoteSubscriptionTarget[] = [];
71
+ for (const symbol of symbols) {
72
72
  const ticker = tickersBySymbol.get(symbol) ?? (fallbackTicker?.metadata.ticker === symbol ? fallbackTicker : null);
73
73
  const target = quoteSubscriptionTargetFromTicker(ticker, symbol, "provider");
74
- return target
75
- ? { ...target, surface: "monitor" as const, visible: true, selected: symbol === fallbackSymbol, weight: symbol === fallbackSymbol ? 100 : 90 }
76
- : null;
77
- })
78
- .filter((target): target is QuoteSubscriptionTarget => target != null)
79
- ), [fallbackTicker, symbols, tickersBySymbol]);
74
+ if (target) {
75
+ targets.push({ ...target, surface: "monitor", visible: true, selected: symbol === fallbackSymbol, weight: symbol === fallbackSymbol ? 100 : 90 });
76
+ }
77
+ }
78
+ return targets;
79
+ }, [fallbackSymbol, fallbackTicker, symbols, tickersBySymbol]);
80
80
  useQuoteStreaming(streamingTargets);
81
81
  const { pinTicker } = usePluginTickerActions();
82
82
  const { openPaneSettings } = usePluginAppActions();
@@ -99,7 +99,7 @@ export function QuoteMonitorPane({ paneId, focused, width, height }: PaneProps)
99
99
  );
100
100
  }
101
101
 
102
- const columns = resolveGridColumnCount(symbols.length, width, height, nativePaneChrome);
102
+ const columns = resolveGridColumnCount(symbols.length, width, height, nativePaneChrome === true);
103
103
  const rows = chunkSymbols(symbols, columns);
104
104
  const contentWidth = Math.max(1, width - (nativePaneChrome ? 0 : 2));
105
105
  const contentHeight = Math.max(3, height);
@@ -1,7 +1,7 @@
1
1
  import { Box, ScrollBox, Text } from "../../../ui";
2
- import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
3
  import { useShortcut } from "../../../react/input";
4
- import { StaticChartSurface, usePaneFooter } from "../../../components";
4
+ import { StaticChartSurface, type PaneFooterSegment } from "../../../components";
5
5
  import type { PaneProps } from "../../../types/plugin";
6
6
  import type { PluginModule } from "../plugin-module";
7
7
  import { colors } from "../../../theme/colors";
@@ -14,6 +14,7 @@ import {
14
14
  TREASURY_MATURITIES,
15
15
  type YieldPoint,
16
16
  } from "./treasury-data";
17
+ import { usePaneStatusFooter } from "../shared/pane-footer";
17
18
 
18
19
  function formatYield(y: number | null): string {
19
20
  if (y == null) return "—";
@@ -70,15 +71,16 @@ function YieldCurvePane({ focused, width, height }: PaneProps) {
70
71
  const inverted = isInverted(points);
71
72
  const bp = spreadBp(points);
72
73
 
73
- usePaneFooter("yield-curve", () => ({
74
- info: [
74
+ const yieldStatus = useMemo<PaneFooterSegment[]>(() => [
75
75
  ...(inverted ? [{ id: "inverted", parts: [{ text: "INVERTED", tone: "warning" as const, bold: true }] }] : []),
76
76
  ...(bp != null ? [{ id: "spread", parts: [{ text: `2Y-10Y ${bp >= 0 ? "+" : ""}${bp}bp`, tone: bp < 0 ? "warning" as const : "muted" as const }] }] : []),
77
- ...(loading ? [{ id: "loading", parts: [{ text: "loading", tone: "muted" as const }] }] : []),
78
- ...(error ? [{ id: "error", parts: [{ text: error, tone: "warning" as const }] }] : []),
79
- ],
80
- hints: [{ id: "refresh", key: "r", label: "efresh", onPress: () => load() }],
81
- }), [bp, error, inverted, load, loading]);
77
+ ], [bp, inverted]);
78
+ usePaneStatusFooter({
79
+ registrationId: "yield-curve",
80
+ loading,
81
+ error,
82
+ info: yieldStatus,
83
+ });
82
84
 
83
85
  if (loading && points.length === 0) {
84
86
  return (
@@ -13,7 +13,7 @@ export function InputDialog({ resolve, step }: PromptContext<string> & { step: W
13
13
  const [value, setValue] = useState("");
14
14
 
15
15
  useEffect(() => {
16
- inputRef.current?.focus();
16
+ inputRef.current?.focus?.();
17
17
  }, []);
18
18
 
19
19
  return (
@@ -31,8 +31,8 @@ export function InputDialog({ resolve, step }: PromptContext<string> & { step: W
31
31
  textColor={colors.text}
32
32
  placeholderColor={colors.textDim}
33
33
  backgroundColor={colors.bg}
34
- onInput={(nextValue) => setValue(nextValue)}
35
- onChange={(nextValue) => setValue(nextValue)}
34
+ onInput={(nextValue: string) => setValue(nextValue)}
35
+ onChange={(nextValue: string) => setValue(nextValue)}
36
36
  onSubmit={() => resolve(value.trim())}
37
37
  />
38
38
  </Box>
@@ -1,5 +1,5 @@
1
1
  import type { Contract, IBApiNext } from "@stoqey/ib";
2
- import type { TimeRange } from "../../../components/chart/core/types";
2
+ import type { TimeRange } from "../../../time-series/range";
3
3
  import type { Quote, PricePoint, TickerFinancials } from "../../../types/financials";
4
4
  import type { BrokerContractRef } from "../../../types/instrument";
5
5
  import { parseFinStatements, parseReportSnapshot } from "../fundamental-parser";
@@ -4,8 +4,8 @@ import {
4
4
  type ContractDetails,
5
5
  type IBApiNext,
6
6
  } from "@stoqey/ib";
7
- import type { TimeRange } from "../../../components/chart/core/types";
8
- import type { ManualChartResolution } from "../../../components/chart/core/resolution";
7
+ import type { TimeRange } from "../../../time-series/range";
8
+ import type { ManualChartResolution } from "../../../time-series/resolution";
9
9
  import type { PricePoint } from "../../../types/financials";
10
10
  import type { BrokerContractRef } from "../../../types/instrument";
11
11
  import {
@@ -1,10 +1,10 @@
1
1
  import { BarSizeSetting } from "@stoqey/ib";
2
- import type { TimeRange } from "../../../components/chart/core/types";
2
+ import type { TimeRange } from "../../../time-series/range";
3
3
  import {
4
4
  normalizeChartResolutionSupport,
5
5
  type ChartResolutionSupport,
6
6
  type ManualChartResolution,
7
- } from "../../../components/chart/core/resolution";
7
+ } from "../../../time-series/resolution";
8
8
  import type { PricePoint } from "../../../types/financials";
9
9
  import { normalizeIbkrPriceValue } from "./price-normalization";
10
10
 
@@ -22,8 +22,8 @@ export function useIbkrGatewaySelection(
22
22
  ) {
23
23
  const activePortfolio = config.portfolios.find((portfolio) => portfolio.id === collectionId);
24
24
  const gatewayInstances = getConfiguredIbkrGatewayInstances(config);
25
- const lockedBrokerInstanceId = getLockedIbkrTradingInstanceId(config, collectionId);
26
- const selectedBrokerInstanceId = resolveIbkrTradingInstanceId(config, collectionId, preferredInstanceId);
25
+ const lockedBrokerInstanceId = getLockedIbkrTradingInstanceId(config, collectionId ?? null);
26
+ const selectedBrokerInstanceId = resolveIbkrTradingInstanceId(config, collectionId ?? null, preferredInstanceId);
27
27
  const selectedInstance = getBrokerInstance(config.brokerInstances, selectedBrokerInstanceId);
28
28
  const gatewaySnapshot = useGatewaySnapshot(selectedBrokerInstanceId);
29
29
  const gatewayService = selectedBrokerInstanceId ? ibkrGatewayManager.getService(selectedBrokerInstanceId) : null;
@@ -1,5 +1,5 @@
1
- import type { TimeRange } from "../../../../components/chart/core/types";
2
- import type { ChartResolutionSupport, ManualChartResolution } from "../../../../components/chart/core/resolution";
1
+ import type { TimeRange } from "../../../../time-series/range";
2
+ import type { ChartResolutionSupport, ManualChartResolution } from "../../../../time-series/resolution";
3
3
  import { getBrokerRemoteClient } from "../../../../brokers/remote-broker-adapter";
4
4
  import type { BrokerPosition } from "../../../../types/broker";
5
5
  import type { QuoteSubscriptionTarget } from "../../../../types/data-provider";
@@ -4,8 +4,8 @@ import {
4
4
  type ContractDetails,
5
5
  type IBApiNext,
6
6
  } from "@stoqey/ib";
7
- import type { TimeRange } from "../../../../components/chart/core/types";
8
- import type { ChartResolutionSupport, ManualChartResolution } from "../../../../components/chart/core/resolution";
7
+ import type { TimeRange } from "../../../../time-series/range";
8
+ import type { ChartResolutionSupport, ManualChartResolution } from "../../../../time-series/resolution";
9
9
  import type { BrokerConnectionStatus, BrokerPosition } from "../../../../types/broker";
10
10
  import type { QuoteSubscriptionTarget } from "../../../../types/data-provider";
11
11
  import type { Quote, PricePoint, TickerFinancials } from "../../../../types/financials";
@@ -1,10 +1,9 @@
1
- import type { PluginStateStore } from "../data/plugin-state-store";
2
- import type { ResourceStore } from "../data/resource-store";
1
+ import type { AppPluginStateStorePort, AppResourceStorePort } from "../core/app-service-ports";
3
2
  import type { PluginPersistence } from "../types/plugin";
4
3
 
5
4
  export function createPluginPersistence(
6
- pluginState: PluginStateStore,
7
- resources: ResourceStore,
5
+ pluginState: AppPluginStateStorePort,
6
+ resources: AppResourceStorePort,
8
7
  namespace: string,
9
8
  pluginId: string,
10
9
  ): PluginPersistence {
@@ -115,7 +115,7 @@ export function usePredictionControllerKeyboard({
115
115
  if (!scrollBox) return;
116
116
  const maxScrollTop = Math.max(
117
117
  0,
118
- scrollBox.scrollHeight - scrollBox.viewport.height,
118
+ scrollBox.scrollHeight - (scrollBox.viewport?.height ?? 0),
119
119
  );
120
120
  scrollBox.scrollTop = Math.max(
121
121
  0,
@@ -65,6 +65,11 @@ export function applyPredictionTradeUpdate(
65
65
  const normalizedYesPrice = isYes
66
66
  ? trade.price
67
67
  : Math.max(0, 1 - trade.price);
68
+ const normalizedTrade: PredictionTrade = {
69
+ ...trade,
70
+ outcome: isYes ? "yes" : "no",
71
+ price: trade.price,
72
+ };
68
73
  return {
69
74
  ...detailEntry,
70
75
  summary: {
@@ -74,11 +79,7 @@ export function applyPredictionTradeUpdate(
74
79
  noPrice: Math.max(0, 1 - normalizedYesPrice),
75
80
  },
76
81
  trades: [
77
- {
78
- ...trade,
79
- outcome: isYes ? "yes" : "no",
80
- price: trade.price,
81
- },
82
+ normalizedTrade,
82
83
  ...detailEntry.trades,
83
84
  ].slice(0, 40),
84
85
  };
@@ -21,8 +21,8 @@ interface BookRow {
21
21
  }
22
22
 
23
23
  const BOOK_COLUMNS: BookColumn[] = [
24
- { id: "outcome", label: "OUT", width: 5 },
25
- { id: "side", label: "SIDE", width: 6 },
24
+ { id: "outcome", label: "OUT", width: 5, align: "left" },
25
+ { id: "side", label: "SIDE", width: 6, align: "left" },
26
26
  { id: "price", label: "PRICE", width: 8, align: "right" },
27
27
  { id: "size", label: "SIZE", width: 10, align: "right" },
28
28
  ];
@@ -10,6 +10,8 @@ import {
10
10
  import type { PredictionListRow } from "../types";
11
11
  import { sortPredictionOutcomeMarkets } from "../outcome-order";
12
12
 
13
+ type OutcomePointerEvent = { preventDefault(): void };
14
+
13
15
  export function PredictionMarketOutcomesView({
14
16
  detailWidth,
15
17
  onSelectMarket,
@@ -54,7 +56,7 @@ export function PredictionMarketOutcomesView({
54
56
  flexDirection="row"
55
57
  height={1}
56
58
  backgroundColor={selected ? colors.selected : undefined}
57
- onMouseDown={(event) => {
59
+ onMouseDown={(event: OutcomePointerEvent) => {
58
60
  event.preventDefault();
59
61
  onSelectMarket(market.key);
60
62
  }}
@@ -27,6 +27,8 @@ import { PredictionMarketRulesView } from "./rules";
27
27
  import { truncatePredictionText } from "./shared";
28
28
  import { PredictionMarketTradesView } from "./trades";
29
29
 
30
+ type RelatedMarketPointerEvent = { preventDefault(): void };
31
+
30
32
  interface MetricCell {
31
33
  label: string;
32
34
  value: string;
@@ -215,7 +217,7 @@ export function PredictionMarketDetailPane({
215
217
  {relatedSiblings.map((sibling) => (
216
218
  <Box
217
219
  key={sibling.key}
218
- onMouseDown={(event) => {
220
+ onMouseDown={(event: RelatedMarketPointerEvent) => {
219
221
  event.preventDefault();
220
222
  onSelectMarket(sibling.key);
221
223
  }}
@@ -8,9 +8,9 @@ type TradeColumnId = "time" | "side" | "outcome" | "price" | "size";
8
8
  type TradeColumn = DataTableColumn & { id: TradeColumnId };
9
9
 
10
10
  const TRADE_COLUMNS: TradeColumn[] = [
11
- { id: "time", label: "TIME", width: 16 },
12
- { id: "side", label: "SIDE", width: 6 },
13
- { id: "outcome", label: "OUT", width: 4 },
11
+ { id: "time", label: "TIME", width: 16, align: "left" },
12
+ { id: "side", label: "SIDE", width: 6, align: "left" },
13
+ { id: "outcome", label: "OUT", width: 4, align: "left" },
14
14
  { id: "price", label: "PRICE", width: 8, align: "right" },
15
15
  { id: "size", label: "SIZE", width: 10, align: "right" },
16
16
  ];
@@ -1,5 +1,4 @@
1
- import type { AppPersistence } from "../../data/app-persistence";
2
- import type { TickerRepository } from "../../data/ticker-repository";
1
+ import type { AppPersistencePort, AppTickerRepositoryPort } from "../../core/app-service-ports";
3
2
  import type { BrokerInstanceConfig, LayoutConfig } from "../../types/config";
4
3
  import type { DataProvider } from "../../types/data-provider";
5
4
  import type { TickerFinancials } from "../../types/financials";
@@ -30,8 +29,8 @@ export interface RegistryPluginContextOptions {
30
29
  contributions: RegistryContributions;
31
30
  enableCapabilityHandlers: boolean;
32
31
  marketData: DataProvider;
33
- tickerRepository: TickerRepository;
34
- persistence: AppPersistence;
32
+ tickerRepository: AppTickerRepositoryPort;
33
+ persistence: AppPersistencePort;
35
34
  getLayout: () => LayoutConfig;
36
35
  updateLayout: (layout: LayoutConfig) => void;
37
36
  resolvePaneTarget: (paneId: string) => string | undefined;
@@ -1,6 +1,5 @@
1
1
  import type { ReactNode } from "react";
2
- import type { AppPersistence } from "../../data/app-persistence";
3
- import type { TickerRepository } from "../../data/ticker-repository";
2
+ import type { AppPersistencePort, AppTickerRepositoryPort } from "../../core/app-service-ports";
4
3
  import type { BrokerAdapter } from "../../types/broker";
5
4
  import {
6
5
  CapabilityRegistry,
@@ -80,8 +79,8 @@ export class PluginRegistry implements PluginRuntimeAccess {
80
79
  readonly events: EventBus;
81
80
  readonly capabilities: CapabilityRegistry;
82
81
  readonly marketData: DataProvider;
83
- readonly tickerRepository: TickerRepository;
84
- readonly persistence: AppPersistence;
82
+ readonly tickerRepository: AppTickerRepositoryPort;
83
+ readonly persistence: AppPersistencePort;
85
84
  private readonly enableCapabilityHandlers: boolean;
86
85
  private readonly wrapBrokerAdapter?: (broker: BrokerAdapter, pluginId: string) => BrokerAdapter;
87
86
 
@@ -184,8 +183,8 @@ export class PluginRegistry implements PluginRuntimeAccess {
184
183
 
185
184
  constructor(
186
185
  marketData: DataProvider,
187
- tickerRepository: TickerRepository,
188
- persistence: AppPersistence,
186
+ tickerRepository: AppTickerRepositoryPort,
187
+ persistence: AppPersistencePort,
189
188
  options: PluginRegistryOptions = {},
190
189
  ) {
191
190
  this.marketData = marketData;