gloomberb 0.19.2 → 0.19.3
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/README.md +7 -1
- package/package.json +1 -1
- package/patches/electrobun@1.18.1.patch +108 -1
- package/src/account/upgrade-dialog.tsx +4 -23
- package/src/api-client/coalesce.ts +118 -0
- package/src/api-client/credit-boards.ts +13 -0
- package/src/api-client/crypto-etf-flows.ts +6 -0
- package/src/api-client/crypto-markets.ts +40 -0
- package/src/api-client/data.ts +201 -14
- package/src/api-client/equity-screener.ts +10 -0
- package/src/api-client/errors.ts +20 -0
- package/src/api-client/gpu.ts +29 -0
- package/src/api-client/index.ts +5 -2
- package/src/api-client/plan-access.ts +10 -1
- package/src/api-client/plan-rules.ts +35 -0
- package/src/api-client/research-activity.ts +1 -32
- package/src/api-client/types.ts +21 -1
- package/src/app/attention-notice.tsx +94 -0
- package/src/app.tsx +23 -1
- package/src/architecture/core-builtin-allowlist.json +2 -1
- package/src/capabilities/factories.ts +1 -0
- package/src/cli/ascii-output.ts +42 -0
- package/src/cli/base-converter.ts +10 -2
- package/src/cli/command-options.ts +16 -1
- package/src/cli/commands/crypto-hints.ts +23 -4
- package/src/cli/commands/market.ts +92 -23
- package/src/cli/commands/news-search.ts +24 -5
- package/src/cli/commands/overview.ts +9 -4
- package/src/cli/commands/search.ts +71 -12
- package/src/cli/commands/system.ts +22 -30
- package/src/cli/commands/ticker.ts +49 -9
- package/src/cli/commands/version.ts +33 -0
- package/src/cli/context.ts +5 -9
- package/src/cli/data-dir.ts +7 -0
- package/src/cli/desktop-pane-shot-api-policy.ts +85 -0
- package/src/cli/desktop-pane-shot-browser.ts +320 -0
- package/src/cli/desktop-pane-shot-routes.ts +26 -1
- package/src/cli/desktop-pane-shot.ts +196 -256
- package/src/cli/early-command.ts +42 -0
- package/src/cli/earnings-calendar.ts +9 -0
- package/src/cli/entry.ts +19 -13
- package/src/cli/errors.ts +12 -2
- package/src/cli/help.ts +1 -1
- package/src/cli/history-export.ts +22 -2
- package/src/cli/history-rows.ts +154 -4
- package/src/cli/index.ts +18 -1
- package/src/cli/known-gaps.ts +40 -5
- package/src/cli/listing-arg.ts +46 -9
- package/src/cli/options.ts +1 -1
- package/src/cli/output-file.ts +60 -13
- package/src/cli/pane-functions/catalog.ts +14 -3
- package/src/cli/pane-functions/data.ts +1 -1
- package/src/cli/pane-functions/dom.ts +45 -0
- package/src/cli/pane-functions/freshness.ts +46 -9
- package/src/cli/pane-functions/function-help.ts +17 -9
- package/src/cli/pane-functions/headless.ts +22 -14
- package/src/cli/pane-functions/index.ts +6 -2
- package/src/cli/pane-functions/options.ts +6 -2
- package/src/cli/pane-functions/resolver.ts +27 -5
- package/src/cli/pane-functions/screenshot-assessment.ts +33 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +94 -13
- package/src/cli/pane-functions/screenshot-http.ts +70 -0
- package/src/cli/pane-functions/screenshot-render.ts +19 -5
- package/src/cli/quote-answer.ts +20 -0
- package/src/cli/registry.ts +41 -13
- package/src/cli/result.ts +12 -6
- package/src/cli/ticker-resolution.ts +2 -1
- package/src/cli/types.ts +2 -0
- package/src/components/chart/composite/format.ts +3 -0
- package/src/components/chart-table/header.tsx +1 -1
- package/src/components/chart-table/layout.ts +28 -11
- package/src/components/command-bar/action-runtime.ts +4 -0
- package/src/components/command-bar/commands/direct/index.ts +18 -33
- package/src/components/command-bar/commands/direct/runtime.ts +5 -0
- package/src/components/command-bar/commands/registry.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +9 -4
- package/src/components/command-bar/routes/root/runtime.ts +24 -1
- package/src/components/command-bar/surface/index.tsx +9 -3
- package/src/components/company-logo.tsx +2 -1
- package/src/components/layout/header.tsx +8 -3
- package/src/components/layout/market-summary.ts +25 -7
- package/src/components/layout/pane/footer/index.tsx +7 -2
- package/src/components/layout/pane/footer/model.ts +40 -5
- package/src/components/market-board/index.tsx +3 -2
- package/src/components/onboarding/desks-step.tsx +12 -4
- package/src/components/onboarding/first-run-workspace.ts +81 -4
- package/src/components/onboarding/onboarding-frame.tsx +2 -1
- package/src/components/onboarding/onboarding-keyboard.ts +8 -5
- package/src/components/onboarding/onboarding-wizard.tsx +54 -23
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +7 -2
- package/src/components/onboarding/run-setup-again.ts +24 -0
- package/src/components/onboarding/use-onboarding-progress.ts +33 -15
- package/src/components/onboarding/use-onboarding-upgrade.ts +2 -6
- package/src/components/onboarding/wizard-model.ts +57 -3
- package/src/components/onboarding/wizard-positions.ts +1 -1
- package/src/components/ui/delayed-mark.tsx +56 -0
- package/src/components/ui/external-link.tsx +3 -6
- package/src/components/ui/icon.tsx +8 -1
- package/src/components/ui/logo-mark.tsx +8 -5
- package/src/components/ui/stat-grid.tsx +263 -19
- package/src/data/config/store/node.ts +11 -5
- package/src/data/config/store/normalize.ts +16 -3
- package/src/data/profile-permissions.ts +47 -0
- package/src/data/resource-store.ts +34 -31
- package/src/data/sqlite/access.ts +19 -8
- package/src/data/sqlite/checkpointer.ts +95 -8
- package/src/data/sqlite/database.ts +40 -7
- package/src/docs/snapshot.json +191 -78
- package/src/i18n/es.ts +18 -2
- package/src/i18n/ja.ts +18 -2
- package/src/i18n/ko.ts +18 -2
- package/src/i18n/zh-cn.ts +18 -2
- package/src/i18n/zh-tw.ts +18 -2
- package/src/layout/desk-keys.ts +4 -1
- package/src/layout/desks.ts +38 -5
- package/src/layout-marketplace/gallery-desktop.tsx +45 -16
- package/src/market-data/batched-reads.ts +16 -0
- package/src/market-data/coordinator/auxiliary.ts +4 -2
- package/src/market-data/coordinator/index.ts +11 -2
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +3 -1
- package/src/market-data/market/index-level.ts +6 -4
- package/src/market-data/published-apac-sessions.ts +6 -0
- package/src/news/aggregator.ts +7 -4
- package/src/news/news-model.ts +11 -0
- package/src/news/story-id.ts +22 -0
- package/src/news/ticker-symbols.ts +17 -1
- package/src/notifications/app-notifier.ts +35 -14
- package/src/plugins/builtin/account-management/form-components.tsx +1 -1
- package/src/plugins/builtin/account-management/index.tsx +2 -3
- package/src/plugins/builtin/account-management/model.ts +1 -1
- package/src/plugins/builtin/alerts/cli-forms.ts +15 -1
- package/src/plugins/builtin/alerts/events-pane.tsx +7 -5
- package/src/plugins/builtin/alerts/events.ts +10 -2
- package/src/plugins/builtin/alerts/index.tsx +5 -5
- package/src/plugins/builtin/alerts/research-builder.ts +5 -1
- package/src/plugins/builtin/alerts/research-rules.ts +18 -0
- package/src/plugins/builtin/alerts/targets.ts +4 -1
- package/src/plugins/builtin/attention/headless.ts +1 -1
- package/src/plugins/builtin/attention/index.tsx +2 -4
- package/src/plugins/builtin/attention/listing.ts +1 -1
- package/src/plugins/builtin/attention/series.ts +1 -1
- package/src/plugins/builtin/awards/index.tsx +1 -2
- package/src/plugins/builtin/backtest/client.ts +1 -0
- package/src/plugins/builtin/backtest/index.tsx +1 -2
- package/src/plugins/builtin/backtest/rules.ts +3 -1
- package/src/plugins/builtin/backtest/window.ts +8 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +16 -3
- package/src/plugins/builtin/broker-manager/index.tsx +1 -1
- package/src/plugins/builtin/buildout/cells.tsx +5 -0
- package/src/plugins/builtin/buildout/company/flow.tsx +367 -0
- package/src/plugins/builtin/buildout/company/id.ts +2 -0
- package/src/plugins/builtin/buildout/company/model.ts +247 -0
- package/src/plugins/builtin/buildout/company/pane.tsx +317 -0
- package/src/plugins/builtin/buildout/data-runtime.ts +31 -10
- package/src/plugins/builtin/buildout/facilities.ts +309 -0
- package/src/plugins/builtin/buildout/format.ts +9 -0
- package/src/plugins/builtin/buildout/index.tsx +51 -5
- package/src/plugins/builtin/buildout/model/index.ts +62 -10
- package/src/plugins/builtin/buildout/model/normalizers.ts +5 -0
- package/src/plugins/builtin/buildout/model/types.ts +11 -2
- package/src/plugins/builtin/buildout/pane/index.tsx +91 -20
- package/src/plugins/builtin/buildout/pane/status.tsx +1 -1
- package/src/plugins/builtin/buildout/pane/themes.tsx +110 -0
- package/src/plugins/builtin/buildout/table-model.ts +26 -2
- package/src/plugins/builtin/builtin-plugin-meta.ts +16 -0
- package/src/plugins/builtin/cds/headless.ts +10 -2
- package/src/plugins/builtin/cds/model.ts +7 -3
- package/src/plugins/builtin/central-bank-rates/index.tsx +1 -2
- package/src/plugins/builtin/central-bank-rates/pane.tsx +2 -1
- package/src/plugins/builtin/changelog/index.tsx +3 -2
- package/src/plugins/builtin/chart-composer/headless-schema.ts +7 -2
- package/src/plugins/builtin/chart-composer/headless.ts +88 -21
- package/src/plugins/builtin/chart-composer/index.tsx +2 -3
- package/src/plugins/builtin/chart-composer/pane.tsx +26 -2
- package/src/plugins/builtin/chart-composer/series-expression.ts +3 -2
- package/src/plugins/builtin/chart-composer/studies.ts +1 -1
- package/src/plugins/builtin/chat/controller/index.ts +1 -1
- package/src/plugins/builtin/chat/controller/messages.ts +15 -4
- package/src/plugins/builtin/chat/ghost-user.ts +8 -0
- package/src/plugins/builtin/chat/index.tsx +5 -5
- package/src/plugins/builtin/clinical-trials/index.tsx +1 -2
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
- package/src/plugins/builtin/cloud/index.tsx +1 -2
- package/src/plugins/builtin/cloud/plugin.tsx +6 -4
- package/src/plugins/builtin/cloud/team/module.tsx +1 -1
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -1
- package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +24 -1
- package/src/plugins/builtin/cloud/upgrade-status-widget.tsx +39 -15
- package/src/plugins/builtin/comment-letters/index.tsx +1 -2
- package/src/plugins/builtin/commodity-balances/index.tsx +3 -3
- package/src/plugins/builtin/commodity-balances/pane.tsx +2 -2
- package/src/plugins/builtin/congress-trades/aggregates.ts +13 -2
- package/src/plugins/builtin/congress-trades/detail.tsx +20 -4
- package/src/plugins/builtin/congress-trades/headless.ts +2 -0
- package/src/plugins/builtin/congress-trades/model.ts +92 -64
- package/src/plugins/builtin/congress-trades/table.tsx +14 -2
- package/src/plugins/builtin/connections/index.ts +2 -3
- package/src/plugins/builtin/cot/index.tsx +1 -2
- package/src/plugins/builtin/cpi/index.tsx +1 -2
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +2 -1
- package/src/plugins/builtin/credit-boards/client.ts +7 -2
- package/src/plugins/builtin/credit-boards/headless.ts +25 -12
- package/src/plugins/builtin/credit-boards/model.ts +29 -0
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +9 -4
- package/src/plugins/builtin/crypto-board/bitcoin-network.ts +143 -0
- package/src/plugins/builtin/crypto-board/headless.ts +4 -3
- package/src/plugins/builtin/crypto-board/index.tsx +4 -2
- package/src/plugins/builtin/crypto-board/series.ts +2 -0
- package/src/plugins/builtin/crypto-etf-flows/client.ts +9 -2
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +61 -6
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +1 -2
- package/src/plugins/builtin/crypto-etf-flows/model.ts +14 -1
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +8 -5
- package/src/plugins/builtin/debt-maturities/headless.ts +4 -3
- package/src/plugins/builtin/debt-maturities/model.ts +17 -1
- package/src/plugins/builtin/debt-maturities/pane.tsx +18 -4
- package/src/plugins/builtin/debug/index.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/client.ts +32 -2
- package/src/plugins/builtin/dividend-yield/headless.ts +58 -33
- package/src/plugins/builtin/dividend-yield/index.tsx +37 -2
- package/src/plugins/builtin/dividend-yield/pane.tsx +32 -13
- package/src/plugins/builtin/dividend-yield/ranking-reads.ts +73 -0
- package/src/plugins/builtin/dividend-yield/ranking-view.tsx +163 -0
- package/src/plugins/builtin/dividend-yield/ranking.ts +1 -1
- package/src/plugins/builtin/dividend-yield/view.ts +21 -0
- package/src/plugins/builtin/docs/index.tsx +2 -3
- package/src/plugins/builtin/doe/headless.ts +16 -3
- package/src/plugins/builtin/doe/index.tsx +5 -4
- package/src/plugins/builtin/earnings/board.tsx +2 -1
- package/src/plugins/builtin/earnings/history.tsx +2 -1
- package/src/plugins/builtin/earnings-ripple/client.ts +32 -7
- package/src/plugins/builtin/earnings-ripple/index.tsx +1 -2
- package/src/plugins/builtin/econ/calendar-model.ts +29 -6
- package/src/plugins/builtin/econ-statistics/index.tsx +1 -2
- package/src/plugins/builtin/equity-screener/client.ts +1 -1
- package/src/plugins/builtin/equity-screener/headless.ts +1 -0
- package/src/plugins/builtin/equity-screener/ideas.ts +30 -1
- package/src/plugins/builtin/equity-screener/index.tsx +1 -2
- package/src/plugins/builtin/equity-screener/model.ts +28 -4
- package/src/plugins/builtin/equity-screener/pane.tsx +5 -0
- package/src/plugins/builtin/equity-screener/screen-check.ts +23 -1
- package/src/plugins/builtin/estimate-revisions/index.tsx +1 -2
- package/src/plugins/builtin/exposure/holdings.ts +35 -13
- package/src/plugins/builtin/exposure/index.tsx +1 -2
- package/src/plugins/builtin/fear-greed/cli.ts +44 -0
- package/src/plugins/builtin/fear-greed/index.tsx +5 -53
- package/src/plugins/builtin/fear-greed/pane.tsx +2 -1
- package/src/plugins/builtin/fixed-income/index.tsx +1 -2
- package/src/plugins/builtin/futures/board-reads.ts +25 -0
- package/src/plugins/builtin/futures/coalesced-bump.ts +44 -0
- package/src/plugins/builtin/futures/index.tsx +15 -0
- package/src/plugins/builtin/futures/model.ts +14 -0
- package/src/plugins/builtin/futures/use-board-terms.ts +22 -15
- package/src/plugins/builtin/futures/use-front-returns.ts +20 -14
- package/src/plugins/builtin/futures-curve/headless.ts +6 -1
- package/src/plugins/builtin/futures-curve/index.tsx +1 -2
- package/src/plugins/builtin/fx-matrix/index.tsx +2 -2
- package/src/plugins/builtin/gpu/board.tsx +51 -12
- package/src/plugins/builtin/gpu/client.ts +15 -2
- package/src/plugins/builtin/gpu/equities.tsx +5 -2
- package/src/plugins/builtin/gpu/headless.ts +14 -2
- package/src/plugins/builtin/gpu/index.tsx +1 -2
- package/src/plugins/builtin/gpu/model.ts +20 -2
- package/src/plugins/builtin/gpu/pane.tsx +1 -1
- package/src/plugins/builtin/help/index.tsx +1 -1
- package/src/plugins/builtin/holders/index-holders.ts +24 -12
- package/src/plugins/builtin/holders/index.tsx +2 -3
- package/src/plugins/builtin/ipo-calendar/index.tsx +1 -2
- package/src/plugins/builtin/iv-history/index.tsx +1 -2
- package/src/plugins/builtin/jodi/index.tsx +1 -2
- package/src/plugins/builtin/kelly-sizer/index.tsx +1 -2
- package/src/plugins/builtin/layout-manager/index.tsx +9 -8
- package/src/plugins/builtin/macro-day/pane.tsx +4 -2
- package/src/plugins/builtin/market-halts/index.tsx +1 -2
- package/src/plugins/builtin/market-heatmap/index.tsx +11 -2
- package/src/plugins/builtin/market-movers/index.tsx +7 -1
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -1
- package/src/plugins/builtin/market-valuation/index.tsx +1 -2
- package/src/plugins/builtin/members/index.tsx +1 -2
- package/src/plugins/builtin/money-markets/index.tsx +1 -2
- package/src/plugins/builtin/money-markets/pane.tsx +2 -1
- package/src/plugins/builtin/news/headless.ts +7 -0
- package/src/plugins/builtin/news/wire/index.tsx +1 -1
- package/src/plugins/builtin/news/wire/news/pop-out.tsx +9 -3
- package/src/plugins/builtin/notes/index.tsx +3 -6
- package/src/plugins/builtin/openfda/index.tsx +1 -2
- package/src/plugins/builtin/options/view.tsx +6 -5
- package/src/plugins/builtin/options-calculator/index.tsx +1 -2
- package/src/plugins/builtin/options-positioning/index.tsx +1 -2
- package/src/plugins/builtin/options-scenario/index.tsx +2 -4
- package/src/plugins/builtin/perps/index.tsx +1 -2
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -3
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -1
- package/src/plugins/builtin/plugin-module.ts +16 -2
- package/src/plugins/builtin/portfolio-list/cli/render.ts +53 -3
- package/src/plugins/builtin/portfolio-list/index.tsx +1 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +11 -0
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +2 -2
- package/src/plugins/builtin/power/index.tsx +1 -2
- package/src/plugins/builtin/rate-path/index.tsx +1 -2
- package/src/plugins/builtin/realized-vol/headless.ts +2 -0
- package/src/plugins/builtin/realized-vol/index.tsx +1 -2
- package/src/plugins/builtin/realized-vol/model.ts +16 -2
- package/src/plugins/builtin/realized-vol/pane.tsx +3 -3
- package/src/plugins/builtin/relative-rotation/index.tsx +1 -2
- package/src/plugins/builtin/research/analyst-headless.ts +33 -6
- package/src/plugins/builtin/research/analyst-model.ts +37 -2
- package/src/plugins/builtin/research/analyst-pane.tsx +25 -5
- package/src/plugins/builtin/research/index.tsx +5 -8
- package/src/plugins/builtin/research-search/index.tsx +1 -2
- package/src/plugins/builtin/revenue-breakdown/headless.ts +22 -8
- package/src/plugins/builtin/revenue-breakdown/model.ts +23 -0
- package/src/plugins/builtin/reverse-dcf/pane.tsx +4 -2
- package/src/plugins/builtin/roadmap/index.tsx +2 -3
- package/src/plugins/builtin/roadmap/pane.tsx +49 -2
- package/src/plugins/builtin/scanner/hilo-model.ts +18 -1
- package/src/plugins/builtin/scanner/hilo-pane.tsx +12 -2
- package/src/plugins/builtin/scanner/live-pane.tsx +7 -4
- package/src/plugins/builtin/sec/filing-content.ts +38 -6
- package/src/plugins/builtin/sec/headless.ts +5 -1
- package/src/plugins/builtin/sec/index.tsx +4 -2
- package/src/plugins/builtin/sec/model.ts +2 -0
- package/src/plugins/builtin/sectors/index.tsx +11 -5
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/cloud-resource.ts +60 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +24 -1
- package/src/plugins/builtin/shared/forming-bars.ts +29 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +17 -0
- package/src/plugins/builtin/shared/series-detail-chart.tsx +4 -2
- package/src/plugins/builtin/shared/use-quote-board.ts +5 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +2 -1
- package/src/plugins/builtin/short-volume/pane.tsx +2 -1
- package/src/plugins/builtin/social-mentions/index.tsx +1 -2
- package/src/plugins/builtin/social-mentions/pane.tsx +2 -1
- package/src/plugins/builtin/supply-chain/client.ts +22 -1
- package/src/plugins/builtin/supply-chain/graph-client.ts +22 -1
- package/src/plugins/builtin/supply-chain/index.tsx +1 -2
- package/src/plugins/builtin/thirteenf/api.ts +116 -13
- package/src/plugins/builtin/thirteenf/data.ts +132 -30
- package/src/plugins/builtin/thirteenf/index.tsx +2 -4
- package/src/plugins/builtin/thirteenf/model.ts +2 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +20 -11
- package/src/plugins/builtin/thirteenf/types.ts +12 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +17 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +81 -11
- package/src/plugins/builtin/ticker-detail/headless.ts +11 -3
- package/src/plugins/builtin/ticker-detail/index.tsx +5 -10
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +16 -6
- package/src/plugins/builtin/time-sales/index.tsx +1 -2
- package/src/plugins/builtin/time-sales/pane.tsx +3 -1
- package/src/plugins/builtin/trace-bonds/headless.ts +11 -2
- package/src/plugins/builtin/trace-bonds/model.ts +44 -10
- package/src/plugins/builtin/trace-bonds/pane.tsx +12 -7
- package/src/plugins/builtin/treasury-auctions/pane.tsx +2 -2
- package/src/plugins/builtin/vol-surface/client.ts +18 -3
- package/src/plugins/builtin/vol-surface/index.tsx +1 -2
- package/src/plugins/builtin/volatility/index.tsx +1 -2
- package/src/plugins/builtin/world-indices/footer.ts +6 -1
- package/src/plugins/builtin/world-venue-map/client.ts +10 -1
- package/src/plugins/builtin/world-venue-map/index.ts +6 -2
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +48 -7
- package/src/plugins/builtin/world-venue-map/layers.ts +17 -0
- package/src/plugins/builtin/world-venue-map/local-layers.ts +141 -0
- package/src/plugins/builtin/world-venue-map/map-symbols.ts +18 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/scope.ts +63 -0
- package/src/plugins/builtin/yield-curve/curves.ts +16 -2
- package/src/plugins/builtin/yield-curve/headless.ts +3 -3
- package/src/plugins/bundle.ts +52 -2
- package/src/plugins/catalog-browser.ts +2 -2
- package/src/plugins/catalog-cli.ts +20 -0
- package/src/plugins/host-link.ts +13 -1
- package/src/plugins/installer.ts +15 -4
- package/src/plugins/loader.ts +43 -11
- package/src/plugins/peer-imports.ts +201 -0
- package/src/plugins/peer-retry.ts +26 -29
- package/src/plugins/plugin-process.ts +128 -0
- package/src/plugins/redirection-guard.ts +45 -0
- package/src/remote/endpoint.ts +16 -3
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/http-proxy.ts +7 -123
- package/src/renderers/dom/desktop/icons.tsx +2 -0
- package/src/renderers/dom/host/image-surface.tsx +46 -21
- package/src/renderers/dom/styles.css +7 -0
- package/src/renderers/dom/toast-host.tsx +2 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +7 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +3 -2
- package/src/renderers/electrobun/bun/desktop/rpc-timing.ts +88 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +20 -4
- package/src/renderers/electrobun/bun/desktop/view-ids.ts +8 -4
- package/src/renderers/electrobun/bun/external-plugins.ts +4 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -2
- package/src/renderers/electrobun/bun/window/native-timing.ts +48 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +82 -4
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +13 -5
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +3 -0
- package/src/renderers/electrobun/view/main.tsx +7 -2
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -0
- package/src/renderers/opentui/browser-open.ts +10 -4
- package/src/renderers/opentui/image/surface.tsx +1 -1
- package/src/renderers/opentui/start.tsx +12 -6
- package/src/renderers/opentui/toast-host.tsx +2 -1
- package/src/series/registry.ts +18 -0
- package/src/series/standalone.ts +10 -1
- package/src/series/types.ts +7 -0
- package/src/series/validate.ts +11 -2
- package/src/sources/gloomberb-cloud/index.ts +28 -5
- package/src/sources/gloomberb-cloud/news.ts +24 -3
- package/src/sources/gloomberb-cloud/normalizers.ts +17 -2
- package/src/sources/provider-errors.ts +26 -3
- package/src/sources/provider-router/history.ts +5 -0
- package/src/sources/provider-router/index.ts +13 -0
- package/src/sync/core-contributors.ts +32 -0
- package/src/telemetry/attention-counts.ts +64 -6
- package/src/telemetry/attention-setting.ts +33 -0
- package/src/telemetry/crash-reports-node.ts +3 -1
- package/src/telemetry/stall-clocks.ts +93 -0
- package/src/telemetry/stall-reports-node.ts +12 -7
- package/src/telemetry/stall-reports.ts +34 -5
- package/src/test-support/preload.ts +9 -0
- package/src/tickers/company-name.ts +19 -0
- package/src/tickers/listing-fate.ts +14 -3
- package/src/tickers/saved-instrument.ts +17 -0
- package/src/tickers/search/home-listing.ts +13 -2
- package/src/tickers/search/index.ts +4 -1
- package/src/tickers/search/types.ts +6 -1
- package/src/time-series/bar-aggregation.ts +7 -1
- package/src/time-series/base-series.ts +3 -3
- package/src/time-series/chart-bounds.ts +1 -1
- package/src/time-series/chart-data.ts +5 -2
- package/src/time-series/chart-seed.ts +1 -1
- package/src/time-series/coin-session-close.ts +211 -0
- package/src/time-series/live-bars.ts +13 -2
- package/src/time-series/live-quotes.ts +1 -1
- package/src/time-series/official-close.ts +159 -0
- package/src/time-series/price-comparison.ts +55 -6
- package/src/time-series/resolve.ts +12 -3
- package/src/time-series/series-presentation.ts +1 -1
- package/src/time-series/studies/formula.ts +205 -0
- package/src/time-series/studies/indicators.ts +299 -0
- package/src/time-series/studies/leverage.ts +75 -0
- package/src/time-series/studies/pair.ts +138 -0
- package/src/time-series/studies/resolve.ts +333 -0
- package/src/time-series/studies/shared.ts +141 -0
- package/src/time-series/studies/units.ts +243 -0
- package/src/time-series/studies/vwap.ts +274 -0
- package/src/types/config.ts +18 -2
- package/src/types/data-provider.ts +23 -0
- package/src/types/financials.ts +22 -0
- package/src/types/headless.ts +42 -3
- package/src/types/plugin.ts +32 -3
- package/src/ui/host.tsx +11 -0
- package/src/ui/toast.tsx +26 -1
- package/src/utils/ascii-text.ts +140 -0
- package/src/utils/cli-output.ts +91 -18
- package/src/utils/concurrency.ts +24 -0
- package/src/utils/exchanges.ts +6 -0
- package/src/utils/external-url.ts +20 -7
- package/src/utils/futures-generic.ts +4 -4
- package/src/utils/http-proxy-upstream.ts +124 -0
- package/src/utils/main-thread-stall.ts +75 -3
- package/src/utils/perf-marks.ts +36 -2
- package/src/utils/private-files.ts +141 -0
- package/src/utils/public-address.ts +99 -0
- package/src/account/upgrade-personalization.ts +0 -57
- package/src/account/upgrade-tickers.ts +0 -124
- package/src/api-client/upgrade-experiment.ts +0 -91
- package/src/plugins/builtin/cloud/browser.tsx +0 -3
- package/src/renderers/electrobun/launcher/preload.ts +0 -13
- package/src/renderers/electrobun/launcher/windows-emulation.ts +0 -50
- package/src/time-series/studies.ts +0 -1628
|
@@ -3,7 +3,6 @@ import { commandRequestParams } from "../shared/command-tab";
|
|
|
3
3
|
import { ipoCalendarCache } from "./client";
|
|
4
4
|
import { ipoCalendarHeadless } from "./headless";
|
|
5
5
|
import { IPO_CALENDAR_PANE_ID } from "./model";
|
|
6
|
-
import { IpoCalendarPane } from "./pane";
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* `IPO japan` opens the calendar on that search, and so does a later `IPO europe`: one pane, the open one
|
|
@@ -44,7 +43,7 @@ export const ipoCalendarPlugin: GloomPlugin = {
|
|
|
44
43
|
id: IPO_CALENDAR_PANE_ID,
|
|
45
44
|
name: "IPO Calendar",
|
|
46
45
|
icon: "I",
|
|
47
|
-
component: IpoCalendarPane,
|
|
46
|
+
get component(): typeof import("./pane").IpoCalendarPane { const { IpoCalendarPane } = require("./pane"); return IpoCalendarPane; },
|
|
48
47
|
defaultPosition: "right",
|
|
49
48
|
defaultMode: "floating",
|
|
50
49
|
defaultFloatingSize: { width: 110, height: 28 },
|
|
@@ -3,14 +3,13 @@ import type { PluginModule } from "../plugin-module";
|
|
|
3
3
|
import { IV_SERIES } from "./series";
|
|
4
4
|
import { createTickerSurfacePaneTemplate } from "../shared/ticker-surface";
|
|
5
5
|
import { ivHistoryHeadless, ivScreenHeadless } from "./headless";
|
|
6
|
-
import { IvHistoryPane } from "./pane";
|
|
7
6
|
import { IvScreenPane, VCA_SCOPE_OPTIONS } from "./screen-pane";
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
export const ivHistoryModule: PluginModule = {
|
|
11
10
|
series: IV_SERIES,
|
|
12
11
|
panes: [{
|
|
13
|
-
id: "iv-history", name: "Implied Volatility History", icon: "V", component: IvHistoryPane,
|
|
12
|
+
id: "iv-history", name: "Implied Volatility History", icon: "V", get component(): typeof import("./pane").IvHistoryPane { const { IvHistoryPane } = require("./pane"); return IvHistoryPane; },
|
|
14
13
|
defaultPosition: "right", tickerFollower: true, defaultMode: "floating", defaultFloatingSize: { width: 118, height: 36 },
|
|
15
14
|
tableExport: true,
|
|
16
15
|
settings: { title: "Implied Volatility History", fields: [
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { PluginModule } from "../plugin-module";
|
|
2
2
|
import { jodiHeadless } from "./headless";
|
|
3
3
|
import { JODI_PANE_ID } from "./model";
|
|
4
|
-
import { JodiPane } from "./pane";
|
|
5
4
|
|
|
6
5
|
export const jodiModule: PluginModule = {
|
|
7
6
|
panes: [
|
|
@@ -9,7 +8,7 @@ export const jodiModule: PluginModule = {
|
|
|
9
8
|
id: JODI_PANE_ID,
|
|
10
9
|
name: "Oil and Gas Balances",
|
|
11
10
|
icon: "O",
|
|
12
|
-
component: JodiPane,
|
|
11
|
+
get component(): typeof import("./pane").JodiPane { const { JodiPane } = require("./pane"); return JodiPane; },
|
|
13
12
|
defaultPosition: "right",
|
|
14
13
|
defaultMode: "floating",
|
|
15
14
|
defaultFloatingSize: { width: 110, height: 30 },
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { PaneTemplateContext, PaneTemplateCreateOptions } from "../../../types/plugin";
|
|
2
2
|
import type { PluginModule } from "../plugin-module";
|
|
3
3
|
import { DEFAULT_FLOATING_SIZE, KELLY_PANE_ID } from "./constants";
|
|
4
|
-
import { KellySizerPane } from "./pane";
|
|
5
4
|
import { kellyHeadless } from "./headless";
|
|
6
5
|
|
|
7
6
|
function resolveTemplateSymbol(context: PaneTemplateContext, options?: PaneTemplateCreateOptions): string | null {
|
|
@@ -21,7 +20,7 @@ export const positionSizerModule: PluginModule = {
|
|
|
21
20
|
icon: "K",
|
|
22
21
|
// The bankroll is the account's value.
|
|
23
22
|
personalData: "holdings",
|
|
24
|
-
component: KellySizerPane,
|
|
23
|
+
get component(): typeof import("./pane").KellySizerPane { const { KellySizerPane } = require("./pane"); return KellySizerPane; },
|
|
25
24
|
defaultPosition: "right",
|
|
26
25
|
defaultMode: "floating",
|
|
27
26
|
defaultFloatingSize: DEFAULT_FLOATING_SIZE,
|
|
@@ -2,7 +2,6 @@ import { findPaneInstance, type LayoutConfig } from "../../../types/config";
|
|
|
2
2
|
import type { AppNotificationRequest, CommandResultDef, GloomPluginContext } from "../../../types/plugin";
|
|
3
3
|
import type { PluginModule } from "../plugin-module";
|
|
4
4
|
import type { AppAction } from "../../../state/app/context";
|
|
5
|
-
import { LayoutMarketplacePane } from "../../../layout-marketplace/pane";
|
|
6
5
|
import { apiClient } from "../../../api-client";
|
|
7
6
|
import { resolvePlanAccess } from "../../../api-client/plan-access";
|
|
8
7
|
import { getSharedRegistry } from "../../registry";
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
deskFunctions,
|
|
12
11
|
DESKS,
|
|
13
12
|
isDeskStock,
|
|
13
|
+
MORE_DESKS,
|
|
14
14
|
pickDeskCompany,
|
|
15
15
|
type Desk,
|
|
16
16
|
} from "../../../layout/desks";
|
|
@@ -60,10 +60,11 @@ function getFocusedPane(layout: LayoutConfig, focusedPaneId: string | null) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/** Desks whose key, name or one of whose functions matches what follows DESK. */
|
|
63
|
-
function matchDesks(query: string): Desk[] {
|
|
63
|
+
function matchDesks(query: string): Desk<string>[] {
|
|
64
64
|
const needle = query.trim().toLowerCase();
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
const desks: Desk<string>[] = [...DESKS, ...MORE_DESKS];
|
|
66
|
+
if (!needle) return desks;
|
|
67
|
+
return desks.filter((desk) => (
|
|
67
68
|
desk.key.startsWith(needle)
|
|
68
69
|
|| desk.label.toLowerCase().includes(needle)
|
|
69
70
|
|| desk.name.toLowerCase().includes(needle)
|
|
@@ -75,7 +76,7 @@ function matchDesks(query: string): Desk[] {
|
|
|
75
76
|
* Opens the desk as a new tab after the others. Its company is the focused
|
|
76
77
|
* pane's stock, else the most recent stock the user looked at.
|
|
77
78
|
*/
|
|
78
|
-
async function addDesk(ctx: GloomPluginContext, desk: Desk): Promise<void> {
|
|
79
|
+
async function addDesk(ctx: GloomPluginContext, desk: Desk<string>): Promise<void> {
|
|
79
80
|
const registry = getSharedRegistry();
|
|
80
81
|
if (!registry || !dispatchRef || !getStateRef) return;
|
|
81
82
|
const config = ctx.getConfig();
|
|
@@ -110,8 +111,8 @@ export const layoutManagerModule: PluginModule = {
|
|
|
110
111
|
id: "layout-marketplace",
|
|
111
112
|
name: "Layouts",
|
|
112
113
|
icon: "L",
|
|
113
|
-
component: LayoutMarketplacePane,
|
|
114
|
-
reportFreshness: { status: "not-a-feed", basis: "layout listings" },
|
|
114
|
+
get component(): typeof import("../../../layout-marketplace/pane").LayoutMarketplacePane { const { LayoutMarketplacePane } = require("../../../layout-marketplace/pane"); return LayoutMarketplacePane; },
|
|
115
|
+
reportFreshness: { status: "not-a-feed", basis: "layout listings", local: true },
|
|
115
116
|
defaultPosition: "right",
|
|
116
117
|
defaultMode: "floating",
|
|
117
118
|
defaultFloatingSize: { width: 118, height: 34 },
|
|
@@ -128,7 +129,7 @@ export const layoutManagerModule: PluginModule = {
|
|
|
128
129
|
label: "Add a Desk",
|
|
129
130
|
description: "Add a ready-made desk for one kind of trading as a new layout tab",
|
|
130
131
|
keywords: ["desk", "desks", "workspace", "starter", "equities", "stocks", "options", "volatility", "futures",
|
|
131
|
-
"commodities", "rates", "credit", "fx", "macro", "active trading", "day trading"],
|
|
132
|
+
"commodities", "rates", "credit", "fx", "macro", "active trading", "day trading", "buildout", "ai buildout", "data centers"],
|
|
132
133
|
category: "config",
|
|
133
134
|
shortcut: "DESK",
|
|
134
135
|
shortcutArg: { placeholder: "desk", kind: "text", parse: (arg) => ({ query: arg.trim() }) },
|
|
@@ -152,7 +152,9 @@ export function MacroDayPane({ width, height, focused }: PaneProps) {
|
|
|
152
152
|
return { text: times(event.multiple), value: event.multiple };
|
|
153
153
|
}, [colors, model?.basis, release]);
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
// A figure wraps only into rows the table's least leaves, so the pane never spills.
|
|
156
|
+
const statMaxLines = height - 1 - 4;
|
|
157
|
+
const contentHeight = Math.max(4, height - 1 - statGridRows(stats, width, undefined, { maxLines: statMaxLines }));
|
|
156
158
|
const key = (event: MacroDayEvent) => `${event.kind}:${event.date}`;
|
|
157
159
|
|
|
158
160
|
return <Box width={width} height={height} flexDirection="column" overflow="hidden">
|
|
@@ -164,7 +166,7 @@ export function MacroDayPane({ width, height, focused }: PaneProps) {
|
|
|
164
166
|
{!symbol ? <EmptyState title="Select a ticker." /> : <PaneStatusBody subject="macro-day moves" loading={history.loading && !model}
|
|
165
167
|
error={!model ? history.error ?? identityError ?? null : null} empty={!!model && !model.events.length}>
|
|
166
168
|
{model ? <>
|
|
167
|
-
<StatGrid items={stats} width={width} />
|
|
169
|
+
<StatGrid items={stats} width={width} maxLines={statMaxLines} />
|
|
168
170
|
<DataTableView<MacroDayEvent> focused={focused} columns={columns} items={rows} rootWidth={width} rootHeight={contentHeight}
|
|
169
171
|
getItemKey={key} emptyStateTitle={surprise === "all" ? "No release days." : `No ${MACRO_SURPRISE_LABELS[surprise].toLowerCase()} prints.`} sortColumnId={null} sortDirection="desc" selectedTextOverridesCellColor
|
|
170
172
|
selection={{ kind: "id", selectedId: selectedRow, getId: key, onChange: (id) => setSelectedRow(id) }}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { GloomPlugin } from "../../../types/plugin";
|
|
2
2
|
import { MARKET_HALTS_PANE_ID } from "./model";
|
|
3
|
-
import { MarketHaltsPane } from "./pane";
|
|
4
3
|
|
|
5
4
|
export const marketHaltsPlugin: GloomPlugin = {
|
|
6
5
|
id: "market-halts",
|
|
@@ -20,7 +19,7 @@ export const marketHaltsPlugin: GloomPlugin = {
|
|
|
20
19
|
reportFreshness: { source: "Nasdaq Trader" },
|
|
21
20
|
name: "Market Halts",
|
|
22
21
|
icon: "H",
|
|
23
|
-
component: MarketHaltsPane,
|
|
22
|
+
get component(): typeof import("./pane").MarketHaltsPane { const { MarketHaltsPane } = require("./pane"); return MarketHaltsPane; },
|
|
24
23
|
defaultPosition: "right",
|
|
25
24
|
defaultMode: "floating",
|
|
26
25
|
defaultFloatingSize: { width: 124, height: 26 },
|
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
type HeatmapSizeBy,
|
|
71
71
|
} from "./portfolio";
|
|
72
72
|
import { useAutoRefresh, useUpdatedAgo } from "../../../react/auto-refresh";
|
|
73
|
+
import { useQuoteDelayFooter } from "../shared/cloud-upgrade";
|
|
73
74
|
import {
|
|
74
75
|
LIVE_STREAMING_QUICK_SETTING,
|
|
75
76
|
useLiveStreamingSetting,
|
|
@@ -635,6 +636,13 @@ function MarketHeatmapPane({ focused, width, height }: PaneProps) {
|
|
|
635
636
|
useAutoRefresh(board?.checkedAt ?? null, autoRefresh, { intervalMs: heatmapCheckIntervalMs(board) });
|
|
636
637
|
|
|
637
638
|
usePaneStatusFooter({ registrationId: "market-heatmap-retained", stale: hasBoard && stale && !portfolioTab });
|
|
639
|
+
// Signed out or free, a market board is the delayed one, and the holdings' quotes are delayed ones.
|
|
640
|
+
const quoteDelay = useQuoteDelayFooter(
|
|
641
|
+
portfolioTab
|
|
642
|
+
? Array.from(financials.values(), (entry) => entry?.quote)
|
|
643
|
+
: shownBoard ? [{ dataSource: shownBoard.access === "realtime" ? "live" as const : "delayed" as const }] : [],
|
|
644
|
+
"heatmap-delay",
|
|
645
|
+
);
|
|
638
646
|
usePaneNoticeFooter({
|
|
639
647
|
registrationId: "market-heatmap-omitted",
|
|
640
648
|
notices: portfolioTab && portfolioBoard.omitted > 0
|
|
@@ -677,7 +685,7 @@ function MarketHeatmapPane({ focused, width, height }: PaneProps) {
|
|
|
677
685
|
// The caption takes the room the rest leaves, with "loading" counted in
|
|
678
686
|
// always, so a refresh never squeezes the row; a narrow pane drops its
|
|
679
687
|
// least important parts rather than truncating every segment.
|
|
680
|
-
const others = [...selected, ...failed, ...feed];
|
|
688
|
+
const others = [...selected, ...failed, ...feed, ...(quoteDelay ? [quoteDelay] : [])];
|
|
681
689
|
const room = width - others.reduce((total, segment) => total + footerSegmentWidth(segment) + 1, 0) - LOADING_FOOTER_WIDTH - 1;
|
|
682
690
|
const caption = shownBoard ? heatmapBoardCaption(shownBoard, { now: Date.now(), checked, failed: failed.length > 0, maxWidth: room }) : null;
|
|
683
691
|
return {
|
|
@@ -687,9 +695,10 @@ function MarketHeatmapPane({ focused, width, height }: PaneProps) {
|
|
|
687
695
|
...(caption ? [{ id: "board", parts: [{ text: caption, tone: "muted" as const }] }] : []),
|
|
688
696
|
...feed,
|
|
689
697
|
...loadingSegment,
|
|
698
|
+
...(quoteDelay ? [quoteDelay] : []),
|
|
690
699
|
],
|
|
691
700
|
};
|
|
692
|
-
}, [checked, feedStatus, hasBoard, loadError, loading, portfolioTab, selectedAsset, shownBoard, width]);
|
|
701
|
+
}, [checked, feedStatus, hasBoard, loadError, loading, portfolioTab, quoteDelay, selectedAsset, shownBoard, width]);
|
|
693
702
|
|
|
694
703
|
return (
|
|
695
704
|
<Box flexDirection="column" width={width} height={height}>
|
|
@@ -14,6 +14,7 @@ import { useAssetData, usePluginPaneState, usePluginTickerActions } from "../../
|
|
|
14
14
|
import { useLiveQuoteEntries } from "../../../state/hooks/quote-streaming";
|
|
15
15
|
import { useAutoRefresh } from "../../../react/auto-refresh";
|
|
16
16
|
import { useQuoteBoard } from "../shared/use-quote-board";
|
|
17
|
+
import { useQuoteDelayFooter } from "../shared/cloud-upgrade";
|
|
17
18
|
import {
|
|
18
19
|
attachMarketMoversPersistence,
|
|
19
20
|
MARKET_SUMMARY_SYMBOLS,
|
|
@@ -62,6 +63,8 @@ import {
|
|
|
62
63
|
const NO_SAVED_SELECTION: string[] = [];
|
|
63
64
|
const SESSION_CHECK_MS = 30_000;
|
|
64
65
|
const NO_QUOTES: MoverQuote[] = [];
|
|
66
|
+
/** A list without Pro is the one built a delay before: the delayed clock reads it as one late price. */
|
|
67
|
+
const DELAYED_LIST = [{ dataSource: "delayed" as const }];
|
|
65
68
|
const moverKey = (row: Pick<ScreenerQuote, "symbol" | "exchange">) => publicTickerKey(row.symbol, row.exchange);
|
|
66
69
|
|
|
67
70
|
/** What is trading in New York, re-read every half minute so the pane follows 04:00, 09:30 and 16:00. */
|
|
@@ -285,6 +288,8 @@ function ScreenerMoversBody({ activeTab, focused, width, summaryQuotes, liveStre
|
|
|
285
288
|
handleRefreshKey(event, () => loadTab(activeTab, { forceRefresh: true }), { stopPropagation: true })
|
|
286
289
|
), [activeTab, loadTab]);
|
|
287
290
|
|
|
291
|
+
// Without Pro the lists are the delayed ones (with Pro the real-time ones), and say so.
|
|
292
|
+
const quoteDelay = useQuoteDelayFooter(rows.length > 0 ? DELAYED_LIST : [], "movers-delay");
|
|
288
293
|
usePaneFooter("market-movers", () => ({
|
|
289
294
|
info: [
|
|
290
295
|
...(loadError ? [{ id: "load-error", parts: [{ text: loadError, tone: "warning" as const }] }] : []),
|
|
@@ -299,8 +304,9 @@ function ScreenerMoversBody({ activeTab, focused, width, summaryQuotes, liveStre
|
|
|
299
304
|
...(moversStale && moversSavedAt == null && loadedKey === listKey ? [STALE_SEGMENT] : []),
|
|
300
305
|
// The FLOAT column shows while a minimum is set; a float the source does not date says so once.
|
|
301
306
|
...partialFloatFooter(columns.some((column) => column.id === "floatShares"), rows),
|
|
307
|
+
...(quoteDelay ? [quoteDelay] : []),
|
|
302
308
|
],
|
|
303
|
-
}), [columns, feedStatus, listKey, loadedKey, loadError, loading, moversStale, moversSavedAt, rows, summaryQuotes]);
|
|
309
|
+
}), [columns, feedStatus, listKey, loadedKey, loadError, loading, moversStale, moversSavedAt, quoteDelay, rows, summaryQuotes]);
|
|
304
310
|
|
|
305
311
|
return (
|
|
306
312
|
<DataTableView<MarketMoverRow, MarketMoverColumn>
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
CloudSessionMoversSide,
|
|
6
6
|
} from "../../../api-client/market-movers";
|
|
7
7
|
import { usePlanAccess } from "../../../api-client/plan-access";
|
|
8
|
+
import { useQuoteDelayFooter } from "../shared/cloud-upgrade";
|
|
8
9
|
import { DataTableView, EmptyState, QueryBar, usePaneFooter, type DataTableKeyEvent } from "../../../components";
|
|
9
10
|
import { STALE_SEGMENT } from "../../../components/layout/pane/status-footer";
|
|
10
11
|
import { handleRefreshKey } from "../../../components/data-table/table-pane";
|
|
@@ -191,6 +192,7 @@ function SessionMoversTable({ view, session, focused, width, summaryQuotes, live
|
|
|
191
192
|
const sessionLabel = payload ? earlierSessionLabel(payload.session, session) : null;
|
|
192
193
|
// While its session trades, a free list says when it was built; a finished one is final and its date says enough.
|
|
193
194
|
const asOfLabel = payload && delayed && sessionTrading ? listAsOfLabel(payload.asOf, payload.session, session) : null;
|
|
195
|
+
const quoteDelay = useQuoteDelayFooter(payload ? [{ dataSource: delayed ? "delayed" : "live" }] : [], "movers-delay");
|
|
194
196
|
usePaneFooter("market-movers", () => ({
|
|
195
197
|
info: [
|
|
196
198
|
...(loadError ? [{ id: "load-error", parts: [{ text: loadError, tone: "warning" as const }] }] : []),
|
|
@@ -205,8 +207,9 @@ function SessionMoversTable({ view, session, focused, width, summaryQuotes, live
|
|
|
205
207
|
...(payload?.stale ? [STALE_SEGMENT] : []),
|
|
206
208
|
// A float the source does not date says so once, while the FLOAT column shows.
|
|
207
209
|
...partialFloatFooter(columns.some((column) => column.id === "floatShares"), rows),
|
|
210
|
+
...(quoteDelay ? [quoteDelay] : []),
|
|
208
211
|
],
|
|
209
|
-
}), [asOfLabel, columns, feedStatus, loadError, loading, payload?.stale, rows, sessionLabel, summaryQuotes]);
|
|
212
|
+
}), [asOfLabel, columns, feedStatus, loadError, loading, payload?.stale, quoteDelay, rows, sessionLabel, summaryQuotes]);
|
|
210
213
|
|
|
211
214
|
const openRow = useCallback((row: SessionMoverRow) => {
|
|
212
215
|
pinTicker(rowKey(row), { floating: true, paneType: TICKER_RESEARCH_PANE_ID, instrument: null });
|
|
@@ -3,7 +3,6 @@ import { valuationCache } from "./cache";
|
|
|
3
3
|
import { valuationSeriesDefinitions } from "./chart-series";
|
|
4
4
|
import { INDICATORS, resolveIndicatorArg } from "./indicators";
|
|
5
5
|
import { marketValuationHeadless } from "./headless";
|
|
6
|
-
import { MarketValuationPane } from "./pane";
|
|
7
6
|
import { buildValuationSettingsDef, VALUATION_DEFAULTS } from "./settings";
|
|
8
7
|
|
|
9
8
|
|
|
@@ -41,7 +40,7 @@ export const marketValuationModule: PluginModule = {
|
|
|
41
40
|
id: MARKET_VALUATION_PANE_ID,
|
|
42
41
|
name: "Market Valuation",
|
|
43
42
|
icon: "V",
|
|
44
|
-
component: MarketValuationPane,
|
|
43
|
+
get component(): typeof import("./pane").MarketValuationPane { const { MarketValuationPane } = require("./pane"); return MarketValuationPane; },
|
|
45
44
|
defaultPosition: "right",
|
|
46
45
|
defaultMode: "floating",
|
|
47
46
|
defaultFloatingSize: { width: 88, height: 34 },
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { GloomPlugin } from "../../../types/plugin";
|
|
2
2
|
import { fundBreadthCache, fundChangesCache, fundListCache, fundMembersCache } from "./client";
|
|
3
3
|
import { membersHeadless } from "./headless";
|
|
4
|
-
import { MembersPane } from "./pane";
|
|
5
4
|
import { membersTitle, TABS } from "./model";
|
|
6
5
|
export const membersPlugin: GloomPlugin = {
|
|
7
6
|
id: "members", name: "Index and ETF members", version: "1.0.0", description: "ETF holdings, member returns, contributions, breadth and index changes", toggleable: true,
|
|
8
7
|
setup(ctx) { fundBreadthCache.attach(ctx.persistence); fundListCache.attach(ctx.persistence); fundMembersCache.attach(ctx.persistence); fundChangesCache.attach(ctx.persistence); },
|
|
9
8
|
dispose() { fundBreadthCache.reset(); fundListCache.reset(); fundMembersCache.reset(); fundChangesCache.reset(); },
|
|
10
|
-
panes: [{ id: "members", name: "Index and ETF members", icon: "M", component: MembersPane, tickerFollower: true,
|
|
9
|
+
panes: [{ id: "members", name: "Index and ETF members", icon: "M", get component(): typeof import("./pane").MembersPane { const { MembersPane } = require("./pane"); return MembersPane; }, tickerFollower: true,
|
|
11
10
|
defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 132, height: 32 }, tableExport: true,
|
|
12
11
|
settings: { fields: [{ key: "tab", label: "View", type: "select", options: TABS }] } }],
|
|
13
12
|
paneTemplates: [{ id: "members-pane", paneId: "members", label: "Index and ETF members", description: "ETF holdings, member returns, daily contributions, breadth and index changes.",
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { PluginModule } from "../plugin-module";
|
|
2
2
|
import { moneyMarketsCache } from "./client";
|
|
3
3
|
import { moneyMarketsHeadless } from "./headless";
|
|
4
|
-
import { MoneyMarketsPane } from "./pane";
|
|
5
4
|
import { MONEY_MARKET_SERIES } from "./series";
|
|
6
5
|
|
|
7
6
|
export const moneyMarketsModule: PluginModule = {
|
|
8
7
|
series: MONEY_MARKET_SERIES,
|
|
9
|
-
panes: [{ id: "money-markets", name: "Money Markets", icon: "$", component: MoneyMarketsPane,
|
|
8
|
+
panes: [{ id: "money-markets", name: "Money Markets", icon: "$", get component(): typeof import("./pane").MoneyMarketsPane { const { MoneyMarketsPane } = require("./pane"); return MoneyMarketsPane; },
|
|
10
9
|
defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 88, height: 28 },
|
|
11
10
|
tableExport: true, headless: moneyMarketsHeadless,
|
|
12
11
|
settings: { title: "Money Markets", fields: [{ key: "tab", label: "View", type: "select",
|
|
@@ -2,6 +2,7 @@ import { useCallback, useMemo } from "react";
|
|
|
2
2
|
import { Box } from "../../../ui";
|
|
3
3
|
import { useAsyncResource, useAutoRefresh, usePaneSettingValue, usePluginPaneState, useUpdatedAgo } from "../../../public/react";
|
|
4
4
|
import { ChartTableHeader, CompositeChart, CurveSurface, curveGhostColors, EmptyState, formatPercentAxis, MarketBoardStack, PaneStatusBody, useChartTableSelection, usePaneNoticeFooter, usePaneStatusLinkFooter, usePaneTabs, type ChartTableChart, type MarketBoardRow, type StatItem } from "../../../components";
|
|
5
|
+
import { ageFooterSegment } from "../../../components/layout/pane/footer";
|
|
5
6
|
import { curveStrip, curveSurfaceMinRows } from "../../../components/chart/curve";
|
|
6
7
|
import { colors } from "../../../theme/colors";
|
|
7
8
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
@@ -125,7 +126,7 @@ export function MoneyMarketsPane({ width, height, focused }: PaneProps) {
|
|
|
125
126
|
notices: [...(data ? moneyMarketNotices(data) : []), ...(resource.data?.refreshError ? [resource.data.refreshError] : [])] });
|
|
126
127
|
usePaneStatusLinkFooter({ registrationId: "money-markets", focused, loading: resource.loading, error: resource.error,
|
|
127
128
|
url: selected?.observation.sourceUrl ?? null, showOpenHint: true,
|
|
128
|
-
info: data && updatedAgo ? [
|
|
129
|
+
info: data && updatedAgo ? [ageFooterSegment(updatedAgo)] : [],
|
|
129
130
|
stale: !!data && resource.data?.stale,
|
|
130
131
|
});
|
|
131
132
|
return <Box width={width} height={height} flexDirection="column">
|
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
15
15
|
import { companyDataNotes, readCompanyFrom } from "../../../types/company-from";
|
|
16
16
|
import { formatUtcSeconds } from "../../../utils/utc-time";
|
|
17
|
+
import { newsSummaryLine } from "../../../news/news-model";
|
|
18
|
+
import { shortStoryId } from "../../../news/story-id";
|
|
17
19
|
import { cloudNewsFreshness, cloudRealtimeAccess } from "../shared/report-freshness";
|
|
18
20
|
import { REPORT_FILTER, REPORT_ROWS } from "../shared/headless-options";
|
|
19
21
|
|
|
@@ -25,6 +27,11 @@ const NEWS_COLUMNS = [
|
|
|
25
27
|
{ key: "tickers", header: "Tickers", textFormat: (value: unknown) => Array.isArray(value) ? value.join(", ") : String(value ?? "") },
|
|
26
28
|
{ key: "sentiment", header: "Sentiment" },
|
|
27
29
|
{ key: "importance", header: "Score", align: "right" as const },
|
|
30
|
+
// The short id `fn news-story-pane` opens the story by, and its summary on one line under the row; exports keep both whole.
|
|
31
|
+
{ key: "id", header: "ID", textFormat: (value: unknown) => typeof value === "string" ? shortStoryId(value) : "" },
|
|
32
|
+
{ key: "summary", header: "Summary", underRow: "line" as const,
|
|
33
|
+
textFormat: (value: unknown, row: Record<string, unknown>) =>
|
|
34
|
+
newsSummaryLine({ title: String(row.headline ?? ""), summary: typeof value === "string" ? value : undefined }) ?? "" },
|
|
28
35
|
];
|
|
29
36
|
|
|
30
37
|
export interface NewsHeadlessDependencies {
|
|
@@ -92,7 +92,7 @@ const newsWirePanes: PluginModule["panes"] = [
|
|
|
92
92
|
{
|
|
93
93
|
id: NEWS_STORY_PANE_ID,
|
|
94
94
|
reportFreshness: NEWS_REPORT_FRESHNESS,
|
|
95
|
-
reportArgument: { kind: "free-text", placeholder: "story id", description: "The id of the story to open." },
|
|
95
|
+
reportArgument: { kind: "free-text", placeholder: "story id", description: "The id of the story to open.", identifier: true },
|
|
96
96
|
name: "Story",
|
|
97
97
|
icon: "A",
|
|
98
98
|
component: NewsStoryPane,
|
|
@@ -7,6 +7,7 @@ import { usePaneInstance } from "../../../../../state/app/context";
|
|
|
7
7
|
import type { PaneProps, PaneTemplateCreateOptions, PaneTemplateDef } from "../../../../../types/plugin";
|
|
8
8
|
import { usePluginAppActions } from "../../../../runtime";
|
|
9
9
|
import { usePersistedNewsArticles } from "../persisted-articles";
|
|
10
|
+
import { storyIdMatches } from "../../../../../news/story-id";
|
|
10
11
|
import { NewsDetailView } from "./detail-view";
|
|
11
12
|
import { useNewsArticleFooter } from "./footer";
|
|
12
13
|
|
|
@@ -33,7 +34,11 @@ function handOffNewsStory(article: NewsArticle): void {
|
|
|
33
34
|
|
|
34
35
|
function handedOffStory(articleId: string): NewsArticle | null {
|
|
35
36
|
if (!articleId) return null;
|
|
36
|
-
|
|
37
|
+
const exact = handedOffStories.get(articleId);
|
|
38
|
+
if (exact) return exact;
|
|
39
|
+
// A pane opened by a short id (`fn news-story-pane 6067684e`) takes the story whose id starts with it.
|
|
40
|
+
for (const [id, article] of handedOffStories) if (storyIdMatches(id, articleId)) return article;
|
|
41
|
+
return null;
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
export const openNewsStoryPane = (
|
|
@@ -82,9 +87,10 @@ export function NewsStoryPane({ focused, width }: PaneProps) {
|
|
|
82
87
|
const [loaded, setLoaded] = useState<NewsArticle | null>(() => handedOffStory(articleId));
|
|
83
88
|
// The pane keeps a copy of its story, so a relaunch or a shared layout shows
|
|
84
89
|
// it at once, including a story from an RSS feed that cannot be fetched by id.
|
|
85
|
-
|
|
90
|
+
// A story opened by its short id (`fn news-story-pane 6067684e`) is the one whose id starts with it.
|
|
91
|
+
const story = useMemo(() => (loaded && storyIdMatches(loaded.id, articleId) ? [loaded] : NO_STORY), [articleId, loaded]);
|
|
86
92
|
const kept = usePersistedNewsArticles("story", story);
|
|
87
|
-
const article = kept.find((entry) => entry.id
|
|
93
|
+
const article = kept.find((entry) => storyIdMatches(entry.id, articleId)) ?? null;
|
|
88
94
|
const [loading, setLoading] = useState(false);
|
|
89
95
|
const [error, setError] = useState<string | null>(null);
|
|
90
96
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { notesPluginMeta } from "../builtin-plugin-meta";
|
|
1
2
|
import { apiClient } from "../../../api-client";
|
|
2
3
|
import type { GloomPlugin } from "../../../types/plugin";
|
|
3
4
|
import { teamStore } from "../../../team/store";
|
|
@@ -12,11 +13,7 @@ import { createNotesTab } from "./ticker-notes-tab";
|
|
|
12
13
|
let disposeNotes: (() => void) | null = null;
|
|
13
14
|
|
|
14
15
|
export const notesPlugin: GloomPlugin = {
|
|
15
|
-
|
|
16
|
-
name: "Notes",
|
|
17
|
-
version: "2.0.0",
|
|
18
|
-
description: "Markdown notes on tickers and on their own, personal or shared with a team.",
|
|
19
|
-
toggleable: true,
|
|
16
|
+
...notesPluginMeta,
|
|
20
17
|
cliCommands: [notesCliCommand],
|
|
21
18
|
|
|
22
19
|
setup(ctx) {
|
|
@@ -79,7 +76,7 @@ export const notesPlugin: GloomPlugin = {
|
|
|
79
76
|
|
|
80
77
|
ctx.registerPane({
|
|
81
78
|
id: "quick-notes",
|
|
82
|
-
reportFreshness: { source: "Your notes", status: "not-a-feed", basis: "your notes" },
|
|
79
|
+
reportFreshness: { source: "Your notes", status: "not-a-feed", basis: "your notes", local: true },
|
|
83
80
|
name: "Notes",
|
|
84
81
|
personalData: "messages",
|
|
85
82
|
icon: "N",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { GloomPlugin, PaneTemplateCreateOptions } from "../../../types/plugin";
|
|
2
|
-
import { OpenFdaPane } from "./pane";
|
|
3
2
|
import { OPENFDA_PANE_ID, OPENFDA_PLUGIN_ID } from "./types";
|
|
4
3
|
|
|
5
4
|
const createOpenFdaPaneInstance = (options?: PaneTemplateCreateOptions) => {
|
|
@@ -35,7 +34,7 @@ export const openFdaPlugin: GloomPlugin = {
|
|
|
35
34
|
reportFreshness: { source: "US FDA", status: "not-a-feed", basis: "published reports" },
|
|
36
35
|
name: "FDA Reports",
|
|
37
36
|
icon: "F",
|
|
38
|
-
component: OpenFdaPane,
|
|
37
|
+
get component(): typeof import("./pane").OpenFdaPane { const { OpenFdaPane } = require("./pane"); return OpenFdaPane; },
|
|
39
38
|
defaultPosition: "right",
|
|
40
39
|
defaultMode: "floating",
|
|
41
40
|
defaultFloatingSize: { width: 100, height: 30 },
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
type QueryBarFilter,
|
|
33
33
|
type DataTableVisibleRange,
|
|
34
34
|
} from "../../../components";
|
|
35
|
+
import { statGridWithin } from "../../../components/ui/stat-grid";
|
|
35
36
|
import { useShortcut } from "../../../react/input";
|
|
36
37
|
import { useOptionalDialog, type AlertContext } from "../../../ui/dialog";
|
|
37
38
|
import { useLiveQuoteEntries, useQuoteUpdates } from "../../../state/hooks/quote-streaming";
|
|
@@ -980,10 +981,10 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
980
981
|
const expiryInline = Math.floor((statWidth - 2 * (cellColumns - 1)) / cellColumns) >= expiryCells;
|
|
981
982
|
const statColumns = expiryInline ? cellColumns : figureColumns;
|
|
982
983
|
const statItems = [expiryInline ? expiryItem : { ...expiryItem, wide: true }, ...figures];
|
|
983
|
-
|
|
984
|
-
//
|
|
985
|
-
const
|
|
986
|
-
|
|
984
|
+
// A short band gives up figures from the end, by lines: a row that wraps
|
|
985
|
+
// takes two. The expiry leads, so it stays.
|
|
986
|
+
const summaryLines = Math.min(statGridRows(statItems, statWidth, statColumns), Math.max(0, height - 6));
|
|
987
|
+
const { items: shownStatItems, lines: summaryRowCount } = statGridWithin(statItems, statWidth, summaryLines, statColumns);
|
|
987
988
|
// No term here follows the selection or the load, so an empty cold-expiry
|
|
988
989
|
// response cannot resize the table: growing it during loading would turn a
|
|
989
990
|
// clamped scroll into apparent user navigation.
|
|
@@ -997,7 +998,7 @@ export function OptionsView({ width, height, focused, nestedInTabs = false, ivRa
|
|
|
997
998
|
<QueryBar width={Math.max(1, width - 2)} filters={queryFilters} />
|
|
998
999
|
|
|
999
1000
|
{summaryRowCount > 0 && (
|
|
1000
|
-
<StatGrid items={shownStatItems} width={statWidth} columns={statColumns} />
|
|
1001
|
+
<StatGrid items={shownStatItems} width={statWidth} columns={statColumns} maxLines={summaryLines} />
|
|
1001
1002
|
)}
|
|
1002
1003
|
|
|
1003
1004
|
{isOpt && parsed && (
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
OPTIONS_CALCULATOR_PANE_ID,
|
|
4
4
|
OPTIONS_CALCULATOR_TEMPLATE_ID,
|
|
5
5
|
} from "./model";
|
|
6
|
-
import { OptionsCalculatorPane } from "./pane";
|
|
7
6
|
import { optionsCalculatorHeadless } from "./headless";
|
|
8
7
|
|
|
9
8
|
export const optionsCalculatorModule: PluginModule = {
|
|
@@ -12,7 +11,7 @@ export const optionsCalculatorModule: PluginModule = {
|
|
|
12
11
|
id: OPTIONS_CALCULATOR_PANE_ID,
|
|
13
12
|
name: "Options Calculator",
|
|
14
13
|
icon: "V",
|
|
15
|
-
component: OptionsCalculatorPane,
|
|
14
|
+
get component(): typeof import("./pane").OptionsCalculatorPane { const { OptionsCalculatorPane } = require("./pane"); return OptionsCalculatorPane; },
|
|
16
15
|
defaultPosition: "right",
|
|
17
16
|
defaultMode: "floating",
|
|
18
17
|
defaultFloatingSize: { width: 96, height: 28 },
|
|
@@ -3,7 +3,6 @@ import type { PluginModule } from "../plugin-module";
|
|
|
3
3
|
import { createTickerSurfacePaneTemplate, type TickerSurfacePaneTemplateOptions } from "../shared/ticker-surface";
|
|
4
4
|
import { optionsPositioningHeadless } from "./headless";
|
|
5
5
|
import { isPositioningTab, type PositioningTab } from "./model";
|
|
6
|
-
import { OptionsPositioningPane } from "./pane";
|
|
7
6
|
|
|
8
7
|
/** The underlying OPX opens on when no ticker is active. */
|
|
9
8
|
const DEFAULT_UNDERLYING = "SPY";
|
|
@@ -45,7 +44,7 @@ export const optionsPositioningModule: PluginModule = {
|
|
|
45
44
|
id: "options-positioning",
|
|
46
45
|
name: "Options Positioning",
|
|
47
46
|
icon: "O",
|
|
48
|
-
component: OptionsPositioningPane,
|
|
47
|
+
get component(): typeof import("./pane").OptionsPositioningPane { const { OptionsPositioningPane } = require("./pane"); return OptionsPositioningPane; },
|
|
49
48
|
defaultPosition: "right",
|
|
50
49
|
tickerFollower: true,
|
|
51
50
|
defaultMode: "floating",
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { PluginModule } from "../plugin-module";
|
|
2
2
|
import { createTickerSurfacePaneTemplate } from "../shared/ticker-surface";
|
|
3
|
-
import { OptionsScenarioPane } from "./pane";
|
|
4
3
|
import { optionsScenarioHeadless } from "./headless";
|
|
5
|
-
import { CspScreenPane } from "./csp-screen-pane";
|
|
6
4
|
import { cspScreenHeadless } from "./csp-screen-headless";
|
|
7
5
|
|
|
8
6
|
const scenarioSettingKeys = ["legs", "strategy", "strike", "delta", "putStrike", "callStrike", "shares", "expiration", "spot", "rate", "dividendYield", "currency", "asOf", "date", "volShift",
|
|
@@ -10,7 +8,7 @@ const scenarioSettingKeys = ["legs", "strategy", "strike", "delta", "putStrike",
|
|
|
10
8
|
|
|
11
9
|
export const optionsScenarioModule: PluginModule = {
|
|
12
10
|
panes: [{
|
|
13
|
-
id: "options-scenario", name: "Options Scenario", icon: "V", component: OptionsScenarioPane,
|
|
11
|
+
id: "options-scenario", name: "Options Scenario", icon: "V", get component(): typeof import("./pane").OptionsScenarioPane { const { OptionsScenarioPane } = require("./pane"); return OptionsScenarioPane; },
|
|
14
12
|
defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 126, height: 36 },
|
|
15
13
|
tableExport: true, headless: optionsScenarioHeadless,
|
|
16
14
|
settings: {
|
|
@@ -26,7 +24,7 @@ export const optionsScenarioModule: PluginModule = {
|
|
|
26
24
|
],
|
|
27
25
|
},
|
|
28
26
|
}, {
|
|
29
|
-
id: "csp-screen", name: "Options Strategy Screen", icon: "V", component: CspScreenPane,
|
|
27
|
+
id: "csp-screen", name: "Options Strategy Screen", icon: "V", get component(): typeof import("./csp-screen-pane").CspScreenPane { const { CspScreenPane } = require("./csp-screen-pane"); return CspScreenPane; },
|
|
30
28
|
defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 144, height: 24 },
|
|
31
29
|
tableExport: true, headless: cspScreenHeadless,
|
|
32
30
|
settings: {
|
|
@@ -4,7 +4,6 @@ import { commandRequestParams } from "../shared/command-tab";
|
|
|
4
4
|
import { PERP_SERIES } from "./series";
|
|
5
5
|
import { perpsCache, perpsDepthCache, perpsHistoryCache, perpsLiquidationsCache, perpsListCache, perpsMarketCache, perpsRankingsCache } from "./client";
|
|
6
6
|
import { perpsHeadless } from "./headless";
|
|
7
|
-
import { PerpsPane } from "./pane";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* A named market has its own pane, and asking for it again (PERP, a stock's perpetual row in DES or QQ) brings that
|
|
@@ -22,7 +21,7 @@ const PERP_CACHES = [perpsCache, perpsHistoryCache, perpsListCache, perpsMarketC
|
|
|
22
21
|
|
|
23
22
|
export const perpsModule: PluginModule = {
|
|
24
23
|
series: PERP_SERIES,
|
|
25
|
-
panes: [{ id: "perps", name: "Perpetuals", icon: "P", component: PerpsPane, defaultPosition: "right", defaultMode: "floating",
|
|
24
|
+
panes: [{ id: "perps", name: "Perpetuals", icon: "P", get component(): typeof import("./pane").PerpsPane { const { PerpsPane } = require("./pane"); return PerpsPane; }, defaultPosition: "right", defaultMode: "floating",
|
|
26
25
|
defaultFloatingSize: { width: 138, height: 34 }, tableExport: true, headless: perpsHeadless }],
|
|
27
26
|
paneTemplates: [{ id: "perps-pane", paneId: "perps", label: "Perpetuals", description: "Perpetual funding, open interest and premiums by market and venue, with rankings, a venue comparison, liquidations, order book depth and Pro history.",
|
|
28
27
|
keywords: ["perp", "perpetual", "perpetuals", "funding", "funding rate", "open interest", "hip-3", "stock perps", "basis", "basis trade", "carry", "venue", "funding spread", "long short ratio", "long/short", "positioning", "liquidations", "liquidation", "order book depth", "market depth", "liquidity"],
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { PLUGIN_AUTO_UPDATE_SETTING } from "../../auto-update";
|
|
2
2
|
import type { PluginModule } from "../plugin-module";
|
|
3
3
|
import { PLUGIN_MARKETPLACE_PANE_ID } from "../../marketplace/ids";
|
|
4
|
-
import { PluginMarketplacePane } from "./pane";
|
|
5
4
|
|
|
6
5
|
export const pluginMarketplaceModule: PluginModule = {
|
|
7
6
|
panes: [
|
|
@@ -9,8 +8,8 @@ export const pluginMarketplaceModule: PluginModule = {
|
|
|
9
8
|
id: PLUGIN_MARKETPLACE_PANE_ID,
|
|
10
9
|
name: "Plugins",
|
|
11
10
|
icon: "P",
|
|
12
|
-
component: PluginMarketplacePane,
|
|
13
|
-
reportFreshness: { status: "not-a-feed", basis: "plugin listings" },
|
|
11
|
+
get component(): typeof import("./pane").PluginMarketplacePane { const { PluginMarketplacePane } = require("./pane"); return PluginMarketplacePane; },
|
|
12
|
+
reportFreshness: { status: "not-a-feed", basis: "plugin listings", local: true },
|
|
14
13
|
defaultPosition: "right",
|
|
15
14
|
defaultMode: "floating",
|
|
16
15
|
defaultFloatingSize: { width: 118, height: 34 },
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
type DataTableKeyEvent,
|
|
22
22
|
type PaneHint,
|
|
23
23
|
} from "../../../components";
|
|
24
|
+
import { ageFooterSegment } from "../../../components/layout/pane/footer";
|
|
24
25
|
import { loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
|
|
25
26
|
import { useRowNotes } from "../../../components/ui/row-notes";
|
|
26
27
|
import { colors } from "../../../theme/colors";
|
|
@@ -922,7 +923,7 @@ export function PluginMarketplacePane({ focused, width, height }: PaneProps) {
|
|
|
922
923
|
info.push({ id: "restart", parts: [{ text: "restart to finish loading", tone: "warning" }] });
|
|
923
924
|
}
|
|
924
925
|
if (status === "ready" && fetchedAt && !stale && !busy) {
|
|
925
|
-
info.push(
|
|
926
|
+
info.push(ageFooterSegment(formatRelativeAge(fetchedAt)));
|
|
926
927
|
}
|
|
927
928
|
|
|
928
929
|
const hints: PaneHint[] = [];
|