gloomberb 0.9.9 → 0.10.0

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 (519) hide show
  1. package/README.md +41 -3
  2. package/README.zh-CN.md +294 -0
  3. package/package.json +10 -4
  4. package/patches/@opentui%2Fcore@0.3.2.patch +26 -69
  5. package/src/api-client/auth.ts +2 -0
  6. package/src/api-client/index.test.ts +4 -0
  7. package/src/api-client/types.ts +3 -0
  8. package/src/app/pane-runtime/pane-settings-runtime.tsx +1 -0
  9. package/src/app/pane-template-dialog-wizard.test.tsx +36 -0
  10. package/src/app/pane-template-dialog-wizard.tsx +10 -3
  11. package/src/app/runtime/desktop-deeplink.test.ts +15 -0
  12. package/src/app/runtime/desktop-deeplink.ts +21 -6
  13. package/src/app.tsx +40 -33
  14. package/src/capabilities/service-capabilities.ts +7 -2
  15. package/src/cli/commands/automation.test.ts +202 -0
  16. package/src/cli/commands/automation.ts +153 -36
  17. package/src/cli/commands/market.ts +1 -14
  18. package/src/cli/commands/system.ts +4 -1
  19. package/src/cli/context.ts +1 -1
  20. package/src/cli/desktop-pane-shot.ts +65 -4
  21. package/src/cli/entry.ts +1 -1
  22. package/src/cli/pane-functions/capabilities.ts +532 -0
  23. package/src/cli/pane-functions/catalog.ts +39 -4
  24. package/src/cli/pane-functions/data.test.ts +17 -0
  25. package/src/cli/pane-functions/data.ts +55 -13
  26. package/src/cli/pane-functions/discovery.ts +36 -9
  27. package/src/cli/pane-functions/index.test.ts +104 -1
  28. package/src/cli/pane-functions/index.ts +64 -5
  29. package/src/cli/pane-functions/options.ts +21 -6
  30. package/src/cli/pane-functions/report.ts +735 -72
  31. package/src/cli/pane-functions/resolver.ts +70 -6
  32. package/src/cli/pane-functions/screenshot.test.ts +431 -0
  33. package/src/cli/pane-functions/screenshot.ts +952 -8
  34. package/src/components/chart/composite/column-layout.ts +215 -0
  35. package/src/components/chart/composite/composite-chart.test.tsx +630 -0
  36. package/src/components/chart/composite/composite-chart.tsx +1148 -0
  37. package/src/components/chart/composite/format.test.ts +137 -0
  38. package/src/components/chart/composite/format.ts +135 -0
  39. package/src/components/chart/composite/index.ts +38 -0
  40. package/src/components/chart/composite/interactions.test.ts +109 -0
  41. package/src/components/chart/composite/interactions.ts +247 -0
  42. package/src/components/chart/composite/price-series.test.ts +39 -0
  43. package/src/components/chart/composite/price-series.ts +78 -0
  44. package/src/components/chart/composite/rasterizer.ts +359 -0
  45. package/src/components/chart/composite/renderers.test.ts +610 -0
  46. package/src/components/chart/composite/scene.test.ts +464 -0
  47. package/src/components/chart/composite/scene.ts +553 -0
  48. package/src/components/chart/composite/text-renderer.ts +285 -0
  49. package/src/components/chart/composite/time-scale.test.ts +88 -0
  50. package/src/components/chart/composite/time-scale.ts +217 -0
  51. package/src/components/chart/composite/types.ts +141 -0
  52. package/src/components/chart/core/data.ts +81 -5
  53. package/src/components/chart/core/index.test.ts +128 -43
  54. package/src/components/chart/core/resolution.ts +0 -6
  55. package/src/components/chart/native/chart-rasterizer.ts +1 -3
  56. package/src/components/chart/native/kitty/index.test.ts +99 -120
  57. package/src/components/chart/native/kitty/manager.ts +3 -0
  58. package/src/components/chart/native/kitty/protocol.ts +4 -1
  59. package/src/components/chart/native/raster/crosshair.ts +79 -46
  60. package/src/components/chart/native/raster/types.ts +2 -11
  61. package/src/components/chart/native/surface/manager.ts +48 -3
  62. package/src/components/chart/price-axis-labels.tsx +18 -4
  63. package/src/components/command-bar/commands/direct/index.ts +25 -0
  64. package/src/components/command-bar/commands/registry.ts +9 -0
  65. package/src/components/command-bar/helpers.test.ts +4 -1
  66. package/src/components/command-bar/list/view.tsx +18 -6
  67. package/src/components/command-bar/multi-select-picker.tsx +6 -5
  68. package/src/components/command-bar/pane-settings.test.ts +141 -0
  69. package/src/components/command-bar/pane-settings.ts +61 -1
  70. package/src/components/command-bar/panel/body.tsx +7 -6
  71. package/src/components/command-bar/routes/root/command-items.ts +4 -4
  72. package/src/components/command-bar/routes/root/results.ts +10 -1
  73. package/src/components/command-bar/routes/root/selection.test.ts +54 -0
  74. package/src/components/command-bar/routes/root/selection.ts +13 -0
  75. package/src/components/command-bar/routing/actions.ts +18 -2
  76. package/src/components/command-bar/routing/list-state.ts +2 -1
  77. package/src/components/command-bar/surface/index.test.tsx +36 -4
  78. package/src/components/command-bar/surface/pane.test.tsx +93 -0
  79. package/src/components/command-bar/theme-picker.tsx +2 -1
  80. package/src/components/command-bar/view-model.ts +19 -20
  81. package/src/components/command-bar/workflow/body.tsx +2 -1
  82. package/src/components/command-bar/workflow/field-row.tsx +3 -2
  83. package/src/components/command-bar/workflow/fields.ts +4 -2
  84. package/src/components/command-bar/workflow/ops.test.ts +161 -0
  85. package/src/components/command-bar/workflow/ops.ts +20 -50
  86. package/src/components/command-bar/workflow/route-actions.test.ts +34 -0
  87. package/src/components/command-bar/workflow/route-actions.ts +4 -0
  88. package/src/components/command-bar/workflow/types.ts +1 -0
  89. package/src/components/feed-data-table/stack-view.tsx +6 -5
  90. package/src/components/index.ts +13 -1
  91. package/src/components/layout/detached-pane-shell.tsx +2 -1
  92. package/src/components/layout/floating-pane.tsx +3 -0
  93. package/src/components/layout/header.tsx +15 -8
  94. package/src/components/layout/pane/footer/index.test.tsx +22 -3
  95. package/src/components/layout/pane/footer/index.tsx +3 -1
  96. package/src/components/layout/pane/footer/model.ts +9 -2
  97. package/src/components/layout/pane/header.tsx +4 -6
  98. package/src/components/layout/pane/index.tsx +3 -0
  99. package/src/components/layout/pane/sidebar.test.tsx +100 -0
  100. package/src/components/layout/pane/sidebar.tsx +239 -0
  101. package/src/components/layout/pane/title.ts +4 -3
  102. package/src/components/layout/shell/action-menu-overlay.tsx +5 -3
  103. package/src/components/layout/shell/drag/runtime.ts +2 -0
  104. package/src/components/layout/shell/menu.test.ts +19 -0
  105. package/src/components/layout/shell/menu.ts +8 -5
  106. package/src/components/layout/shell/native/pointer-runtime.ts +4 -1
  107. package/src/components/layout/shell/pane/layers.tsx +2 -2
  108. package/src/components/layout/status-bar.tsx +8 -7
  109. package/src/components/layout/window-controls.tsx +4 -3
  110. package/src/components/metric-treemap/index.tsx +3 -2
  111. package/src/components/onboarding/onboarding-steps.tsx +30 -29
  112. package/src/components/onboarding/onboarding-wizard.tsx +5 -4
  113. package/src/components/onboarding/portfolio-step/broker-fields-panel.tsx +15 -12
  114. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +17 -16
  115. package/src/components/onboarding/portfolio-step/broker-sync-panel.tsx +6 -5
  116. package/src/components/onboarding/portfolio-step/choose-panel.tsx +5 -4
  117. package/src/components/pane-settings-dialog/desktop.tsx +25 -3
  118. package/src/components/pane-settings-dialog/field-dialogs.tsx +5 -4
  119. package/src/components/pane-settings-dialog/tui.tsx +11 -9
  120. package/src/components/pane-settings-dialog/value.ts +8 -5
  121. package/src/components/pane-settings-dialog.test.tsx +235 -0
  122. package/src/components/pane-settings-dialog.tsx +24 -0
  123. package/src/components/pane-template-wizard.tsx +6 -2
  124. package/src/components/ticker/list-table-view.tsx +3 -2
  125. package/src/components/ui/button.tsx +3 -1
  126. package/src/components/ui/choice-dialog.tsx +6 -1
  127. package/src/components/ui/confirm-dialog.tsx +3 -2
  128. package/src/components/ui/fields.tsx +10 -1
  129. package/src/components/ui/frame.tsx +4 -1
  130. package/src/components/ui/index.ts +5 -0
  131. package/src/components/ui/inline-quick-add.tsx +104 -0
  132. package/src/components/ui/list-view.tsx +5 -4
  133. package/src/components/ui/loading.tsx +2 -1
  134. package/src/components/ui/multi-select/dialog.tsx +188 -44
  135. package/src/components/ui/popover.tsx +10 -0
  136. package/src/components/ui/shortcut-hint.tsx +2 -0
  137. package/src/components/ui/status.tsx +4 -3
  138. package/src/components/ui/tabs.tsx +19 -8
  139. package/src/components/ui/toggle.tsx +44 -3
  140. package/src/components/ui/ui.test.tsx +67 -5
  141. package/src/core/app-services.ts +4 -6
  142. package/src/core/state/session-persistence.ts +3 -2
  143. package/src/data/config/chart-settings.ts +712 -0
  144. package/src/data/config/layout.ts +24 -5
  145. package/src/data/config/store/index.test.ts +377 -14
  146. package/src/data/config/store/normalize.ts +79 -65
  147. package/src/data/fred-series.ts +137 -0
  148. package/src/i18n/index.test.ts +114 -0
  149. package/src/i18n/index.ts +147 -0
  150. package/src/i18n/ja.ts +1013 -0
  151. package/src/i18n/ko.ts +1011 -0
  152. package/src/i18n/languages.test.ts +31 -0
  153. package/src/i18n/languages.ts +72 -0
  154. package/src/i18n/zh-cn.ts +1013 -0
  155. package/src/i18n/zh-tw.ts +1013 -0
  156. package/src/plugins/builtin/account-management/footer.ts +3 -2
  157. package/src/plugins/builtin/account-management/form-components.tsx +3 -2
  158. package/src/plugins/builtin/account-management/keyboard.ts +6 -0
  159. package/src/plugins/builtin/account-management/model.ts +25 -21
  160. package/src/plugins/builtin/account-management/navigation.test.ts +27 -0
  161. package/src/plugins/builtin/account-management/navigation.ts +24 -0
  162. package/src/plugins/builtin/account-management/pane.tsx +120 -85
  163. package/src/plugins/builtin/account-management/password-dialog.tsx +10 -9
  164. package/src/plugins/builtin/ai/agent-history.ts +139 -0
  165. package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +133 -51
  166. package/src/plugins/builtin/ai/ask-ai.test.tsx +83 -22
  167. package/src/plugins/builtin/ai/index.test.ts +302 -0
  168. package/src/plugins/builtin/ai/index.tsx +374 -40
  169. package/src/plugins/builtin/ai/pane-settings.test.ts +155 -0
  170. package/src/plugins/builtin/ai/pane-settings.ts +319 -0
  171. package/src/plugins/builtin/ai/pi/credential-store.test.ts +80 -0
  172. package/src/plugins/builtin/ai/pi/credential-store.ts +138 -0
  173. package/src/plugins/builtin/ai/pi/file-store.ts +138 -0
  174. package/src/plugins/builtin/ai/pi/host.test.ts +500 -0
  175. package/src/plugins/builtin/ai/pi/host.ts +564 -0
  176. package/src/plugins/builtin/ai/pi/index.ts +5 -0
  177. package/src/plugins/builtin/ai/pi/models-store.test.ts +44 -0
  178. package/src/plugins/builtin/ai/pi/models-store.ts +141 -0
  179. package/src/plugins/builtin/ai/pi/providers.ts +68 -0
  180. package/src/plugins/builtin/ai/pi/runtime.test.ts +240 -0
  181. package/src/plugins/builtin/ai/pi/runtime.ts +635 -0
  182. package/src/plugins/builtin/ai/providers.test.ts +68 -0
  183. package/src/plugins/builtin/ai/providers.ts +163 -38
  184. package/src/plugins/builtin/ai/runner-selection.test.ts +174 -0
  185. package/src/plugins/builtin/ai/runner-selection.ts +193 -0
  186. package/src/plugins/builtin/ai/runner-selector.tsx +153 -0
  187. package/src/plugins/builtin/ai/runner.test.ts +198 -0
  188. package/src/plugins/builtin/ai/runner.ts +276 -73
  189. package/src/plugins/builtin/ai/screener/contract.test.ts +26 -73
  190. package/src/plugins/builtin/ai/screener/contract.ts +14 -52
  191. package/src/plugins/builtin/ai/screener/editor-runtime.ts +55 -5
  192. package/src/plugins/builtin/ai/screener/editor.tsx +42 -36
  193. package/src/plugins/builtin/ai/screener/footer.ts +82 -67
  194. package/src/plugins/builtin/ai/screener/keyboard.ts +27 -11
  195. package/src/plugins/builtin/ai/screener/model.test.ts +24 -0
  196. package/src/plugins/builtin/ai/screener/model.ts +9 -3
  197. package/src/plugins/builtin/ai/screener/pane.test.tsx +142 -55
  198. package/src/plugins/builtin/ai/screener/pane.tsx +95 -97
  199. package/src/plugins/builtin/ai/screener/results-view.tsx +8 -41
  200. package/src/plugins/builtin/ai/screener/runner.ts +41 -25
  201. package/src/plugins/builtin/ai/screener/tabs-bar.tsx +2 -2
  202. package/src/plugins/builtin/ai/use-runtime-providers.ts +28 -0
  203. package/src/plugins/builtin/ai/workspace/model.test.ts +227 -0
  204. package/src/plugins/builtin/ai/workspace/model.ts +308 -0
  205. package/src/plugins/builtin/ai/workspace/pane.test.tsx +197 -0
  206. package/src/plugins/builtin/ai/workspace/pane.tsx +896 -0
  207. package/src/plugins/builtin/analytics/index.test.tsx +3 -3
  208. package/src/plugins/builtin/analytics/index.tsx +3 -8
  209. package/src/plugins/builtin/broker-manager/detail.tsx +25 -24
  210. package/src/plugins/builtin/broker-manager/index.test.tsx +1 -1
  211. package/src/plugins/builtin/broker-manager/index.tsx +9 -11
  212. package/src/plugins/builtin/broker-manager/model.ts +11 -10
  213. package/src/plugins/builtin/broker-manager/pane-actions.tsx +22 -21
  214. package/src/plugins/builtin/broker-manager/table.ts +9 -8
  215. package/src/plugins/builtin/changelog/index.tsx +3 -8
  216. package/src/plugins/builtin/chart-composer/chart-spec.ts +89 -0
  217. package/src/plugins/builtin/chart-composer/cli-options.ts +98 -0
  218. package/src/plugins/builtin/chart-composer/date-window-dialog.tsx +120 -0
  219. package/src/plugins/builtin/chart-composer/editor.test.tsx +332 -0
  220. package/src/plugins/builtin/chart-composer/editor.tsx +1107 -0
  221. package/src/plugins/builtin/chart-composer/index.tsx +228 -0
  222. package/src/plugins/builtin/chart-composer/pane.tsx +645 -0
  223. package/src/plugins/builtin/chart-composer/presets.test.ts +561 -0
  224. package/src/plugins/builtin/chart-composer/presets.ts +759 -0
  225. package/src/plugins/builtin/chart-composer/quick-add.test.tsx +245 -0
  226. package/src/plugins/builtin/chart-composer/quick-add.tsx +409 -0
  227. package/src/plugins/builtin/chart-composer/semantic.ts +86 -0
  228. package/src/plugins/builtin/chart-composer/series-catalog.test.ts +65 -0
  229. package/src/plugins/builtin/chart-composer/series-catalog.ts +295 -0
  230. package/src/plugins/builtin/chart-composer/settings.test.ts +163 -0
  231. package/src/plugins/builtin/chart-composer/settings.ts +397 -0
  232. package/src/plugins/builtin/chart-composer/shortcuts.test.ts +44 -0
  233. package/src/plugins/builtin/chart-composer/shortcuts.ts +35 -0
  234. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +103 -0
  235. package/src/plugins/builtin/chat/channel-labels.ts +5 -4
  236. package/src/plugins/builtin/chat/channels.ts +12 -11
  237. package/src/plugins/builtin/chat/chat.test.tsx +32 -0
  238. package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
  239. package/src/plugins/builtin/chat/content/composer.tsx +9 -8
  240. package/src/plugins/builtin/chat/content/index.tsx +36 -1
  241. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +8 -7
  242. package/src/plugins/builtin/chat/content/transcript.tsx +9 -3
  243. package/src/plugins/builtin/chat/controller/utils.ts +10 -9
  244. package/src/plugins/builtin/chat/message/desktop.tsx +17 -10
  245. package/src/plugins/builtin/chat/message/profile-popover.test.tsx +122 -3
  246. package/src/plugins/builtin/chat/message/profile-popover.tsx +38 -1
  247. package/src/plugins/builtin/chat/message/terminal.tsx +19 -10
  248. package/src/plugins/builtin/chat/pane-state.test.ts +31 -0
  249. package/src/plugins/builtin/chat/pane-state.ts +30 -0
  250. package/src/plugins/builtin/chat/pane.tsx +27 -4
  251. package/src/plugins/builtin/chat/profile-popover.ts +62 -5
  252. package/src/plugins/builtin/chat/sidebar.test.tsx +4 -7
  253. package/src/plugins/builtin/chat/sidebar.tsx +107 -168
  254. package/src/plugins/builtin/chat/test-harness.tsx +6 -0
  255. package/src/plugins/builtin/cloud/auth-actions.tsx +5 -4
  256. package/src/plugins/builtin/cloud/plugin.tsx +150 -127
  257. package/src/plugins/builtin/composite-plugins.ts +71 -0
  258. package/src/plugins/builtin/correlation/index.test.tsx +4 -4
  259. package/src/plugins/builtin/correlation/index.tsx +3 -8
  260. package/src/plugins/builtin/earnings/index.tsx +37 -21
  261. package/src/plugins/builtin/earnings/model.test.ts +52 -0
  262. package/src/plugins/builtin/earnings/model.ts +32 -0
  263. package/src/plugins/builtin/econ/detail-view.tsx +17 -4
  264. package/src/plugins/builtin/econ/fred-cache.test.ts +57 -11
  265. package/src/plugins/builtin/econ/index.tsx +16 -20
  266. package/src/plugins/builtin/fear-greed/index.tsx +2 -8
  267. package/src/plugins/builtin/fx-matrix/index.tsx +3 -8
  268. package/src/plugins/builtin/help/components.tsx +5 -4
  269. package/src/plugins/builtin/help/index.tsx +14 -17
  270. package/src/plugins/builtin/holders/index.tsx +2 -8
  271. package/src/plugins/builtin/insider/index.tsx +2 -7
  272. package/src/plugins/builtin/kelly-sizer/index.test.tsx +2 -2
  273. package/src/plugins/builtin/kelly-sizer/index.tsx +3 -7
  274. package/src/plugins/builtin/kelly-sizer/test-support.tsx +3 -3
  275. package/src/plugins/builtin/layout-manager/index.tsx +3 -7
  276. package/src/plugins/builtin/market-heatmap/index.tsx +3 -8
  277. package/src/plugins/builtin/market-movers/index.tsx +3 -8
  278. package/src/plugins/builtin/news/index.tsx +12 -16
  279. package/src/plugins/builtin/news/wire/breaking/pane.test.tsx +3 -3
  280. package/src/plugins/builtin/news/wire/index.tsx +83 -73
  281. package/src/plugins/builtin/options/index.tsx +2 -8
  282. package/src/plugins/builtin/plugin-module.test.ts +89 -0
  283. package/src/plugins/builtin/plugin-module.ts +116 -0
  284. package/src/plugins/builtin/portfolio-list/header.tsx +4 -3
  285. package/src/plugins/builtin/portfolio-list/index.test.ts +17 -0
  286. package/src/plugins/builtin/portfolio-list/index.tsx +3 -5
  287. package/src/plugins/builtin/portfolio-list/pane/index.test.tsx +3 -3
  288. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +53 -53
  289. package/src/plugins/builtin/portfolio-list/settings.ts +5 -3
  290. package/src/plugins/builtin/portfolio-list/summary/index.tsx +4 -3
  291. package/src/plugins/builtin/research/index.tsx +2 -8
  292. package/src/plugins/builtin/sec/index.tsx +2 -8
  293. package/src/plugins/builtin/sectors/index.tsx +3 -8
  294. package/src/plugins/builtin/thirteenf/index.tsx +3 -8
  295. package/src/plugins/builtin/thirteenf/pane.test.tsx +1 -1
  296. package/src/plugins/builtin/ticker-detail/chart-tab-switch.test.tsx +49 -23
  297. package/src/plugins/builtin/ticker-detail/index.test.tsx +15 -136
  298. package/src/plugins/builtin/ticker-detail/index.tsx +2 -93
  299. package/src/plugins/builtin/ticker-detail/overview/components.tsx +6 -5
  300. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +41 -17
  301. package/src/plugins/builtin/ticker-detail/pane.tsx +4 -3
  302. package/src/plugins/builtin/ticker-detail/quote-monitor/index.test.tsx +1 -1
  303. package/src/plugins/builtin/ticker-detail/settings.ts +3 -50
  304. package/src/plugins/builtin/ticker-research-backend-plugin.ts +17 -0
  305. package/src/plugins/builtin/ticker-research-plugin.ts +27 -0
  306. package/src/plugins/builtin/tv/channels.ts +27 -0
  307. package/src/plugins/builtin/tv/index.tsx +40 -0
  308. package/src/plugins/builtin/tv/pane.tsx +286 -0
  309. package/src/plugins/builtin/tv/youtube-stream.ts +100 -0
  310. package/src/plugins/builtin/world-indices/index.tsx +3 -8
  311. package/src/plugins/builtin/yield-curve/index.tsx +8 -8
  312. package/src/plugins/catalog-backend.test.ts +21 -0
  313. package/src/plugins/catalog-backend.ts +42 -0
  314. package/src/plugins/catalog-ui.ts +6 -14
  315. package/src/plugins/ibkr/instance-selection.test.ts +0 -1
  316. package/src/plugins/ownership.ts +143 -0
  317. package/src/plugins/prediction-markets/backend-plugin.ts +19 -0
  318. package/src/plugins/prediction-markets/chart.test.tsx +7 -5
  319. package/src/plugins/prediction-markets/chart.tsx +25 -7
  320. package/src/plugins/registry/index.test.ts +51 -0
  321. package/src/plugins/registry/index.ts +8 -0
  322. package/src/plugins/registry/pane-settings.ts +1 -1
  323. package/src/plugins/runtime/index.test.tsx +2 -2
  324. package/src/remote/app-host.tsx +16 -3
  325. package/src/remote/controller.test.ts +102 -1
  326. package/src/remote/controller.ts +122 -0
  327. package/src/remote/types.ts +11 -0
  328. package/src/renderers/electrobun/bun/core-capabilities.ts +123 -27
  329. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +5 -1
  330. package/src/renderers/electrobun/bun/desktop/initialization.ts +5 -1
  331. package/src/renderers/electrobun/bun/desktop/media.ts +15 -0
  332. package/src/renderers/electrobun/bun/desktop/window-style.ts +4 -1
  333. package/src/renderers/electrobun/bun/desktop/workspace/index.test.ts +32 -1
  334. package/src/renderers/electrobun/bun/desktop/workspace/index.ts +10 -0
  335. package/src/renderers/electrobun/bun/index.ts +5 -0
  336. package/src/renderers/electrobun/bun/tui-entry.ts +1 -6
  337. package/src/renderers/electrobun/view/ai-host.ts +124 -19
  338. package/src/renderers/electrobun/view/backend-rpc.ts +4 -0
  339. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +151 -39
  340. package/src/renderers/electrobun/view/desktop/popover.tsx +166 -0
  341. package/src/renderers/electrobun/view/dialog-host.test.ts +25 -0
  342. package/src/renderers/electrobun/view/dialog-host.tsx +75 -12
  343. package/src/renderers/electrobun/view/host/box.tsx +5 -0
  344. package/src/renderers/electrobun/view/host/chart-surface.tsx +10 -9
  345. package/src/renderers/electrobun/view/host/input.tsx +9 -19
  346. package/src/renderers/electrobun/view/host/media-surface.tsx +170 -0
  347. package/src/renderers/electrobun/view/host/mouse.ts +1 -0
  348. package/src/renderers/electrobun/view/host/style.ts +1 -1
  349. package/src/renderers/electrobun/view/host/tabs.tsx +4 -3
  350. package/src/renderers/electrobun/view/main.tsx +10 -3
  351. package/src/renderers/electrobun/view/styles.css +17 -0
  352. package/src/renderers/electrobun/view/ui-host.tsx +7 -0
  353. package/src/renderers/opentui/chart-surface.test.tsx +52 -6
  354. package/src/renderers/opentui/chart-surface.tsx +95 -11
  355. package/src/renderers/opentui/dialog-host.tsx +36 -5
  356. package/src/renderers/opentui/host.tsx +39 -0
  357. package/src/renderers/opentui/start.tsx +30 -0
  358. package/src/renderers/opentui/ui-host.tsx +2 -0
  359. package/src/sources/provider-router/index.test.ts +43 -0
  360. package/src/sources/provider-router/index.ts +4 -0
  361. package/src/sources/provider-router/supplemental.ts +46 -0
  362. package/src/sources/sec-edgar.test.ts +203 -2
  363. package/src/sources/sec-edgar.ts +70 -15
  364. package/src/state/app/context/index.tsx +13 -1
  365. package/src/state/app/context/selector.test.tsx +62 -1
  366. package/src/state/session-persistence.test.ts +13 -2
  367. package/src/sync/controller.test.ts +190 -3
  368. package/src/sync/controller.ts +76 -45
  369. package/src/sync/core-contributors.test.ts +121 -0
  370. package/src/sync/core-contributors.ts +104 -27
  371. package/src/sync/react.ts +6 -8
  372. package/src/sync/types.ts +3 -0
  373. package/src/time-series/alignment.ts +158 -0
  374. package/src/time-series/economic.ts +49 -0
  375. package/src/time-series/field-catalog.ts +306 -0
  376. package/src/time-series/fundamentals.test.ts +505 -0
  377. package/src/time-series/fundamentals.ts +842 -0
  378. package/src/time-series/hooks.ts +45 -0
  379. package/src/time-series/index.ts +14 -0
  380. package/src/time-series/live-quotes.test.ts +219 -0
  381. package/src/time-series/live-quotes.ts +203 -0
  382. package/src/time-series/market-resolution.ts +53 -0
  383. package/src/time-series/market.ts +125 -0
  384. package/src/time-series/reporting.ts +98 -0
  385. package/src/time-series/resolve.test.ts +1281 -0
  386. package/src/time-series/resolve.ts +783 -0
  387. package/src/time-series/spec-studies.test.ts +400 -0
  388. package/src/time-series/spec.ts +487 -0
  389. package/src/time-series/studies.ts +563 -0
  390. package/src/time-series/transforms.test.ts +105 -0
  391. package/src/time-series/transforms.ts +152 -0
  392. package/src/time-series/types.ts +162 -0
  393. package/src/time-series/use-chart-resolution.ts +166 -0
  394. package/src/types/config.ts +9 -11
  395. package/src/types/desktop-window.ts +1 -0
  396. package/src/types/financials.ts +4 -0
  397. package/src/types/media.ts +17 -0
  398. package/src/types/plugin.ts +32 -1
  399. package/src/ui/context-menu.tsx +15 -3
  400. package/src/ui/dialog.tsx +14 -2
  401. package/src/ui/host.tsx +40 -1
  402. package/src/ui/index.tsx +9 -0
  403. package/src/utils/exchanges.test.ts +13 -1
  404. package/src/utils/exchanges.ts +10 -0
  405. package/src/utils/financial-statements.test.ts +138 -0
  406. package/src/utils/financial-statements.ts +115 -8
  407. package/src/utils/format.test.ts +11 -1
  408. package/src/utils/format.ts +7 -0
  409. package/src/version.ts +1 -1
  410. package/src/components/chart/bar-chart-renderer.test.ts +0 -233
  411. package/src/components/chart/bar-chart-renderer.ts +0 -445
  412. package/src/components/chart/comparison/data.test.ts +0 -159
  413. package/src/components/chart/comparison/data.ts +0 -302
  414. package/src/components/chart/comparison/renderer.test.ts +0 -187
  415. package/src/components/chart/comparison/renderer.ts +0 -282
  416. package/src/components/chart/comparison/scene.ts +0 -178
  417. package/src/components/chart/comparison-stock-chart/axis-width.ts +0 -99
  418. package/src/components/chart/comparison-stock-chart/canvas.ts +0 -148
  419. package/src/components/chart/comparison-stock-chart/controls.ts +0 -252
  420. package/src/components/chart/comparison-stock-chart/helpers.ts +0 -101
  421. package/src/components/chart/comparison-stock-chart/interactions.ts +0 -208
  422. package/src/components/chart/comparison-stock-chart/layout-metrics.ts +0 -62
  423. package/src/components/chart/comparison-stock-chart/layout.tsx +0 -155
  424. package/src/components/chart/comparison-stock-chart/legend.tsx +0 -74
  425. package/src/components/chart/comparison-stock-chart/native-surfaces.ts +0 -89
  426. package/src/components/chart/comparison-stock-chart/render-data.ts +0 -227
  427. package/src/components/chart/comparison-stock-chart/render-output.ts +0 -140
  428. package/src/components/chart/comparison-stock-chart/selection-runtime.ts +0 -128
  429. package/src/components/chart/comparison-stock-chart/sources.ts +0 -51
  430. package/src/components/chart/comparison-stock-chart/surface-runtime.ts +0 -159
  431. package/src/components/chart/comparison-stock-chart/toolbar.tsx +0 -117
  432. package/src/components/chart/comparison-stock-chart/types.ts +0 -22
  433. package/src/components/chart/comparison-stock-chart/view.tsx +0 -572
  434. package/src/components/chart/comparison-stock-chart/viewport-runtime.ts +0 -239
  435. package/src/components/chart/comparison-stock-chart.tsx +0 -24
  436. package/src/components/chart/core/axis-measure.ts +0 -33
  437. package/src/components/chart/core/controller.test.ts +0 -157
  438. package/src/components/chart/core/controller.ts +0 -349
  439. package/src/components/chart/core/indicator-selector.tsx +0 -75
  440. package/src/components/chart/core/keyboard.ts +0 -24
  441. package/src/components/chart/core/pane-settings.test.ts +0 -52
  442. package/src/components/chart/core/pane-settings.ts +0 -141
  443. package/src/components/chart/core/scroll.test.ts +0 -64
  444. package/src/components/chart/core/scroll.ts +0 -82
  445. package/src/components/chart/core/window-viewport.test.ts +0 -69
  446. package/src/components/chart/core/window-viewport.ts +0 -162
  447. package/src/components/chart/display-cursor.ts +0 -153
  448. package/src/components/chart/indicators/bands.test.ts +0 -36
  449. package/src/components/chart/indicators/bands.ts +0 -29
  450. package/src/components/chart/indicators/moving-averages.test.ts +0 -39
  451. package/src/components/chart/indicators/moving-averages.ts +0 -42
  452. package/src/components/chart/indicators/options.test.ts +0 -32
  453. package/src/components/chart/indicators/options.ts +0 -107
  454. package/src/components/chart/indicators/oscillators.test.ts +0 -58
  455. package/src/components/chart/indicators/oscillators.ts +0 -92
  456. package/src/components/chart/native/canvas-bitmaps.ts +0 -140
  457. package/src/components/chart/native/raster/comparison-chart.ts +0 -162
  458. package/src/components/chart/native/surface/hooks.ts +0 -144
  459. package/src/components/chart/native/surface/rendering.ts +0 -211
  460. package/src/components/chart/static/bar-chart-surface.test.tsx +0 -101
  461. package/src/components/chart/static/bar-chart-surface.tsx +0 -292
  462. package/src/components/chart/stock-chart/auto.ts +0 -216
  463. package/src/components/chart/stock-chart/axis-width.ts +0 -146
  464. package/src/components/chart/stock-chart/bitmaps.ts +0 -22
  465. package/src/components/chart/stock-chart/canvas.ts +0 -202
  466. package/src/components/chart/stock-chart/controls.tsx +0 -149
  467. package/src/components/chart/stock-chart/cursor.ts +0 -60
  468. package/src/components/chart/stock-chart/data-runtime.ts +0 -128
  469. package/src/components/chart/stock-chart/footer.test.ts +0 -65
  470. package/src/components/chart/stock-chart/footer.ts +0 -303
  471. package/src/components/chart/stock-chart/geometry.ts +0 -160
  472. package/src/components/chart/stock-chart/index.test.ts +0 -532
  473. package/src/components/chart/stock-chart/index.tsx +0 -29
  474. package/src/components/chart/stock-chart/indicators.ts +0 -226
  475. package/src/components/chart/stock-chart/interaction-runtime.ts +0 -44
  476. package/src/components/chart/stock-chart/interactions.ts +0 -300
  477. package/src/components/chart/stock-chart/keyboard.ts +0 -373
  478. package/src/components/chart/stock-chart/layout-metrics.ts +0 -62
  479. package/src/components/chart/stock-chart/layout.tsx +0 -177
  480. package/src/components/chart/stock-chart/native-surfaces.ts +0 -121
  481. package/src/components/chart/stock-chart/presentation.ts +0 -67
  482. package/src/components/chart/stock-chart/renderer-switch.test.tsx +0 -263
  483. package/src/components/chart/stock-chart/rendering/bounds.ts +0 -116
  484. package/src/components/chart/stock-chart/rendering/candidates.ts +0 -145
  485. package/src/components/chart/stock-chart/rendering/data.ts +0 -370
  486. package/src/components/chart/stock-chart/rendering/invalidation.ts +0 -68
  487. package/src/components/chart/stock-chart/rendering/output.ts +0 -304
  488. package/src/components/chart/stock-chart/rendering/planning.ts +0 -122
  489. package/src/components/chart/stock-chart/rendering/projection.test.tsx +0 -98
  490. package/src/components/chart/stock-chart/rendering/projection.ts +0 -112
  491. package/src/components/chart/stock-chart/rendering/state.test.ts +0 -70
  492. package/src/components/chart/stock-chart/rendering/state.ts +0 -283
  493. package/src/components/chart/stock-chart/requests.ts +0 -337
  494. package/src/components/chart/stock-chart/resolution-support.ts +0 -96
  495. package/src/components/chart/stock-chart/resolved/runtime.ts +0 -289
  496. package/src/components/chart/stock-chart/resolved.tsx +0 -359
  497. package/src/components/chart/stock-chart/settings.ts +0 -81
  498. package/src/components/chart/stock-chart/surface-runtime.ts +0 -62
  499. package/src/components/chart/stock-chart/types.ts +0 -25
  500. package/src/components/chart/stock-chart/view.tsx +0 -155
  501. package/src/components/chart/stock-chart/viewport/effects.ts +0 -293
  502. package/src/components/chart/stock-chart/viewport/index.ts +0 -144
  503. package/src/components/chart/stock-chart/viewport/runtime.ts +0 -375
  504. package/src/components/chart/time-axis-label.tsx +0 -175
  505. package/src/plugins/builtin/ai/gloomberb-cli.ts +0 -71
  506. package/src/plugins/builtin/ai/screener/action-bar.tsx +0 -58
  507. package/src/plugins/builtin/comparison-chart/index.test.tsx +0 -848
  508. package/src/plugins/builtin/comparison-chart/index.tsx +0 -194
  509. package/src/plugins/builtin/econ/fred-cache.ts +0 -106
  510. package/src/plugins/builtin/plugin-groups.ts +0 -130
  511. package/src/plugins/builtin/ticker-detail/chart-pane.tsx +0 -91
  512. package/src/plugins/builtin/ticker-detail/chart-tab.tsx +0 -100
  513. package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/content.tsx +0 -296
  514. package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/data.ts +0 -62
  515. package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/model.ts +0 -608
  516. package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/settings.ts +0 -65
  517. package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/types.ts +0 -58
  518. package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph.tsx +0 -138
  519. package/src/plugins/builtin/ticker-detail/data-panes.test.ts +0 -220
