gloomberb 0.10.1 → 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.
- package/package.json +8 -1
- package/src/api-client/auth.ts +1 -0
- package/src/api-client/index.test.ts +359 -108
- package/src/api-client/index.ts +24 -13
- package/src/api-client/socket.ts +70 -35
- package/src/api-client/types.ts +1 -1
- package/src/app/language-observer.test.tsx +82 -0
- package/src/app/language-observer.tsx +13 -0
- package/src/app/pane-runtime/index.tsx +2 -2
- package/src/app/pane-runtime/pane-settings-runtime.tsx +2 -2
- package/src/app/pane-runtime/pane-template-runtime.ts +2 -2
- package/src/app/pane-runtime/plugin-bindings.ts +2 -2
- package/src/app/pane-runtime/ticker-open-runtime.ts +2 -2
- package/src/app/runtime/broker-import.ts +2 -2
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +2 -2
- package/src/app.tsx +16 -7
- package/src/brokers/account-cache.ts +6 -6
- package/src/brokers/broker-ticker-sync.ts +3 -3
- package/src/brokers/remote-broker-adapter.ts +2 -2
- package/src/brokers/sync-broker-instance.ts +5 -6
- package/src/cli/commands/api.ts +3 -6
- package/src/cli/commands/automation.ts +7 -15
- package/src/cli/commands/market.ts +26 -61
- package/src/cli/commands/overview.ts +34 -45
- package/src/cli/commands/search.ts +25 -27
- package/src/cli/commands/system.ts +27 -57
- package/src/cli/commands/ticker.ts +62 -63
- package/src/cli/context.test.ts +63 -0
- package/src/cli/context.ts +15 -1
- package/src/cli/index.ts +1 -1
- package/src/cli/pane-functions/data.ts +2 -19
- package/src/cli/pane-functions/index.ts +26 -25
- package/src/cli/pane-functions/report.ts +1 -1
- package/src/cli/pane-functions/screenshot.ts +3 -3
- package/src/cli/scoped-context.ts +41 -0
- package/src/components/chart/composite/composite-chart.test.tsx +615 -18
- package/src/components/chart/composite/composite-chart.tsx +179 -79
- package/src/components/chart/composite/format.test.ts +20 -7
- package/src/components/chart/composite/index.ts +0 -21
- package/src/components/chart/composite/interactions.test.ts +90 -3
- package/src/components/chart/composite/interactions.ts +189 -24
- package/src/components/chart/composite/price-series.ts +0 -2
- package/src/components/chart/composite/rasterizer.ts +10 -9
- package/src/components/chart/composite/renderers.test.ts +108 -2
- package/src/components/chart/composite/scene.test.ts +36 -0
- package/src/components/chart/composite/scene.ts +5 -2
- package/src/components/chart/composite/text-renderer.ts +37 -25
- package/src/components/chart/composite/time-axis.test.ts +243 -0
- package/src/components/chart/composite/time-axis.ts +608 -0
- package/src/components/chart/composite/types.ts +12 -1
- package/src/components/chart/core/data.ts +2 -159
- package/src/components/chart/core/date-window.ts +6 -225
- package/src/components/chart/core/palette.ts +1 -12
- package/src/components/chart/core/pointer.ts +0 -142
- package/src/components/chart/core/types.ts +1 -58
- package/src/components/chart/cursor-motion.ts +2 -4
- package/src/components/chart/indicators/types.ts +0 -9
- package/src/components/chart/market-session.ts +0 -11
- package/src/components/chart/native/kitty/protocol.ts +1 -1
- package/src/components/chart/native/raster/layout.ts +3 -10
- package/src/components/chart/static/chart/axis-overlays.test.tsx +64 -0
- package/src/components/chart/static/chart/axis-overlays.tsx +59 -14
- package/src/components/chart/static/chart/surface.tsx +1 -2
- package/src/components/command-bar/action-runtime.ts +2 -2
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/panel/body.tsx +2 -2
- package/src/components/command-bar/panel/index.tsx +11 -9
- package/src/components/command-bar/routes/ticker-search/actions.ts +2 -2
- package/src/components/command-bar/surface/index.tsx +2 -2
- package/src/components/command-bar/workflow/body.tsx +3 -3
- package/src/components/command-bar/workflow/collection-actions.ts +2 -2
- package/src/components/command-bar/workflow/coordinator.ts +2 -2
- package/src/components/command-bar/workflow/field-row.tsx +25 -11
- package/src/components/command-bar/workflow/tickers.ts +2 -2
- package/src/components/feed-data-table/stack-view.test.tsx +28 -36
- package/src/components/feed-data-table/stack-view.tsx +3 -1
- package/src/components/layout/detached-pane-shell.tsx +6 -6
- package/src/components/layout/header.tsx +13 -9
- package/src/components/layout/pane/content.test.tsx +42 -3
- package/src/components/layout/pane/content.tsx +3 -1
- package/src/components/layout/pane/footer/index.test.tsx +45 -2
- package/src/components/layout/pane/footer/registration.tsx +3 -1
- package/src/components/layout/shell/index.tsx +1 -2
- package/src/components/layout/shell/native/surfaces.ts +1 -1
- package/src/components/layout/shell/native/window-state.ts +1 -1
- package/src/components/layout/status-bar.tsx +12 -8
- package/src/components/layout/window-controls.tsx +8 -6
- package/src/components/onboarding/onboarding-wizard.tsx +3 -1
- package/src/components/pane-settings-dialog/desktop.tsx +0 -2
- package/src/components/pane-settings-dialog.tsx +0 -2
- package/src/components/pane-template-wizard.tsx +10 -9
- package/src/components/price-performance.tsx +2 -113
- package/src/components/price-sparkline/model.ts +15 -17
- package/src/components/price-sparkline/view.tsx +8 -7
- package/src/components/speedometer-gauge/desktop.tsx +2 -1
- package/src/components/speedometer-gauge/index.tsx +0 -2
- package/src/components/speedometer-gauge/terminal.tsx +24 -5
- package/src/components/ticker/badge/index.tsx +1 -18
- package/src/components/ui/data-table/opentui/index.tsx +3 -3
- package/src/components/ui/frame.tsx +1 -2
- package/src/components/ui/page-stack-view.test.tsx +126 -0
- package/src/components/ui/page-stack-view.tsx +24 -12
- package/src/components/ui/tabs.tsx +7 -3
- package/src/components/ui/ui.test.tsx +23 -2
- package/src/components/use-external-link-footer.ts +4 -2
- package/src/core/app-service-ports.ts +46 -0
- package/src/core/app-services.test.ts +66 -0
- package/src/core/app-services.ts +17 -15
- package/src/data/config/chart-settings.ts +3 -10
- package/src/data/config/store/index.test.ts +99 -2
- package/src/data/config/store/migrations.ts +278 -0
- package/src/data/config/store/normalize.ts +44 -186
- package/src/data/resource-store.ts +73 -12
- package/src/data/sqlite/cache.test.ts +104 -15
- package/src/i18n/index.test.ts +17 -0
- package/src/i18n/index.ts +23 -6
- package/src/i18n/ja.ts +13 -0
- package/src/i18n/ko.ts +13 -0
- package/src/i18n/react.ts +6 -0
- package/src/i18n/zh-cn.ts +13 -0
- package/src/i18n/zh-tw.ts +13 -0
- package/src/market-data/coordinator/auxiliary.ts +7 -3
- package/src/market-data/coordinator/chart.ts +1 -1
- package/src/market-data/coordinator/index.test.ts +26 -0
- package/src/market-data/coordinator/index.ts +11 -5
- package/src/market-data/coordinator/quotes.ts +4 -40
- package/src/market-data/coordinator/subscriptions.test.ts +89 -1
- package/src/market-data/hooks.tsx +47 -1
- package/src/market-data/market/status.ts +6 -6
- package/src/market-data/performance.ts +1 -1
- package/src/market-data/quote-subscription-target.test.ts +37 -0
- package/src/market-data/quote-subscription-target.ts +60 -0
- package/src/market-data/quotes/freshness.ts +1 -0
- package/src/market-data/quotes/resolution.ts +4 -0
- package/src/market-data/request-types.ts +3 -3
- package/src/news/aggregator.test.ts +97 -1
- package/src/news/aggregator.ts +100 -57
- package/src/news/hooks.test.tsx +64 -0
- package/src/news/hooks.ts +18 -25
- package/src/plugins/builtin/account-management/footer.ts +4 -2
- package/src/plugins/builtin/account-management/pane.tsx +9 -4
- package/src/plugins/builtin/ai/agent-history.ts +11 -7
- package/src/plugins/builtin/ai/ask-ai-detail-tab.tsx +0 -5
- package/src/plugins/builtin/ai/ask-ai.test.tsx +3 -4
- package/src/plugins/builtin/ai/index.test.ts +2 -2
- package/src/plugins/builtin/ai/index.tsx +10 -11
- package/src/plugins/builtin/ai/pane-settings.ts +1 -1
- package/src/plugins/builtin/ai/pi/runtime.ts +6 -5
- package/src/plugins/builtin/ai/providers.ts +1 -9
- package/src/plugins/builtin/ai/runner.ts +0 -6
- package/src/plugins/builtin/ai/screener/footer.ts +4 -1
- package/src/plugins/builtin/ai/screener/pane.test.tsx +9 -9
- package/src/plugins/builtin/ai/workspace/model.ts +2 -27
- package/src/plugins/builtin/ai/workspace/pane.tsx +2 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +3 -2
- package/src/plugins/builtin/broker-manager/index.tsx +4 -2
- package/src/plugins/builtin/chart-composer/editor/controller.ts +643 -0
- package/src/plugins/builtin/chart-composer/editor/desktop-view.tsx +134 -0
- package/src/plugins/builtin/chart-composer/editor/model.test.ts +85 -0
- package/src/plugins/builtin/chart-composer/editor/model.ts +292 -0
- package/src/plugins/builtin/chart-composer/editor/opentui-view.tsx +108 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +65 -947
- package/src/plugins/builtin/chart-composer/index.tsx +0 -6
- package/src/plugins/builtin/chart-composer/pane.tsx +69 -36
- package/src/plugins/builtin/chart-composer/presets.ts +1 -19
- package/src/plugins/builtin/chart-composer/settings.ts +1 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +1 -1
- package/src/plugins/builtin/chat/content/shortcuts.ts +0 -1
- package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
- package/src/plugins/builtin/chat/controller/persistence.ts +2 -0
- package/src/plugins/builtin/chat/controller/session.test.ts +25 -0
- package/src/plugins/builtin/chat/controller/session.ts +2 -0
- package/src/plugins/builtin/chat/controller/state.ts +7 -0
- package/src/plugins/builtin/chat/controller.test.ts +73 -20
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -0
- package/src/plugins/builtin/cloud-tweets/footer.ts +9 -28
- package/src/plugins/builtin/cloud-tweets/pane.tsx +0 -5
- package/src/plugins/builtin/cloud-tweets/table.tsx +12 -17
- package/src/plugins/builtin/correlation/compute.ts +4 -10
- package/src/plugins/builtin/econ/index.tsx +17 -19
- package/src/plugins/builtin/holders/types.ts +0 -1
- package/src/plugins/builtin/insider/index.tsx +6 -31
- package/src/plugins/builtin/news/index.tsx +5 -7
- package/src/plugins/builtin/news/wire/breaking/pane.test.tsx +6 -8
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -11
- package/src/plugins/builtin/news/wire/read-state.test.ts +7 -0
- package/src/plugins/builtin/news/wire/read-state.ts +18 -28
- package/src/plugins/builtin/news/wire/rss/parser.ts +1 -11
- package/src/plugins/builtin/options/footer.test.ts +115 -0
- package/src/plugins/builtin/options/footer.ts +110 -0
- package/src/plugins/builtin/options/live-quotes.test.ts +238 -0
- package/src/plugins/builtin/options/live-quotes.ts +147 -0
- package/src/plugins/builtin/options/view.test.tsx +71 -1
- package/src/plugins/builtin/options/view.tsx +39 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +103 -117
- package/src/plugins/builtin/portfolio-list/cli/render.ts +11 -5
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -135
- package/src/plugins/builtin/portfolio-list/header.tsx +9 -4
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +4 -2
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +24 -52
- package/src/plugins/builtin/sec/filing-content.test.ts +41 -0
- package/src/plugins/builtin/sec/filing-content.ts +94 -0
- package/src/plugins/builtin/sec/index.tsx +21 -104
- package/src/plugins/builtin/sectors/sector-model.ts +1 -7
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -0
- package/src/plugins/builtin/shared/pane-footer.ts +82 -0
- package/src/plugins/builtin/shared/read-state.ts +64 -3
- package/src/plugins/builtin/substack/read-state.ts +16 -41
- package/src/plugins/builtin/thirteenf/pane.tsx +24 -73
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +10 -10
- package/src/plugins/builtin/yield-curve/index.tsx +11 -9
- package/src/plugins/ibkr/dialogs.tsx +3 -3
- package/src/plugins/ibkr/gateway/fundamentals.ts +1 -1
- package/src/plugins/ibkr/gateway/history-requests.ts +2 -2
- package/src/plugins/ibkr/gateway/history.ts +2 -2
- package/src/plugins/ibkr/gateway/selection.ts +2 -2
- package/src/plugins/ibkr/gateway/service/index.ts +2 -2
- package/src/plugins/ibkr/gateway/service/native.ts +2 -2
- package/src/plugins/plugin-persistence.ts +3 -4
- package/src/plugins/prediction-markets/controller/keyboard.ts +1 -1
- package/src/plugins/prediction-markets/controller/live-updates.ts +6 -5
- package/src/plugins/prediction-markets/detail/book.tsx +2 -2
- package/src/plugins/prediction-markets/detail/outcomes.tsx +3 -1
- package/src/plugins/prediction-markets/detail/pane.tsx +3 -1
- package/src/plugins/prediction-markets/detail/trades.tsx +3 -3
- package/src/plugins/registry/context.ts +3 -4
- package/src/plugins/registry/index.ts +5 -6
- package/src/react/input.test.ts +126 -3
- package/src/react/input.ts +120 -1
- package/src/remote/app-host.tsx +2 -13
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +44 -60
- package/src/renderers/electrobun/bun/desktop/capability-bridge.ts +15 -13
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +26 -22
- package/src/renderers/electrobun/bun/desktop/http-fetch.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +11 -6
- package/src/renderers/electrobun/bun/desktop/media.ts +5 -3
- package/src/renderers/electrobun/bun/desktop/plugin-state.ts +21 -22
- package/src/renderers/electrobun/bun/desktop/window-controls.ts +3 -1
- package/src/renderers/electrobun/bun/desktop/workspace/requests.ts +18 -18
- package/src/renderers/electrobun/bun/index.ts +123 -83
- package/src/renderers/electrobun/shared/protocol.ts +146 -7
- package/src/renderers/electrobun/view/app-services.ts +5 -8
- package/src/renderers/electrobun/view/backend-rpc.ts +18 -8
- package/src/renderers/electrobun/view/broker-remote-client.ts +2 -2
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +5 -22
- package/src/renderers/electrobun/view/config-host.ts +1 -1
- package/src/renderers/electrobun/view/context-menu.ts +1 -17
- package/src/renderers/electrobun/view/data-table/index.tsx +0 -1
- package/src/renderers/electrobun/view/data-table/row.tsx +0 -4
- package/src/renderers/electrobun/view/desktop/control-styles.ts +37 -34
- package/src/renderers/electrobun/view/desktop/controls.tsx +36 -33
- package/src/renderers/electrobun/view/desktop/list-view.tsx +15 -12
- package/src/renderers/electrobun/view/desktop/popover.tsx +2 -3
- package/src/renderers/electrobun/view/dialog-host.tsx +2 -3
- package/src/renderers/electrobun/view/fatal-screen.tsx +0 -1
- package/src/renderers/electrobun/view/host/box.tsx +0 -1
- package/src/renderers/electrobun/view/host/chart-surface.tsx +0 -1
- package/src/renderers/electrobun/view/host/input.tsx +0 -1
- package/src/renderers/electrobun/view/host/media-surface.tsx +0 -1
- package/src/renderers/electrobun/view/host/native.ts +0 -1
- package/src/renderers/electrobun/view/host/scroll-box.tsx +0 -1
- package/src/renderers/electrobun/view/host/tabs.tsx +0 -1
- package/src/renderers/electrobun/view/host/text.tsx +0 -1
- package/src/renderers/electrobun/view/http-fetch.ts +3 -11
- package/src/renderers/electrobun/view/input-host.tsx +10 -53
- package/src/renderers/electrobun/view/key-event.ts +0 -1
- package/src/renderers/electrobun/view/main.tsx +3 -3
- package/src/renderers/electrobun/view/native-renderer.ts +0 -1
- package/src/renderers/electrobun/view/native-stubs/backend-rpc.ts +13 -1
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +6 -44
- package/src/renderers/electrobun/view/remote/persistence.ts +6 -2
- package/src/renderers/electrobun/view/remote/quote-subscription-registry.test.ts +86 -0
- package/src/renderers/electrobun/view/remote/quote-subscription-registry.ts +72 -0
- package/src/renderers/electrobun/view/remote/ticker-repository.ts +2 -2
- package/src/renderers/electrobun/view/toast-host.tsx +0 -1
- package/src/renderers/electrobun/view/ui-host.tsx +1 -2
- package/src/renderers/electrobun/view/update-host.ts +1 -1
- package/src/renderers/opentui/chart-surface.tsx +2 -1
- package/src/renderers/opentui/dialog-host.tsx +20 -4
- package/src/renderers/opentui/image/loader.ts +12 -2
- package/src/renderers/opentui/input-host.tsx +7 -49
- package/src/renderers/opentui/start.tsx +2 -0
- package/src/sources/gloomberb-cloud/history-quality.ts +44 -0
- package/src/sources/gloomberb-cloud/index.test.ts +173 -0
- package/src/sources/gloomberb-cloud/index.ts +42 -20
- package/src/sources/gloomberb-cloud/normalizers.ts +9 -3
- package/src/sources/provider-router/cache.ts +1 -1
- package/src/sources/provider-router/document-routes.ts +10 -5
- package/src/sources/provider-router/financials.test.ts +14 -0
- package/src/sources/provider-router/financials.ts +6 -1
- package/src/sources/provider-router/history.test.ts +163 -1
- package/src/sources/provider-router/history.ts +278 -347
- package/src/sources/provider-router/index.ts +2 -2
- package/src/sources/provider-router/routing.test.ts +39 -0
- package/src/sources/provider-router/routing.ts +24 -11
- package/src/sources/provider-router/supplemental.ts +37 -17
- package/src/sources/sec-edgar/content.ts +2 -12
- package/src/sources/sec-edgar.ts +2 -13
- package/src/sources/yahoo-finance/history.ts +2 -2
- package/src/sources/yahoo-finance/options.ts +5 -0
- package/src/sources/yahoo-finance.ts +2 -2
- package/src/state/app/bootstrap.ts +2 -2
- package/src/state/app/context/index.tsx +2 -2
- package/src/state/hooks/quote-streaming.ts +66 -1
- package/src/state/hooks/session-snapshot.ts +2 -2
- package/src/state/selectors.ts +0 -9
- package/src/sync/controller.test.ts +98 -0
- package/src/sync/controller.ts +29 -5
- package/src/sync/react.ts +2 -2
- package/src/sync/types.ts +2 -2
- package/src/theme/colors.test.ts +10 -0
- package/src/theme/colors.ts +75 -78
- package/src/theme/theme-context.test.tsx +67 -0
- package/src/theme/theme-context.tsx +9 -5
- package/src/tickers/open-target.ts +2 -2
- package/src/tickers/search/upsert.ts +2 -2
- package/src/time-series/alignment.ts +0 -7
- package/src/time-series/chart-data.ts +145 -0
- package/src/time-series/date-window.ts +44 -0
- package/src/time-series/history-window.ts +21 -0
- package/src/time-series/hooks.test.ts +59 -0
- package/src/time-series/hooks.ts +33 -12
- package/src/time-series/market-resolution.ts +2 -2
- package/src/time-series/market.ts +1 -1
- package/src/time-series/range.ts +9 -0
- package/src/{components/chart/core → time-series}/resolution.ts +3 -102
- package/src/time-series/resolve.test.ts +203 -1
- package/src/time-series/resolve.ts +96 -18
- package/src/time-series/spec-studies.test.ts +15 -0
- package/src/time-series/spec.ts +2 -2
- package/src/time-series/studies.ts +5 -2
- package/src/time-series/types.ts +3 -1
- package/src/time-series/use-chart-resolution.test.tsx +358 -0
- package/src/time-series/use-chart-resolution.ts +46 -4
- package/src/types/broker.ts +2 -2
- package/src/types/data-provider.ts +3 -3
- package/src/types/financials.ts +12 -0
- package/src/types/plugin.ts +2 -2
- package/src/ui/context-menu.tsx +3 -2
- package/src/ui/dialog.tsx +2 -2
- package/src/utils/html-entities.ts +3 -5
- package/src/utils/main-thread-monitor.ts +1 -1
- package/src/utils/price-history.ts +5 -5
- package/src/version.ts +3 -1
- package/src/components/chart/core/viewport.test.ts +0 -8
- package/src/components/chart/core/viewport.ts +0 -24
- package/src/time-series/index.ts +0 -14
- /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
|
-
|
|
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
|
|
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
|
-
}, [
|
|
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(
|
|
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 (
|
package/src/types/broker.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Quote, TickerFinancials, PricePoint, OptionsChain } from "./financials";
|
|
2
|
-
import type { TimeRange } from "../
|
|
3
|
-
import type { ChartResolutionSupport, ManualChartResolution } from "../
|
|
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 "../
|
|
11
|
-
import type { ChartResolutionSupport, ManualChartResolution } from "../
|
|
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;
|
package/src/types/financials.ts
CHANGED
|
@@ -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
|
}
|
package/src/types/plugin.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import type {
|
|
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:
|
|
515
|
+
readonly tickerRepository: AppTickerRepositoryPort;
|
|
516
516
|
readonly persistence: PluginPersistence;
|
|
517
517
|
readonly log: PluginLogger;
|
|
518
518
|
readonly resume: PluginResumeState;
|
package/src/ui/context-menu.tsx
CHANGED
|
@@ -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):
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
24
|
-
const rightTime =
|
|
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 =
|
|
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 =
|
|
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,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
|
-
}
|
package/src/time-series/index.ts
DELETED
|
@@ -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";
|
|
File without changes
|