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
@@ -20,6 +20,7 @@ export interface UseChartResolutionResult extends ChartResolutionResult {
20
20
  export interface UseChartResolutionOptions {
21
21
  liveRefreshIntervalMs?: number;
22
22
  autoViewport?: ChartResolveOptions["autoViewport"];
23
+ requestViewport?: ChartResolveOptions["requestViewport"];
23
24
  targetPointCount?: number;
24
25
  }
25
26
 
@@ -30,6 +31,10 @@ const EMPTY_RESULT: ChartResolutionResult = {
30
31
  warnings: [],
31
32
  };
32
33
 
34
+ function hasRenderableData(result: ChartResolutionResult): boolean {
35
+ return (result.bufferedSeries ?? result.series).some((series) => series.points.length > 0);
36
+ }
37
+
33
38
  function withQuoteOverrides(
34
39
  sources: ChartResolveSources,
35
40
  liveOverrides: ReadonlyMap<string, Quote>,
@@ -49,6 +54,8 @@ export function useChartResolution(
49
54
  options: UseChartResolutionOptions = {},
50
55
  ): UseChartResolutionResult {
51
56
  const [result, setResult] = useState<ChartResolutionResult>(EMPTY_RESULT);
57
+ const resultRef = useRef(result);
58
+ resultRef.current = result;
52
59
  const [revision, setRevision] = useState(0);
53
60
  const generationRef = useRef(0);
54
61
  const liveSubscriptionGenerationRef = useRef(0);
@@ -68,9 +75,19 @@ export function useChartResolution(
68
75
  && autoViewportStart <= autoViewportEnd
69
76
  ? { start: new Date(autoViewportStart), end: new Date(autoViewportEnd) }
70
77
  : null;
78
+ const requestViewportStart = options.requestViewport?.start.getTime();
79
+ const requestViewportEnd = options.requestViewport?.end.getTime();
80
+ const validRequestViewport = typeof requestViewportStart === "number"
81
+ && Number.isFinite(requestViewportStart)
82
+ && typeof requestViewportEnd === "number"
83
+ && Number.isFinite(requestViewportEnd)
84
+ && requestViewportStart <= requestViewportEnd
85
+ ? { start: new Date(requestViewportStart), end: new Date(requestViewportEnd) }
86
+ : null;
71
87
  const adaptiveTargetPointCount = validAutoViewport ? options.targetPointCount : undefined;
72
88
  const resolveOptions: ChartResolveOptions = {
73
89
  autoViewport: validAutoViewport,
90
+ requestViewport: validRequestViewport,
74
91
  targetPointCount: adaptiveTargetPointCount,
75
92
  };
76
93
  const latestRequestRef = useRef({ spec, sources, options: resolveOptions });
@@ -89,7 +106,13 @@ export function useChartResolution(
89
106
  cacheIdentityRef.current = { spec, sources, revision };
90
107
  }
91
108
  const cache = resolveCacheRef.current;
92
- setResult((current) => ({ ...current, loading: true, errors: [] }));
109
+ const current = resultRef.current;
110
+ const backgroundRefresh = !resetCache
111
+ && !current.loading
112
+ && hasRenderableData(current);
113
+ if (!backgroundRefresh) {
114
+ setResult((currentResult) => ({ ...currentResult, loading: true, errors: [] }));
115
+ }
93
116
  resolveChartSpecData(
94
117
  spec,
95
118
  withQuoteOverrides(sources, liveQuoteOverridesRef.current),
@@ -97,10 +120,13 @@ export function useChartResolution(
97
120
  resolveOptions,
98
121
  )
99
122
  .then((next) => {
100
- if (generationRef.current === generation) setResult(next);
123
+ if (generationRef.current !== generation) return;
124
+ if (backgroundRefresh && !hasRenderableData(next)) return;
125
+ setResult(next);
101
126
  })
102
127
  .catch((error) => {
103
128
  if (generationRef.current !== generation) return;
129
+ if (backgroundRefresh) return;
104
130
  setResult({
105
131
  series: [],
106
132
  loading: false,
@@ -111,7 +137,16 @@ export function useChartResolution(
111
137
  return () => {
112
138
  if (generationRef.current === generation) generationRef.current += 1;
113
139
  };
114
- }, [adaptiveTargetPointCount, autoViewportEnd, autoViewportStart, revision, sources, spec]);
140
+ }, [
141
+ adaptiveTargetPointCount,
142
+ autoViewportEnd,
143
+ autoViewportStart,
144
+ requestViewportEnd,
145
+ requestViewportStart,
146
+ revision,
147
+ sources,
148
+ spec,
149
+ ]);
115
150
 
116
151
  const liveTargetSignature = liveChartQuoteTargetSignature(spec);
117
152
  const liveRefreshIntervalMs = options.liveRefreshIntervalMs ?? LIVE_CHART_REFRESH_INTERVAL_MS;
@@ -138,7 +173,14 @@ export function useChartResolution(
138
173
  liveSubscriptionGenerationRef.current === subscriptionGeneration
139
174
  && generationRef.current === generation
140
175
  ) {
141
- setResult(next);
176
+ setResult((current) => (
177
+ (request.options.autoViewport || request.options.requestViewport)
178
+ && !current.loading
179
+ && hasRenderableData(current)
180
+ && !hasRenderableData(next)
181
+ ? current
182
+ : next
183
+ ));
142
184
  }
143
185
  } catch (error) {
144
186
  if (
@@ -1,6 +1,6 @@
1
1
  import type { Quote, TickerFinancials, PricePoint, OptionsChain } from "./financials";
2
- import type { TimeRange } from "../components/chart/core/types";
3
- import type { ChartResolutionSupport, ManualChartResolution } from "../components/chart/core/resolution";
2
+ import type { TimeRange } from "../time-series/range";
3
+ import type { ChartResolutionSupport, ManualChartResolution } from "../time-series/resolution";
4
4
  import type { BrokerInstanceConfig } from "./config";
5
5
  import type { QuoteSubscriptionTarget } from "./data-provider";
6
6
  import type { BrokerContractRef, InstrumentSearchResult } from "./instrument";
@@ -7,8 +7,8 @@ import type {
7
7
  OptionsChain,
8
8
  HolderData,
9
9
  } from "./financials";
10
- import type { TimeRange } from "../components/chart/core/types";
11
- import type { ChartResolutionSupport, ManualChartResolution } from "../components/chart/core/resolution";
10
+ import type { TimeRange } from "../time-series/range";
11
+ import type { ChartResolutionSupport, ManualChartResolution } from "../time-series/resolution";
12
12
  import type { BrokerContractRef, InstrumentSearchResult } from "./instrument";
13
13
  import type { CachePolicyMap } from "./persistence";
14
14
 
@@ -100,7 +100,7 @@ export interface QuoteSubscriptionTarget {
100
100
  exchange?: string;
101
101
  context?: MarketDataRequestContext;
102
102
  route?: "auto" | "provider" | "broker";
103
- surface?: "portfolio" | "watchlist" | "detail" | "monitor" | "inline" | "screener" | "unknown";
103
+ surface?: "portfolio" | "watchlist" | "detail" | "monitor" | "inline" | "options" | "screener" | "unknown";
104
104
  visible?: boolean;
105
105
  selected?: boolean;
106
106
  weight?: number;
@@ -2,6 +2,7 @@
2
2
  export type MarketState = "PRE" | "REGULAR" | "POST" | "PREPRE" | "POSTPOST" | "CLOSED";
3
3
  export type SessionConfidence = "explicit" | "derived" | "unknown";
4
4
  export type QuoteDataSource = "live" | "delayed" | "snapshot";
5
+ export type QuoteDelivery = "stream" | "poll";
5
6
 
6
7
  export interface QuoteFieldProvenance {
7
8
  providerId: string;
@@ -33,6 +34,8 @@ export interface Quote {
33
34
  name?: string;
34
35
  lastUpdated: number; // timestamp ms
35
36
  receivedAt?: number; // local receipt timestamp ms for streamed/display freshness
37
+ delivery?: QuoteDelivery;
38
+ stale?: boolean;
36
39
  exchangeName?: string;
37
40
  fullExchangeName?: string;
38
41
  listingExchangeName?: string;
@@ -395,6 +398,8 @@ export interface OptionContract {
395
398
  inTheMoney: boolean;
396
399
  expiration: number;
397
400
  lastTradeDate: number;
401
+ /** Millisecond timestamp for the latest streamed quote applied to this snapshot. */
402
+ lastUpdated?: number;
398
403
  }
399
404
 
400
405
  export interface OptionsChain {
@@ -402,4 +407,11 @@ export interface OptionsChain {
402
407
  expirationDates: number[];
403
408
  calls: OptionContract[];
404
409
  puts: OptionContract[];
410
+ providerId?: string;
411
+ dataSource?: "live" | "delayed";
412
+ feed?: "opra" | "yahoo";
413
+ delayMinutes?: number;
414
+ realtimeEligible?: boolean;
415
+ /** ISO timestamp for the upstream options snapshot. */
416
+ asOf?: string;
405
417
  }
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from "react";
2
- import type { TickerRepository } from "../data/ticker-repository";
2
+ import type { AppTickerRepositoryPort } from "../core/app-service-ports";
3
3
  import type { PluginEvents } from "../plugins/event-bus";
4
4
  import type { PluginLogger } from "../utils/debug-log";
5
5
  import type { BrokerAdapter } from "./broker";
@@ -512,7 +512,7 @@ export interface GloomPluginContext {
512
512
  getPaneDef(paneId: string): PaneDef | undefined;
513
513
 
514
514
  readonly marketData: DataProvider;
515
- readonly tickerRepository: TickerRepository;
515
+ readonly tickerRepository: AppTickerRepositoryPort;
516
516
  readonly persistence: PluginPersistence;
517
517
  readonly log: PluginLogger;
518
518
  readonly resume: PluginResumeState;
@@ -8,6 +8,7 @@ import {
8
8
  contextMenuDivider,
9
9
  hasRunnableContextMenuItem,
10
10
  type ContextMenuContext,
11
+ type ContextMenuDividerItem,
11
12
  type ContextMenuItem,
12
13
  } from "../types/context-menu";
13
14
  import { useRendererHost, useUiCapabilities } from "./host";
@@ -44,19 +45,19 @@ const MENU_SURFACE_SELECTOR = [
44
45
  "[data-gloom-role='tab-button']",
45
46
  ].join(", ");
46
47
 
47
- function isDivider(item: ContextMenuItem): boolean {
48
+ function isDivider(item: ContextMenuItem): item is ContextMenuDividerItem {
48
49
  return item.type === "divider";
49
50
  }
50
51
 
51
52
  export function compactContextMenuItems(items: ContextMenuItem[]): ContextMenuItem[] {
52
53
  const result: ContextMenuItem[] = [];
53
54
  for (const item of items) {
54
- if (item.hidden === true) continue;
55
55
  if (isDivider(item)) {
56
56
  if (result.length === 0 || isDivider(result[result.length - 1]!)) continue;
57
57
  result.push(item);
58
58
  continue;
59
59
  }
60
+ if (item.hidden === true) continue;
60
61
  const nextItem = item.type === "normal" || item.type == null
61
62
  ? {
62
63
  ...item,
package/src/ui/dialog.tsx CHANGED
@@ -11,8 +11,8 @@ export interface PromptContext<T> extends AlertContext {
11
11
  }
12
12
 
13
13
  export interface DialogApi {
14
- alert<T = void>(options: Record<string, unknown>): Promise<T>;
15
- prompt<T = string>(options: Record<string, unknown>): Promise<T>;
14
+ alert(options: Record<string, unknown>): Promise<void>;
15
+ prompt<T = string>(options: Record<string, unknown>): Promise<T | undefined>;
16
16
  }
17
17
 
18
18
  interface DialogContextValue {
@@ -1,4 +1,4 @@
1
- const NAMED_ENTITIES: Record<string, string> = {
1
+ const NAMED_ENTITIES: Readonly<Record<string, string>> = {
2
2
  amp: "&",
3
3
  apos: "'",
4
4
  gt: ">",
@@ -18,13 +18,11 @@ export function decodeHtmlEntities(value: string): string {
18
18
  const normalized = entity.toLowerCase();
19
19
 
20
20
  if (normalized.startsWith("#x")) {
21
- const codePoint = Number.parseInt(normalized.slice(2), 16);
22
- return decodeCodePoint(codePoint, match);
21
+ return decodeCodePoint(Number.parseInt(normalized.slice(2), 16), match);
23
22
  }
24
23
 
25
24
  if (normalized.startsWith("#")) {
26
- const codePoint = Number.parseInt(normalized.slice(1), 10);
27
- return decodeCodePoint(codePoint, match);
25
+ return decodeCodePoint(Number.parseInt(normalized.slice(1), 10), match);
28
26
  }
29
27
 
30
28
  return NAMED_ENTITIES[normalized] ?? match;
@@ -84,7 +84,7 @@ export function startMainThreadMonitor(
84
84
  }, SAMPLE_INTERVAL_MS);
85
85
 
86
86
  const ObserverCtor = (globalThis as { PerformanceObserver?: unknown }).PerformanceObserver;
87
- let observer: { disconnect?: () => void } | null = null;
87
+ let observer: { observe: (options: { entryTypes: string[] }) => void; disconnect?: () => void } | null = null;
88
88
  if (typeof ObserverCtor === "function") {
89
89
  try {
90
90
  observer = new (ObserverCtor as new (callback: (list: { getEntries: () => unknown[] }) => void) => {
@@ -8,7 +8,7 @@ interface PriceHistoryFreshnessOptions {
8
8
  exchange?: string;
9
9
  }
10
10
 
11
- function getPointTimestamp(point: PricePoint): number {
11
+ export function getPricePointTimestamp(point: PricePoint): number {
12
12
  const value = point.date as Date | string | number | null | undefined;
13
13
  if (value instanceof Date) return value.getTime();
14
14
  if (value == null) return Number.NaN;
@@ -20,8 +20,8 @@ function hasValidClose(point: PricePoint): boolean {
20
20
  }
21
21
 
22
22
  function comparePricePointsByDate(left: PricePoint, right: PricePoint): number {
23
- const leftTime = getPointTimestamp(left);
24
- const rightTime = getPointTimestamp(right);
23
+ const leftTime = getPricePointTimestamp(left);
24
+ const rightTime = getPricePointTimestamp(right);
25
25
  const leftValid = Number.isFinite(leftTime);
26
26
  const rightValid = Number.isFinite(rightTime);
27
27
 
@@ -41,7 +41,7 @@ export function normalizePriceHistory(points: PricePoint[]): PricePoint[] {
41
41
  let requiresSort = false;
42
42
 
43
43
  for (const point of points) {
44
- const time = getPointTimestamp(point);
44
+ const time = getPricePointTimestamp(point);
45
45
  if (!Number.isFinite(time)) continue;
46
46
  if (!hasValidClose(point)) continue;
47
47
 
@@ -77,7 +77,7 @@ export function isPriceHistoryStaleForCurrentWindow(
77
77
  const latest = normalized.at(-1);
78
78
  if (!latest) return false;
79
79
 
80
- const latestTime = getPointTimestamp(latest);
80
+ const latestTime = getPricePointTimestamp(latest);
81
81
  if (!Number.isFinite(latestTime) || now - latestTime <= MAX_CURRENT_INTRADAY_HISTORY_LAG_MS) {
82
82
  return false;
83
83
  }
package/src/version.ts CHANGED
@@ -1 +1,3 @@
1
- export const VERSION = "0.10.0";
1
+ import packageJson from "../package.json" with { type: "json" };
2
+
3
+ export const VERSION = packageJson.version;
@@ -1,8 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import { getVisiblePointCount } from "./viewport";
3
-
4
- describe("chart viewport", () => {
5
- test("allows zooming down to a two-point viewport", () => {
6
- expect(getVisiblePointCount(433, 1000)).toBe(2);
7
- });
8
- });
@@ -1,24 +0,0 @@
1
-
2
- const MIN_VISIBLE_POINTS = 2;
3
- export const CHART_ZOOM_STEP_FACTOR = 1.2;
4
- export const RIGHT_EDGE_ANCHOR_RATIO = 1;
5
-
6
- function clamp(value: number, min: number, max: number): number {
7
- return Math.max(min, Math.min(max, value));
8
- }
9
-
10
- function getMaxChartZoom(totalPoints: number): number {
11
- if (totalPoints <= 0) return 1;
12
- return Math.max(1, totalPoints / MIN_VISIBLE_POINTS);
13
- }
14
-
15
- export function clampChartZoom(totalPoints: number, zoomLevel: number): number {
16
- return clamp(zoomLevel, 1, getMaxChartZoom(totalPoints));
17
- }
18
-
19
- export function getVisiblePointCount(totalPoints: number, zoomLevel: number): number {
20
- if (totalPoints <= 0) return 0;
21
-
22
- const clampedZoom = clampChartZoom(totalPoints, zoomLevel);
23
- return Math.min(totalPoints, Math.max(Math.floor(totalPoints / clampedZoom), MIN_VISIBLE_POINTS));
24
- }
@@ -1,14 +0,0 @@
1
- export * from "./alignment";
2
- export * from "./economic";
3
- export * from "./field-catalog";
4
- export * from "./fundamentals";
5
- export * from "./hooks";
6
- export * from "./live-quotes";
7
- export * from "./market";
8
- export * from "./reporting";
9
- export * from "./resolve";
10
- export * from "./spec";
11
- export * from "./studies";
12
- export * from "./transforms";
13
- export * from "./types";
14
- export * from "./use-chart-resolution";