@@ -1,144 +0,0 @@
1
- import type { PricePoint } from "../../../../types/financials";
2
- import {
3
- applyDateWindowViewport,
4
- applyPresetDateWindowViewport,
5
- clearActivePreset,
6
- resolvePresetSelection,
7
- resolveResolutionSelection,
8
- resolveStoredChartSelection,
9
- zoomDateWindow,
10
- type DateWindowRange,
11
- } from "../../core/controller";
12
- import type { ManualChartResolution } from "../../core/resolution";
13
- import { getVisiblePointCount } from "../../core/viewport";
14
- import type {
15
- ChartResolution,
16
- ChartViewState,
17
- TimeRange,
18
- } from "../../core/types";
19
-
20
- export type StockChartViewportState = Omit<ChartViewState, "resolution">;
21
- type ResolutionAwareViewportState = StockChartViewportState & { resolution: ChartResolution };
22
-
23
- export type PendingExpansionAction =
24
- | { kind: "zoom-out"; targetVisibleCount: number; anchorRatio: number }
25
- | { kind: "pan-left"; targetPanOffset: number }
26
- | null;
27
-
28
- export function clamp(value: number, min: number, max: number): number {
29
- return Math.max(min, Math.min(max, value));
30
- }
31
-
32
- export function getMaxPanOffset(history: PricePoint[], zoomLevel: number): number {
33
- const visibleCount = getVisiblePointCount(history.length, zoomLevel);
34
- return Math.max(history.length - visibleCount, 0);
35
- }
36
-
37
- function attachViewportResolution(
38
- view: StockChartViewportState,
39
- resolution: ChartResolution,
40
- ): ResolutionAwareViewportState {
41
- return {
42
- ...view,
43
- resolution,
44
- };
45
- }
46
-
47
- function stripViewportResolution(view: ResolutionAwareViewportState): StockChartViewportState {
48
- const { resolution: _resolution, ...viewport } = view;
49
- return viewport;
50
- }
51
-
52
- export function resolveViewportPresetSelection(
53
- view: StockChartViewportState,
54
- presetRange: TimeRange,
55
- supportMaxRange: TimeRange | null = null,
56
- dates: readonly Date[] = [],
57
- ): StockChartViewportState {
58
- return stripViewportResolution(
59
- applyPresetDateWindowViewport(
60
- resolvePresetSelection(attachViewportResolution(view, "auto"), presetRange, supportMaxRange),
61
- dates,
62
- presetRange,
63
- { clearCursor: true },
64
- ),
65
- );
66
- }
67
-
68
- export function resolveViewportResolutionSelection(
69
- view: StockChartViewportState,
70
- resolution: ChartResolution,
71
- support: ReadonlyMap<ManualChartResolution, TimeRange>,
72
- visibleWindow: DateWindowRange | null,
73
- dates: readonly Date[] = [],
74
- ): StockChartViewportState | null {
75
- const nextView = resolveResolutionSelection(
76
- attachViewportResolution(view, resolution),
77
- resolution,
78
- support,
79
- visibleWindow,
80
- );
81
- if (!nextView) return null;
82
- if (resolution === "auto") return stripViewportResolution(nextView);
83
- const nextWindow = nextView.activePreset
84
- ? applyPresetDateWindowViewport(nextView, dates, nextView.presetRange, { clearCursor: true })
85
- : applyDateWindowViewport(nextView, dates, nextView.dateWindow ?? visibleWindow, {
86
- activePreset: null,
87
- clearCursor: true,
88
- });
89
- return stripViewportResolution(nextWindow);
90
- }
91
-
92
- export function resolveViewportStoredSelection(
93
- view: StockChartViewportState,
94
- presetRange: TimeRange,
95
- resolution: ChartResolution,
96
- support: ReadonlyMap<ManualChartResolution, TimeRange>,
97
- dates: readonly Date[] = [],
98
- ): StockChartViewportState {
99
- const nextView = resolveStoredChartSelection(attachViewportResolution(view, resolution), presetRange, resolution, support);
100
- if (nextView.resolution === "auto" || !nextView.activePreset) {
101
- return stripViewportResolution(nextView);
102
- }
103
- return stripViewportResolution(
104
- applyPresetDateWindowViewport(nextView, dates, nextView.presetRange, { clearCursor: true }),
105
- );
106
- }
107
-
108
- export function clearAutoViewportState(view: StockChartViewportState): StockChartViewportState {
109
- const clearedPreset = clearActivePreset(view);
110
- if (clearedPreset.dateWindow === null && clearedPreset.panOffset === 0 && clearedPreset.zoomLevel === 1) {
111
- return clearedPreset;
112
- }
113
- return {
114
- ...clearedPreset,
115
- dateWindow: null,
116
- panOffset: 0,
117
- zoomLevel: 1,
118
- };
119
- }
120
-
121
- export function applyZoomStepAroundAnchor(
122
- view: StockChartViewportState,
123
- zoomFactor: number,
124
- anchorRatio: number,
125
- dates: readonly Date[],
126
- displayedDateWindow?: DateWindowRange | null,
127
- bounds?: DateWindowRange | null,
128
- minimumSpanMs?: number,
129
- ): StockChartViewportState {
130
- if (!Number.isFinite(zoomFactor) || zoomFactor <= 0) return view;
131
- const currentWindow = displayedDateWindow?.start && displayedDateWindow.end
132
- ? displayedDateWindow
133
- : view.dateWindow;
134
- return applyDateWindowViewport(
135
- clearActivePreset(view),
136
- dates,
137
- zoomDateWindow(currentWindow, zoomFactor, anchorRatio),
138
- {
139
- activePreset: null,
140
- bounds,
141
- minimumSpanMs,
142
- },
143
- );
144
- }
@@ -1,375 +0,0 @@
1
- import { useCallback, useRef, type Dispatch, type MutableRefObject, type SetStateAction } from "react";
2
- import { applyBufferedPanExpansion } from "../../core/scroll";
3
- import {
4
- createStoredChartSelectionSyncState,
5
- markStoredChartSelectionLocallyApplied,
6
- } from "../../core/pane-settings";
7
- import {
8
- clampDateWindowToBounds,
9
- resolveVisibleActivePreset,
10
- sameDateWindow,
11
- type DateWindowRange,
12
- } from "../../core/controller";
13
- import {
14
- getExpandedBufferRange,
15
- getNextBufferRange,
16
- getPresetResolution,
17
- getSupportMaxRange,
18
- isRangePresetSupported,
19
- type ChartResolutionSupport,
20
- type ManualChartResolution,
21
- } from "../../core/resolution";
22
- import {
23
- EMPTY_DISPLAY_CURSOR,
24
- type DisplayCursorState,
25
- } from "../../core/pointer";
26
- import type {
27
- ChartRenderMode,
28
- ChartResolution,
29
- TimeRange,
30
- } from "../../core/types";
31
- import type { ChartCursorMotionKind } from "../../cursor-motion";
32
- import type { AutoRenderedView } from "../auto";
33
- import {
34
- clearAutoViewportState,
35
- resolveViewportPresetSelection,
36
- resolveViewportResolutionSelection,
37
- type PendingExpansionAction,
38
- type StockChartViewportState,
39
- } from "./index";
40
- import {
41
- useAutoWindowOverrideSync,
42
- useInteractiveCursorSync,
43
- useManualViewportReconcile,
44
- useStoredRenderModeSync,
45
- useStoredViewportSelectionSync,
46
- } from "./effects";
47
-
48
- interface UseStockChartViewportRuntimeOptions {
49
- availableManualResolutions: readonly ChartResolution[];
50
- autoMinimumSpanMs: number;
51
- baseDateBounds: DateWindowRange | null;
52
- boundsHistoryDates: Date[];
53
- canonicalAutoWindow: DateWindowRange | null;
54
- chartWidth: number;
55
- compact?: boolean;
56
- cursorMotionKindRef: MutableRefObject<ChartCursorMotionKind>;
57
- displayedDateWindow: DateWindowRange | null;
58
- effectiveResolution: ChartResolution;
59
- effectiveResolutionSupport: readonly ChartResolutionSupport[];
60
- interactive?: boolean;
61
- manualVisibleDateWindow: DateWindowRange;
62
- navigableDateWindow: DateWindowRange | null;
63
- pendingAutoWindowOverride: DateWindowRange | null;
64
- pendingAutoWindowRef: MutableRefObject<DateWindowRange | null>;
65
- pendingCanonicalResetRef: MutableRefObject<number>;
66
- pendingExpansionRef: MutableRefObject<PendingExpansionAction>;
67
- persistChartControls: (range: TimeRange, resolution: ChartResolution) => void;
68
- renderedResolution: ChartResolution;
69
- selectionSupportMap: ReadonlyMap<ManualChartResolution, TimeRange>;
70
- persistChartRenderMode: (mode: ChartRenderMode) => void;
71
- setPendingAutoWindowOverride: Dispatch<SetStateAction<DateWindowRange | null>>;
72
- setRenderedAutoView: Dispatch<SetStateAction<AutoRenderedView | null>>;
73
- setRequestedResolution: Dispatch<SetStateAction<ChartResolution>>;
74
- setViewState: Dispatch<SetStateAction<StockChartViewportState>>;
75
- storedRangePreset: TimeRange;
76
- storedRenderMode: ChartRenderMode;
77
- storedResolution: ChartResolution;
78
- supportMap: ReadonlyMap<ManualChartResolution, TimeRange>;
79
- updateDisplayCursorTarget: (next: DisplayCursorState, motionKind: ChartCursorMotionKind) => void;
80
- viewState: StockChartViewportState;
81
- visibleDateWindow: DateWindowRange | null;
82
- }
83
-
84
- export function useStockChartViewportRuntime({
85
- availableManualResolutions,
86
- autoMinimumSpanMs,
87
- baseDateBounds,
88
- boundsHistoryDates,
89
- canonicalAutoWindow,
90
- chartWidth,
91
- compact,
92
- cursorMotionKindRef,
93
- displayedDateWindow,
94
- effectiveResolution,
95
- effectiveResolutionSupport,
96
- interactive,
97
- manualVisibleDateWindow,
98
- navigableDateWindow,
99
- pendingAutoWindowOverride,
100
- pendingAutoWindowRef,
101
- pendingCanonicalResetRef,
102
- pendingExpansionRef,
103
- persistChartControls,
104
- persistChartRenderMode,
105
- renderedResolution,
106
- selectionSupportMap,
107
- setPendingAutoWindowOverride,
108
- setRenderedAutoView,
109
- setRequestedResolution,
110
- setViewState,
111
- storedRangePreset,
112
- storedRenderMode,
113
- storedResolution,
114
- supportMap,
115
- updateDisplayCursorTarget,
116
- viewState,
117
- visibleDateWindow,
118
- }: UseStockChartViewportRuntimeOptions) {
119
- const storedSelectionSyncStateRef = useRef(
120
- createStoredChartSelectionSyncState(storedRangePreset, storedResolution),
121
- );
122
-
123
- useStoredViewportSelectionSync({
124
- boundsHistoryDates,
125
- compact,
126
- pendingAutoWindowRef,
127
- pendingCanonicalResetRef,
128
- selectionSupportMap,
129
- setPendingAutoWindowOverride,
130
- setRenderedAutoView,
131
- setRequestedResolution,
132
- setViewState,
133
- storedRangePreset,
134
- storedResolution,
135
- storedSelectionSyncStateRef,
136
- updateDisplayCursorTarget,
137
- });
138
-
139
- useStoredRenderModeSync({
140
- compact,
141
- setViewState,
142
- storedRenderMode,
143
- });
144
-
145
- useManualViewportReconcile({
146
- boundsHistoryDates,
147
- compact,
148
- effectiveResolution,
149
- pendingCanonicalResetRef,
150
- pendingExpansionRef,
151
- setViewState,
152
- viewState,
153
- });
154
-
155
- useAutoWindowOverrideSync({
156
- autoMinimumSpanMs,
157
- baseDateBounds,
158
- canonicalAutoWindow,
159
- compact,
160
- effectiveResolution,
161
- pendingAutoWindowOverride,
162
- pendingAutoWindowRef,
163
- setPendingAutoWindowOverride,
164
- });
165
-
166
- useInteractiveCursorSync({
167
- chartWidth,
168
- cursorMotionKindRef,
169
- interactive,
170
- setViewState,
171
- updateDisplayCursorTarget,
172
- });
173
-
174
- const persistRenderMode = useCallback((nextMode: ChartRenderMode) => {
175
- if (!compact) {
176
- persistChartRenderMode(nextMode);
177
- }
178
- }, [compact, persistChartRenderMode]);
179
-
180
- const expandBufferRange = useCallback((action: PendingExpansionAction): boolean => {
181
- if (compact) return false;
182
- const expansionResolution = effectiveResolution === "auto" ? "auto" : renderedResolution;
183
- const nextBufferRange = getExpandedBufferRange(viewState.bufferRange, expansionResolution, supportMap);
184
- if (!nextBufferRange) return false;
185
- pendingExpansionRef.current = action;
186
- setViewState((current) => applyBufferedPanExpansion(current, nextBufferRange));
187
- return true;
188
- }, [
189
- compact,
190
- effectiveResolution,
191
- pendingExpansionRef,
192
- renderedResolution,
193
- setViewState,
194
- supportMap,
195
- viewState.bufferRange,
196
- ]);
197
-
198
- const requestAutoWindow = useCallback((nextWindow: DateWindowRange | null | undefined): boolean => {
199
- if (compact || effectiveResolution !== "auto" || !nextWindow?.start || !nextWindow.end || !baseDateBounds?.start || !baseDateBounds.end) {
200
- return false;
201
- }
202
-
203
- if (nextWindow.start.getTime() < baseDateBounds.start.getTime()) {
204
- const nextBufferRange = getNextBufferRange(viewState.bufferRange);
205
- if (nextBufferRange !== viewState.bufferRange) {
206
- pendingAutoWindowRef.current = nextWindow;
207
- setViewState((current) => {
208
- const nextState = clearAutoViewportState(current);
209
- return nextState.bufferRange === nextBufferRange
210
- ? nextState
211
- : { ...nextState, bufferRange: nextBufferRange };
212
- });
213
- return true;
214
- }
215
- }
216
-
217
- const clampedWindow = clampDateWindowToBounds(nextWindow, baseDateBounds, autoMinimumSpanMs);
218
- if (!clampedWindow) {
219
- return false;
220
- }
221
- const normalizedWindow = canonicalAutoWindow && sameDateWindow(clampedWindow, canonicalAutoWindow)
222
- ? null
223
- : clampedWindow;
224
- if (sameDateWindow(navigableDateWindow, normalizedWindow)) {
225
- return false;
226
- }
227
- pendingAutoWindowRef.current = null;
228
- setPendingAutoWindowOverride((current) => (sameDateWindow(current, normalizedWindow) ? current : normalizedWindow));
229
- setViewState((current) => clearAutoViewportState(current));
230
- return true;
231
- }, [
232
- autoMinimumSpanMs,
233
- baseDateBounds,
234
- canonicalAutoWindow,
235
- compact,
236
- effectiveResolution,
237
- navigableDateWindow,
238
- pendingAutoWindowRef,
239
- setPendingAutoWindowOverride,
240
- setViewState,
241
- viewState.bufferRange,
242
- ]);
243
-
244
- const setRange = useCallback((range: TimeRange) => {
245
- if (!compact && !isRangePresetSupported(range, effectiveResolutionSupport)) return;
246
- const supportMaxRange = getSupportMaxRange(effectiveResolutionSupport, getPresetResolution(range));
247
- const nextResolution = getPresetResolution(range);
248
- setRequestedResolution(nextResolution);
249
- if (!compact) {
250
- markStoredChartSelectionLocallyApplied(storedSelectionSyncStateRef.current, range, nextResolution);
251
- persistChartControls(range, nextResolution);
252
- }
253
- pendingCanonicalResetRef.current += 1;
254
- pendingAutoWindowRef.current = null;
255
- setPendingAutoWindowOverride(null);
256
- updateDisplayCursorTarget(EMPTY_DISPLAY_CURSOR, "discrete");
257
- setViewState((current) => resolveViewportPresetSelection(current, range, supportMaxRange, boundsHistoryDates));
258
- }, [
259
- boundsHistoryDates,
260
- compact,
261
- effectiveResolutionSupport,
262
- pendingAutoWindowRef,
263
- pendingCanonicalResetRef,
264
- persistChartControls,
265
- setPendingAutoWindowOverride,
266
- setRequestedResolution,
267
- setViewState,
268
- updateDisplayCursorTarget,
269
- ]);
270
-
271
- const setResolution = useCallback((resolution: ChartResolution) => {
272
- if (compact) return;
273
- if (resolution !== "auto" && !availableManualResolutions.includes(resolution)) return;
274
-
275
- if (resolution === "auto") {
276
- const preservedWindow = effectiveResolution === "auto" ? navigableDateWindow : manualVisibleDateWindow;
277
- const nextAutoWindow = clampDateWindowToBounds(preservedWindow, baseDateBounds, autoMinimumSpanMs);
278
- pendingAutoWindowRef.current = null;
279
- setPendingAutoWindowOverride(
280
- canonicalAutoWindow && nextAutoWindow && sameDateWindow(nextAutoWindow, canonicalAutoWindow)
281
- ? null
282
- : nextAutoWindow,
283
- );
284
- if (effectiveResolution !== "auto") {
285
- setRenderedAutoView(null);
286
- }
287
- setRequestedResolution(resolution);
288
- markStoredChartSelectionLocallyApplied(storedSelectionSyncStateRef.current, viewState.presetRange, resolution);
289
- persistChartControls(viewState.presetRange, resolution);
290
- updateDisplayCursorTarget(EMPTY_DISPLAY_CURSOR, "discrete");
291
- setViewState((current) => ({
292
- ...clearAutoViewportState(current),
293
- bufferRange: getNextBufferRange(current.presetRange),
294
- }));
295
- return;
296
- }
297
-
298
- const nextState = resolveViewportResolutionSelection(
299
- viewState,
300
- resolution,
301
- selectionSupportMap,
302
- visibleDateWindow,
303
- boundsHistoryDates,
304
- );
305
- if (!nextState) return;
306
- setRequestedResolution(resolution);
307
- pendingAutoWindowRef.current = null;
308
- setPendingAutoWindowOverride(null);
309
- pendingCanonicalResetRef.current += 1;
310
- markStoredChartSelectionLocallyApplied(storedSelectionSyncStateRef.current, nextState.presetRange, resolution);
311
- persistChartControls(nextState.presetRange, resolution);
312
- updateDisplayCursorTarget(EMPTY_DISPLAY_CURSOR, "discrete");
313
- setViewState(nextState);
314
- }, [
315
- autoMinimumSpanMs,
316
- availableManualResolutions,
317
- baseDateBounds,
318
- canonicalAutoWindow,
319
- compact,
320
- effectiveResolution,
321
- manualVisibleDateWindow,
322
- navigableDateWindow,
323
- pendingAutoWindowRef,
324
- pendingCanonicalResetRef,
325
- persistChartControls,
326
- selectionSupportMap,
327
- setPendingAutoWindowOverride,
328
- setRenderedAutoView,
329
- setRequestedResolution,
330
- setViewState,
331
- updateDisplayCursorTarget,
332
- viewState,
333
- visibleDateWindow,
334
- boundsHistoryDates,
335
- ]);
336
-
337
- const setRenderMode = useCallback((mode: ChartRenderMode) => {
338
- persistRenderMode(mode);
339
- setViewState((current) => ({ ...current, renderMode: mode }));
340
- }, [persistRenderMode, setViewState]);
341
-
342
- const commitSelectionCursor = useCallback((next: { cursorX: number | null; cursorY: number | null }) => {
343
- setViewState((current) => (
344
- current.cursorX === next.cursorX && current.cursorY === next.cursorY
345
- ? current
346
- : { ...current, cursorX: next.cursorX, cursorY: next.cursorY }
347
- ));
348
- }, [setViewState]);
349
-
350
- const activePreset = compact
351
- ? null
352
- : effectiveResolution === "auto"
353
- ? (canonicalAutoWindow && displayedDateWindow && sameDateWindow(displayedDateWindow, canonicalAutoWindow)
354
- ? viewState.presetRange
355
- : null)
356
- : resolveVisibleActivePreset(boundsHistoryDates, {
357
- presetRange: viewState.presetRange,
358
- activePreset: viewState.activePreset,
359
- dateWindow: viewState.dateWindow,
360
- panOffset: viewState.panOffset,
361
- zoomLevel: viewState.zoomLevel,
362
- resolution: effectiveResolution,
363
- });
364
-
365
- return {
366
- activePreset,
367
- commitSelectionCursor,
368
- expandBufferRange,
369
- persistRenderMode,
370
- requestAutoWindow,
371
- setRange,
372
- setRenderMode,
373
- setResolution,
374
- };
375
- }
@@ -1,175 +0,0 @@
1
- import { useMemo } from "react";
2
- import { Box, Span, Text, useUiCapabilities } from "../../ui";
3
- import { colors } from "../../theme/colors";
4
- import { buildCursorTimeAxisSegments } from "./core/renderer";
5
-
6
- interface TimeAxisLabelProps {
7
- timeLabels: string;
8
- width: number;
9
- cursorColumn: number | null;
10
- cursorPixelX?: number | null;
11
- cursorDate: Date | string | number | null;
12
- dates: Array<Date | string | number>;
13
- cursorColor: string;
14
- }
15
-
16
- interface CursorTimeAxisOverlay {
17
- baseText: string;
18
- label: string | null;
19
- leftPercent: number | null;
20
- }
21
-
22
- function clamp(value: number, min: number, max: number): number {
23
- return Math.max(min, Math.min(max, value));
24
- }
25
-
26
- function normalizeDate(value: Date | string | number): Date | null {
27
- const date = value instanceof Date ? value : new Date(value);
28
- return Number.isFinite(date.getTime()) ? date : null;
29
- }
30
-
31
- export function resolveCursorDateFromAxis({
32
- dates,
33
- width,
34
- cursorColumn,
35
- cursorPixelX,
36
- cellWidthPx,
37
- }: {
38
- dates: Array<Date | string | number>;
39
- width: number;
40
- cursorColumn: number | null;
41
- cursorPixelX?: number | null;
42
- cellWidthPx?: number | null;
43
- }): Date | null {
44
- const normalizedDates = dates
45
- .map(normalizeDate)
46
- .filter((date): date is Date => date !== null);
47
- if (normalizedDates.length === 0) return null;
48
- if (normalizedDates.length === 1) return normalizedDates[0]!;
49
-
50
- let ratio: number | null = null;
51
- if (
52
- cursorPixelX !== null
53
- && cursorPixelX !== undefined
54
- && Number.isFinite(cursorPixelX)
55
- && cellWidthPx !== null
56
- && cellWidthPx !== undefined
57
- && Number.isFinite(cellWidthPx)
58
- && cellWidthPx > 0
59
- ) {
60
- const pixelWidth = Math.max(width * cellWidthPx, 1);
61
- ratio = clamp(cursorPixelX / Math.max(pixelWidth - 1, 1), 0, 1);
62
- } else if (cursorColumn !== null && Number.isFinite(cursorColumn) && width > 1) {
63
- ratio = clamp(cursorColumn / Math.max(width - 1, 1), 0, 1);
64
- }
65
-
66
- if (ratio === null) return null;
67
- const index = Math.round(ratio * (normalizedDates.length - 1));
68
- return normalizedDates[clamp(index, 0, normalizedDates.length - 1)] ?? null;
69
- }
70
-
71
- export function buildCursorTimeAxisOverlay({
72
- segments,
73
- width,
74
- cursorPixelX,
75
- cellWidthPx,
76
- }: {
77
- segments: ReturnType<typeof buildCursorTimeAxisSegments>;
78
- width: number;
79
- cursorPixelX: number | null | undefined;
80
- cellWidthPx: number;
81
- }): CursorTimeAxisOverlay {
82
- const baseText = segments
83
- .map((segment) => (segment.highlighted ? " ".repeat(segment.text.length) : segment.text))
84
- .join("")
85
- .padEnd(width)
86
- .slice(0, width);
87
- const label = segments.find((segment) => segment.highlighted)?.text ?? null;
88
- const pixelWidth = Math.max(width * cellWidthPx, 1);
89
- let leftPercent: number | null = null;
90
- if (label && cursorPixelX !== null && cursorPixelX !== undefined && Number.isFinite(cursorPixelX) && pixelWidth > 1) {
91
- const halfLabelWidth = Math.min((label.length * cellWidthPx) / 2, (pixelWidth - 1) / 2);
92
- const leftPx = clamp(cursorPixelX, halfLabelWidth, Math.max(pixelWidth - halfLabelWidth, halfLabelWidth));
93
- leftPercent = (leftPx / Math.max(pixelWidth - 1, 1)) * 100;
94
- }
95
-
96
- return { baseText, label, leftPercent };
97
- }
98
-
99
- export function TimeAxisLabel({
100
- timeLabels,
101
- width,
102
- cursorColumn,
103
- cursorPixelX = null,
104
- cursorDate,
105
- dates,
106
- cursorColor,
107
- }: TimeAxisLabelProps) {
108
- const { cellWidthPx = 8, fractionalViewport = false } = useUiCapabilities();
109
- const resolvedCursorDate = useMemo(() => {
110
- return resolveCursorDateFromAxis({
111
- dates,
112
- width,
113
- cursorColumn,
114
- cursorPixelX: fractionalViewport ? cursorPixelX : null,
115
- cellWidthPx,
116
- }) ?? cursorDate;
117
- }, [cellWidthPx, cursorColumn, cursorDate, cursorPixelX, dates, fractionalViewport, width]);
118
- const segments = useMemo(() => buildCursorTimeAxisSegments({
119
- timeLabels,
120
- width,
121
- cursorColumn,
122
- cursorDate: resolvedCursorDate,
123
- dates,
124
- }), [cursorColumn, dates, resolvedCursorDate, timeLabels, width]);
125
- const overlay = useMemo(() => buildCursorTimeAxisOverlay({
126
- segments,
127
- width,
128
- cursorPixelX,
129
- cellWidthPx,
130
- }), [cellWidthPx, cursorPixelX, segments, width]);
131
-
132
- if (fractionalViewport && overlay.label && overlay.leftPercent !== null) {
133
- return (
134
- <Box
135
- width={width}
136
- height={1}
137
- overflow="hidden"
138
- style={{ position: "relative" }}
139
- >
140
- <Text fg={colors.textDim} selectable={false} style={{ whiteSpace: "pre" }}>
141
- {overlay.baseText}
142
- </Text>
143
- <Text
144
- fg={cursorColor}
145
- bg={colors.bg}
146
- selectable={false}
147
- style={{
148
- position: "absolute",
149
- left: `${overlay.leftPercent}%`,
150
- top: 0,
151
- transform: "translateX(-50%)",
152
- whiteSpace: "pre",
153
- pointerEvents: "none",
154
- zIndex: 1,
155
- }}
156
- >
157
- {overlay.label}
158
- </Text>
159
- </Box>
160
- );
161
- }
162
-
163
- return (
164
- <Text selectable={false} style={{ whiteSpace: "pre" }}>
165
- {segments.map((segment, index) => (
166
- <Span
167
- key={index}
168
- fg={segment.highlighted ? cursorColor : colors.textDim}
169
- >
170
- {segment.text}
171
- </Span>
172
- ))}
173
- </Text>
174
- );
175
- }