gloomberb 0.16.0 → 0.16.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/README.md +2 -1
- package/package.json +2 -1
- package/src/api-client/beneficial-owners.ts +92 -0
- package/src/api-client/data.ts +44 -11
- package/src/api-client/errors.ts +12 -0
- package/src/api-client/geo.ts +363 -0
- package/src/api-client/index.ts +5 -0
- package/src/api-client/market-discovery.ts +10 -0
- package/src/api-client/members.ts +26 -0
- package/src/api-client/paths.ts +30 -1
- package/src/api-client/perps.ts +41 -0
- package/src/api-client/request.ts +5 -2
- package/src/api-client/types.ts +9 -1
- package/src/app/global-shortcuts.ts +14 -6
- package/src/app/keybindings/actions.ts +1 -1
- package/src/app/runtime/update.ts +38 -2
- package/src/app.tsx +10 -6
- package/src/brokers/account-cache.ts +24 -0
- package/src/cli/commands/command-utils.ts +8 -0
- package/src/cli/commands/crypto-hints.ts +75 -0
- package/src/cli/commands/market.ts +414 -106
- package/src/cli/commands/overview.ts +77 -32
- package/src/cli/commands/ticker.ts +101 -43
- package/src/cli/desktop-pane-shot.ts +34 -4
- package/src/cli/freshness.ts +61 -0
- package/src/cli/help.ts +1 -0
- package/src/cli/helpers.ts +4 -8
- package/src/cli/index.ts +12 -2
- package/src/cli/listing-arg.ts +321 -0
- package/src/cli/pane-functions/access-gate.ts +42 -0
- package/src/cli/pane-functions/catalog.ts +28 -1
- package/src/cli/pane-functions/data.ts +3 -1
- package/src/cli/pane-functions/dom.ts +20 -2
- package/src/cli/pane-functions/freshness.ts +400 -0
- package/src/cli/pane-functions/function-help.ts +36 -22
- package/src/cli/pane-functions/headless.ts +39 -11
- package/src/cli/pane-functions/index.ts +15 -4
- package/src/cli/pane-functions/options.ts +3 -0
- package/src/cli/pane-functions/report.ts +4 -0
- package/src/cli/pane-functions/resolver.ts +35 -7
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +7 -3
- package/src/cli/result.ts +41 -27
- package/src/cli/ticker-resolution.ts +7 -5
- package/src/components/chart/composite/composite-chart.tsx +88 -2536
- package/src/components/chart/composite/drawing-store.ts +59 -0
- package/src/components/chart/composite/legend.tsx +319 -0
- package/src/components/chart/composite/panel-bitmap.ts +139 -0
- package/src/components/chart/composite/panel-gestures.ts +59 -0
- package/src/components/chart/composite/panel-labels.ts +107 -0
- package/src/components/chart/composite/panel-surface.tsx +876 -0
- package/src/components/chart/composite/tool-catalog.ts +98 -0
- package/src/components/chart/composite/toolbar.tsx +186 -0
- package/src/components/chart/composite/tools.ts +8 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
- package/src/components/chart/composite/use-composite-viewport.ts +143 -0
- package/src/components/command-bar/commands/collection.ts +5 -1
- package/src/components/command-bar/list/model.ts +5 -0
- package/src/components/command-bar/list/view.tsx +16 -3
- package/src/components/command-bar/pane-templates/workflow.ts +1 -0
- package/src/components/command-bar/routes/root/command-items.ts +9 -2
- package/src/components/command-bar/routes/root/plugin-install.ts +2 -2
- package/src/components/command-bar/routes/root/provider-search.ts +19 -5
- package/src/components/command-bar/routes/root/runtime.ts +14 -5
- package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
- package/src/components/command-bar/routes/ticker-search/results.ts +31 -5
- package/src/components/command-bar/routes/ticker-search/route.ts +2 -2
- package/src/components/command-bar/routing/actions.ts +2 -0
- package/src/components/command-bar/selection-runtime.ts +38 -0
- package/src/components/command-bar/surface/index.tsx +7 -2
- package/src/components/command-bar/workflow/ops.ts +1 -1
- package/src/components/command-bar/workflow/tickers.ts +6 -0
- package/src/components/data-table/view.tsx +29 -10
- package/src/components/feedback-dialog.tsx +2 -1
- package/src/components/form-modal/field-row.tsx +2 -2
- package/src/components/index.ts +2 -2
- package/src/components/layout/detached-pane-shell.tsx +6 -3
- package/src/components/layout/floating-pane.tsx +6 -0
- package/src/components/layout/header.tsx +24 -7
- package/src/components/layout/missing-pane.tsx +2 -2
- package/src/components/layout/pane/content.tsx +23 -10
- package/src/components/layout/pane/error-boundary.tsx +103 -0
- package/src/components/layout/pane/footer/registration.tsx +68 -23
- package/src/components/layout/pane/header.tsx +61 -28
- package/src/components/layout/pane/index.tsx +6 -0
- package/src/components/layout/pane/title.ts +31 -7
- package/src/components/layout/shell/drag/index.ts +6 -5
- package/src/components/layout/shell/drag/runtime.ts +3 -0
- package/src/components/layout/shell/index.tsx +6 -0
- package/src/components/layout/shell/menu.ts +2 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +29 -10
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -3
- package/src/components/layout/shell/ticker-link-menu.ts +23 -9
- package/src/components/metric-treemap/heat-surface.tsx +745 -0
- package/src/components/metric-treemap/heat-tiles.ts +228 -0
- package/src/components/metric-treemap/index.tsx +2 -0
- package/src/components/metric-treemap/layout.ts +8 -0
- package/src/components/metric-treemap/scene.ts +432 -0
- package/src/components/onboarding/onboarding-keyboard.ts +311 -0
- package/src/components/onboarding/onboarding-wizard.tsx +101 -788
- package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
- package/src/components/onboarding/use-onboarding-progress.ts +298 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
- package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -0
- package/src/components/ticker/list-table-view.tsx +13 -1
- package/src/components/toggle-list.tsx +38 -12
- package/src/components/ui/country-flag-art.tsx +449 -0
- package/src/components/ui/country-flag.tsx +41 -0
- package/src/components/ui/data-table/types.ts +13 -0
- package/src/components/ui/fields.tsx +8 -0
- package/src/components/ui/icon.tsx +2 -0
- package/src/components/ui/index.ts +4 -0
- package/src/components/ui/multi-select/dialog.tsx +108 -22
- package/src/components/ui/range-track.tsx +53 -0
- package/src/components/ui/status.tsx +8 -2
- package/src/components/ui/tabs.tsx +11 -4
- package/src/components/ui/text-prompt-dialog.tsx +4 -2
- package/src/core/state/app/types.ts +10 -1
- package/src/data/config/store/normalize.ts +17 -1
- package/src/i18n/es.ts +24 -4
- package/src/i18n/ja.ts +24 -4
- package/src/i18n/ko.ts +24 -4
- package/src/i18n/zh-cn.ts +24 -4
- package/src/i18n/zh-tw.ts +24 -4
- package/src/layout/ticker-navigation.ts +28 -2
- package/src/market-data/coordinator/chart.ts +1 -1
- package/src/market-data/coordinator/quotes.ts +23 -4
- package/src/market-data/fx-closes.ts +72 -0
- package/src/market-data/market/freshness.ts +78 -6
- package/src/market-data/market/session-close-note.ts +57 -0
- package/src/market-data/market/status.ts +151 -0
- package/src/market-data/published-apac-sessions.ts +66 -0
- package/src/market-data/quotes/contributions.ts +8 -0
- package/src/market-data/quotes/freshness.ts +36 -0
- package/src/market-data/quotes/resolution.ts +24 -8
- package/src/market-data/quotes/screener-live-quotes.ts +49 -4
- package/src/market-data/quotes/time.ts +16 -0
- package/src/plugins/builtin/account-management/pane.tsx +4 -0
- package/src/plugins/builtin/alerts/cli.ts +10 -5
- package/src/plugins/builtin/alerts/index.tsx +1 -0
- package/src/plugins/builtin/analytics/metrics.ts +8 -3
- package/src/plugins/builtin/analytics/risk-client.ts +330 -79
- package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
- package/src/plugins/builtin/analytics/risk-headless.ts +61 -49
- package/src/plugins/builtin/analytics/risk-math.ts +33 -13
- package/src/plugins/builtin/analytics/risk-model.ts +282 -64
- package/src/plugins/builtin/analytics/risk-pane.tsx +62 -30
- package/src/plugins/builtin/analytics/risk-test-data.ts +206 -0
- package/src/plugins/builtin/attention/headless.ts +6 -4
- package/src/plugins/builtin/attention/index.tsx +1 -1
- package/src/plugins/builtin/attention/pane.tsx +1 -1
- package/src/plugins/builtin/awards/headless.ts +1 -0
- package/src/plugins/builtin/awards/pane.tsx +1 -1
- package/src/plugins/builtin/backtest/headless.ts +1 -0
- package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
- package/src/plugins/builtin/buildout/cells.tsx +15 -12
- package/src/plugins/builtin/buildout/detail/company.tsx +3 -3
- package/src/plugins/builtin/buildout/detail/index.tsx +0 -1
- package/src/plugins/builtin/buildout/detail/intel.tsx +6 -6
- package/src/plugins/builtin/buildout/detail/site.tsx +4 -7
- package/src/plugins/builtin/buildout/detail/ui.tsx +0 -19
- package/src/plugins/builtin/buildout/index.tsx +1 -0
- package/src/plugins/builtin/catalysts/headless.ts +3 -1
- package/src/plugins/builtin/catalysts/index.tsx +2 -2
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/headless.ts +2 -0
- package/src/plugins/builtin/cds/index.tsx +1 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
- package/src/plugins/builtin/chart-composer/headless.ts +38 -3
- package/src/plugins/builtin/chart-composer/index.tsx +3 -1
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
- package/src/plugins/builtin/chat/channels.ts +19 -3
- package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
- package/src/plugins/builtin/chat/content/footer.tsx +15 -6
- package/src/plugins/builtin/chat/content/index.tsx +120 -21
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
- package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
- package/src/plugins/builtin/chat/direct-messages.ts +200 -0
- package/src/plugins/builtin/chat/index.tsx +1 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
- package/src/plugins/builtin/chat/message/header.tsx +16 -6
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
- package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
- package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
- package/src/plugins/builtin/chat/message/types.ts +14 -2
- package/src/plugins/builtin/chat/profile-popover.ts +18 -13
- package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
- package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
- package/src/plugins/builtin/cloud/plugin.tsx +1 -0
- package/src/plugins/builtin/cloud/team/module.tsx +1 -0
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/comment-letters/index.tsx +1 -0
- package/src/plugins/builtin/company-attention/headless.ts +5 -1
- package/src/plugins/builtin/company-attention/pane.tsx +1 -1
- package/src/plugins/builtin/company-kpis/headless.ts +1 -0
- package/src/plugins/builtin/congress-trades/headless.ts +1 -0
- package/src/plugins/builtin/correlation/compute.ts +59 -16
- package/src/plugins/builtin/correlation/geo.ts +34 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
- package/src/plugins/builtin/correlation/headless.ts +42 -8
- package/src/plugins/builtin/correlation/history.ts +2 -0
- package/src/plugins/builtin/correlation/index.tsx +68 -14
- package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
- package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
- package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
- package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
- package/src/plugins/builtin/correlation/settings.ts +1 -1
- package/src/plugins/builtin/cot/headless.ts +6 -3
- package/src/plugins/builtin/cot/index.tsx +3 -3
- package/src/plugins/builtin/cot/model.ts +36 -3
- package/src/plugins/builtin/cpi/headless.ts +4 -0
- package/src/plugins/builtin/credit-boards/headless.ts +2 -0
- package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
- package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
- package/src/plugins/builtin/credit-documents/headless.ts +2 -0
- package/src/plugins/builtin/crypto-board/headless.ts +3 -0
- package/src/plugins/builtin/custom-view/loader.ts +1 -1
- package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
- package/src/plugins/builtin/debt-maturities/wall-bar.tsx +14 -41
- package/src/plugins/builtin/dividend-yield/client.ts +4 -2
- package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
- package/src/plugins/builtin/doe/headless.ts +7 -0
- package/src/plugins/builtin/doe/range-bar.tsx +7 -37
- package/src/plugins/builtin/earnings/client.ts +2 -2
- package/src/plugins/builtin/earnings/headless.ts +5 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
- package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
- package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
- package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
- package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
- package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
- package/src/plugins/builtin/econ/index.tsx +1 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
- package/src/plugins/builtin/equity-screener/headless.ts +2 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
- package/src/plugins/builtin/executives/index.tsx +1 -0
- package/src/plugins/builtin/exposure/headless.ts +3 -1
- package/src/plugins/builtin/fear-greed/headless.ts +2 -0
- package/src/plugins/builtin/filing-events/index.tsx +1 -0
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +39 -10
- package/src/plugins/builtin/futures-curve/index.tsx +3 -3
- package/src/plugins/builtin/futures-curve/model.ts +188 -4
- package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
- package/src/plugins/builtin/fx-matrix/direction.ts +81 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +71 -33
- package/src/plugins/builtin/fx-matrix/live-legs.ts +17 -0
- package/src/plugins/builtin/fx-matrix/pairs.ts +68 -14
- package/src/plugins/builtin/fx-matrix/settings.ts +62 -0
- package/src/plugins/builtin/gpu/headless.ts +7 -3
- package/src/plugins/builtin/gpu/ladder.tsx +26 -30
- package/src/plugins/builtin/gpu/model.ts +27 -1
- package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
- package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
- package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
- package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
- package/src/plugins/builtin/holders/headless.ts +139 -5
- package/src/plugins/builtin/holders/index.tsx +10 -3
- package/src/plugins/builtin/holders/pane.tsx +20 -3
- package/src/plugins/builtin/holders/report-header.ts +95 -0
- package/src/plugins/builtin/holders/table-model.ts +20 -5
- package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
- package/src/plugins/builtin/holders/types.ts +2 -1
- package/src/plugins/builtin/insider/headless.ts +2 -0
- package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
- package/src/plugins/builtin/iv-history/headless.ts +4 -1
- package/src/plugins/builtin/jobs/headless.ts +1 -0
- package/src/plugins/builtin/jobs/index.tsx +1 -0
- package/src/plugins/builtin/jobs/share-bars.tsx +5 -28
- package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +2 -0
- package/src/plugins/builtin/market-halts/index.tsx +1 -0
- package/src/plugins/builtin/market-heatmap/data.ts +30 -2
- package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +245 -81
- package/src/plugins/builtin/market-heatmap/live.ts +88 -0
- package/src/plugins/builtin/market-heatmap/model.ts +146 -0
- package/src/plugins/builtin/market-heatmap/portfolio.ts +50 -11
- package/src/plugins/builtin/market-movers/client.ts +3 -2
- package/src/plugins/builtin/market-movers/headless.ts +10 -1
- package/src/plugins/builtin/market-movers/screener.ts +18 -5
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/members/client.ts +53 -0
- package/src/plugins/builtin/members/headless.ts +35 -0
- package/src/plugins/builtin/members/index.tsx +20 -0
- package/src/plugins/builtin/members/model.ts +68 -0
- package/src/plugins/builtin/members/pane.tsx +175 -0
- package/src/plugins/builtin/mna/distress/headless.ts +1 -0
- package/src/plugins/builtin/mna/headless.ts +1 -0
- package/src/plugins/builtin/mna/index.tsx +2 -1
- package/src/plugins/builtin/mna/pane.tsx +5 -2
- package/src/plugins/builtin/money-markets/headless.ts +1 -0
- package/src/plugins/builtin/news/headless.ts +2 -0
- package/src/plugins/builtin/news/wire/index.tsx +8 -1
- package/src/plugins/builtin/notes/cli.ts +14 -6
- package/src/plugins/builtin/notes/index.tsx +1 -0
- package/src/plugins/builtin/openfda/index.tsx +1 -0
- package/src/plugins/builtin/options/index.tsx +2 -1
- package/src/plugins/builtin/options-calculator/headless.ts +2 -0
- package/src/plugins/builtin/options-positioning/headless.ts +3 -0
- package/src/plugins/builtin/options-scenario/headless.ts +5 -0
- package/src/plugins/builtin/pe-band/client.ts +74 -2
- package/src/plugins/builtin/pe-band/headless.ts +26 -8
- package/src/plugins/builtin/pe-band/model.ts +102 -22
- package/src/plugins/builtin/pe-band/pane.tsx +34 -16
- package/src/plugins/builtin/pe-band/report-dates.ts +78 -0
- package/src/plugins/builtin/perps/client.ts +66 -5
- package/src/plugins/builtin/perps/equity-identity.ts +16 -0
- package/src/plugins/builtin/perps/equity-row.tsx +6 -4
- package/src/plugins/builtin/perps/headless.ts +144 -16
- package/src/plugins/builtin/perps/index.tsx +6 -6
- package/src/plugins/builtin/perps/model.ts +189 -12
- package/src/plugins/builtin/perps/pane.tsx +248 -47
- package/src/plugins/builtin/plugin-marketplace/activation.ts +19 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -2
- package/src/plugins/builtin/plugin-marketplace/store.ts +2 -0
- package/src/plugins/builtin/portfolio-list/allocation.ts +245 -0
- package/src/plugins/builtin/portfolio-list/cached-account.ts +33 -0
- package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
- package/src/plugins/builtin/portfolio-list/cli/render.ts +230 -39
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
- package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
- package/src/plugins/builtin/portfolio-list/headless.ts +98 -16
- package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
- package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
- package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +47 -13
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +43 -2
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +48 -5
- package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +24 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
- package/src/plugins/builtin/power/headless.ts +3 -1
- package/src/plugins/builtin/rate-path/headless.ts +2 -0
- package/src/plugins/builtin/realized-vol/headless.ts +2 -0
- package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
- package/src/plugins/builtin/research/analyst-headless.ts +3 -0
- package/src/plugins/builtin/research/events-headless.ts +2 -0
- package/src/plugins/builtin/research/headless.ts +2 -0
- package/src/plugins/builtin/research/index.tsx +1 -0
- package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
- package/src/plugins/builtin/research/relative-valuation-model.ts +11 -3
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
- package/src/plugins/builtin/research-search/index.tsx +1 -0
- package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
- package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
- package/src/plugins/builtin/risk-factors/headless.ts +2 -0
- package/src/plugins/builtin/scanner/flow-history.ts +2 -13
- package/src/plugins/builtin/scanner/headless.ts +14 -0
- package/src/plugins/builtin/scanner/hilo-bars.tsx +12 -70
- package/src/plugins/builtin/scanner/hilo-model.ts +0 -18
- package/src/plugins/builtin/seasonality/headless.ts +2 -0
- package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
- package/src/plugins/builtin/sec/filing-content.ts +42 -17
- package/src/plugins/builtin/sec/forms.ts +12 -0
- package/src/plugins/builtin/sec/headless.ts +2 -0
- package/src/plugins/builtin/sectors/client.ts +1 -0
- package/src/plugins/builtin/sectors/headless.ts +9 -1
- package/src/plugins/builtin/sectors/move-bar.tsx +10 -32
- package/src/plugins/builtin/sectors/sector-model.ts +2 -0
- package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
- package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
- package/src/plugins/builtin/shared/report-freshness.ts +57 -0
- package/src/plugins/builtin/shared/research-cells.tsx +4 -9
- package/src/plugins/builtin/short-interest/headless.ts +2 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/social-mentions/headless.ts +1 -0
- package/src/plugins/builtin/social-mentions/index.tsx +1 -1
- package/src/plugins/builtin/supply-chain/headless.ts +7 -1
- package/src/plugins/builtin/supply-chain/index.tsx +10 -1
- package/src/plugins/builtin/supply-chain/model.ts +27 -2
- package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
- package/src/plugins/builtin/themes/headless.ts +3 -0
- package/src/plugins/builtin/thirteenf/headless.ts +110 -25
- package/src/plugins/builtin/thirteenf/index.tsx +2 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +7 -1
- package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +5 -60
- package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -2
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +26 -26
- package/src/plugins/builtin/ticker-detail/pane.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +7 -1
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +20 -4
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -2
- package/src/plugins/builtin/time-sales/headless.ts +5 -1
- package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
- package/src/plugins/builtin/vol-surface/index.tsx +1 -1
- package/src/plugins/builtin/volatility/headless.ts +6 -1
- package/src/plugins/builtin/world-indices/headless.ts +2 -0
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +157 -0
- package/src/plugins/builtin/world-venue-map/basemap.ts +214 -0
- package/src/plugins/builtin/world-venue-map/client.ts +45 -0
- package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
- package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
- package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
- package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
- package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +447 -0
- package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
- package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
- package/src/plugins/builtin/world-venue-map/index.ts +67 -4
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +552 -0
- package/src/plugins/builtin/world-venue-map/layers.ts +348 -0
- package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +381 -45
- package/src/plugins/builtin/world-venue-map/model.ts +7 -4
- package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +199 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/pane.tsx +28 -43
- package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
- package/src/plugins/builtin/yield-curve/headless.ts +16 -0
- package/src/plugins/catalog-browser.ts +2 -0
- package/src/plugins/catalog-manifest.ts +1 -0
- package/src/plugins/catalog-ui.ts +3 -1
- package/src/plugins/catalog.ts +1 -1
- package/src/plugins/host-link.ts +33 -1
- package/src/plugins/installer.ts +48 -12
- package/src/plugins/loader.ts +30 -3
- package/src/plugins/manager-node.ts +15 -5
- package/src/plugins/registry/index.ts +1 -1
- package/src/plugins/registry/pane-settings.ts +26 -7
- package/src/public/__snapshots__/public-api.test.ts.snap +2 -0
- package/src/renderers/dom/build-assets.ts +81 -3
- package/src/renderers/dom/data-table/row.tsx +52 -16
- package/src/renderers/dom/desktop/controls.tsx +7 -3
- package/src/renderers/dom/desktop/icons.tsx +1 -0
- package/src/renderers/dom/desktop/list-view.tsx +35 -10
- package/src/renderers/dom/desktop/popover.tsx +73 -14
- package/src/renderers/dom/host/box.tsx +69 -26
- package/src/renderers/dom/host/input.tsx +14 -3
- package/src/renderers/dom/host/tabs.tsx +37 -1
- package/src/renderers/dom/styles.css +41 -7
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +11 -6
- package/src/renderers/electrobun/bun/desktop/backend.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +181 -87
- package/src/renderers/electrobun/bun/index.ts +73 -6
- package/src/renderers/electrobun/bun/window/remembered-frame.ts +122 -0
- package/src/renderers/electrobun/shared/protocol.ts +3 -0
- package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +3 -1
- package/src/renderers/electrobun/view/main.tsx +7 -1
- package/src/renderers/electrobun/view/renderer-window-error.ts +18 -0
- package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
- package/src/renderers/electrobun/view/update-host.ts +45 -21
- package/src/renderers/opentui/host.tsx +5 -0
- package/src/sources/gloomberb-cloud/index.ts +25 -4
- package/src/sources/gloomberb-cloud/normalizers.ts +36 -5
- package/src/sources/provider-router/cached-routes.ts +4 -1
- package/src/sources/provider-router/financials.ts +11 -8
- package/src/sources/provider-router/history.ts +15 -10
- package/src/sources/sec-registrant.ts +75 -0
- package/src/state/app/context/index.tsx +24 -8
- package/src/state/hooks/quote-streaming.ts +41 -26
- package/src/sync/core-contributors.ts +4 -0
- package/src/telemetry/benign-window-error.ts +7 -0
- package/src/telemetry/crash-reports-dom.ts +2 -0
- package/src/telemetry/crash-reports.ts +4 -1
- package/src/test-support/cli-context.ts +10 -2
- package/src/test-support/daily-nav.ts +25 -0
- package/src/theme/heat-colors.ts +357 -2
- package/src/tickers/instrument-kind.ts +34 -7
- package/src/tickers/search/asset-classes.ts +24 -9
- package/src/tickers/search/index.ts +44 -11
- package/src/tickers/search/ranking.ts +23 -3
- package/src/time-series/resolve.ts +1 -1
- package/src/time-series/use-chart-resolution.ts +1 -1
- package/src/types/context-menu.ts +6 -0
- package/src/types/data-provider.ts +2 -0
- package/src/types/financials.ts +5 -0
- package/src/types/headless.ts +79 -2
- package/src/types/plugin.ts +38 -6
- package/src/types/ticker.ts +15 -0
- package/src/ui/context-menu.tsx +1 -0
- package/src/ui/host.tsx +16 -0
- package/src/updater/index.ts +38 -13
- package/src/utils/async-deadline.ts +21 -0
- package/src/utils/cli-output.ts +5 -1
- package/src/utils/crypto-pair.ts +41 -0
- package/src/utils/currency-units.ts +14 -0
- package/src/utils/depositary-receipt.ts +26 -0
- package/src/utils/exchanges.ts +72 -0
- package/src/utils/fire-and-forget.ts +24 -0
- package/src/utils/format.ts +13 -0
- package/src/utils/price-earnings.ts +70 -3
- package/src/utils/price-history.ts +58 -13
- package/src/utils/rpc-timeout-error.ts +27 -0
- package/src/utils/sec.ts +13 -1
- package/src/utils/utc-time.ts +79 -0
package/src/plugins/installer.ts
CHANGED
|
@@ -95,6 +95,8 @@ export interface PluginDirectoryInfo {
|
|
|
95
95
|
path: string;
|
|
96
96
|
commit: string | null;
|
|
97
97
|
plugin: Pick<GloomPlugin, "id" | "name" | "version"> | null;
|
|
98
|
+
/** Sibling plugins installed along with it, by folder, each before the plugin that imports it. */
|
|
99
|
+
peers?: string[];
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
class GitError extends Error {
|
|
@@ -258,6 +260,10 @@ async function installDependencies(targetDir: string, quiet: boolean): Promise<v
|
|
|
258
260
|
}
|
|
259
261
|
|
|
260
262
|
async function readPluginExport(targetDir: string): Promise<Pick<GloomPlugin, "id" | "name" | "version"> | null> {
|
|
263
|
+
// Not before the sibling plugins it imports are installed: the import
|
|
264
|
+
// would fail, and Bun keeps that failure for the life of the process, so
|
|
265
|
+
// loading the plugin once the sibling is there would fail the same way.
|
|
266
|
+
if (missingPeerPlugins(targetDir).length > 0) return null;
|
|
261
267
|
const entryFile = await resolvePluginEntry(targetDir);
|
|
262
268
|
if (!entryFile) return null;
|
|
263
269
|
// Fresh so an update is validated against the new code, not the module Bun
|
|
@@ -322,6 +328,19 @@ export async function installPlugin(ref: string, options: PluginInstallOptions =
|
|
|
322
328
|
|
|
323
329
|
await installDependencies(targetDir, quiet);
|
|
324
330
|
|
|
331
|
+
const missing = missingPeerPlugins(targetDir);
|
|
332
|
+
if (missing.length > 0) {
|
|
333
|
+
say(cliStyles.muted(`Needs the ${missing.join(", ")} plugin.`));
|
|
334
|
+
return describe(targetDir, name, null);
|
|
335
|
+
}
|
|
336
|
+
return validateInstall(targetDir, name, quiet);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** Reads the export of a checkout that was just installed, and says what it is. */
|
|
340
|
+
async function validateInstall(targetDir: string, name: string, quiet: boolean): Promise<PluginDirectoryInfo> {
|
|
341
|
+
const say = (message: string) => {
|
|
342
|
+
if (!quiet) console.log(message);
|
|
343
|
+
};
|
|
325
344
|
try {
|
|
326
345
|
const plugin = await readPluginExport(targetDir);
|
|
327
346
|
if (plugin) {
|
|
@@ -518,28 +537,45 @@ export async function loadRegistryListings(): Promise<Map<string, RegistryListin
|
|
|
518
537
|
|
|
519
538
|
/**
|
|
520
539
|
* Installs a plugin the way the marketplace does: a listed one at the commit
|
|
521
|
-
* the registry reviewed
|
|
522
|
-
*
|
|
523
|
-
* several passes `listings` so the
|
|
540
|
+
* the registry reviewed (or at `options.pin`, the one the user was shown), and
|
|
541
|
+
* not at all on a Gloomberb too old to run it. An unlisted repository follows
|
|
542
|
+
* its default branch. A caller installing several passes `listings` so the
|
|
543
|
+
* registry is read once.
|
|
524
544
|
*/
|
|
525
545
|
export async function installListedPlugin(
|
|
526
546
|
ref: string,
|
|
527
|
-
options:
|
|
547
|
+
options: PluginInstallOptions = {},
|
|
528
548
|
listings?: ReadonlyMap<string, RegistryListing>,
|
|
529
549
|
): Promise<PluginDirectoryInfo> {
|
|
550
|
+
const { pin, ...shared } = options;
|
|
530
551
|
const repo = parseGitHubRef(ref).repo.toLowerCase();
|
|
531
|
-
const
|
|
552
|
+
const known = listings ?? await loadRegistryListings();
|
|
553
|
+
const listing = known.get(repo);
|
|
532
554
|
const required = requiredGloomberb(listing?.minGloomberb);
|
|
533
555
|
if (required) fail(`${ref} needs Gloomberb ${required}, this is ${VERSION}.`, "Update Gloomberb first.");
|
|
534
|
-
const
|
|
556
|
+
const reviewed = pin ?? listing?.pin;
|
|
557
|
+
const installed = await installPlugin(ref, { ...shared, ...(reviewed ? { pin: reviewed } : {}) });
|
|
558
|
+
const missing = missingPeerPlugins(installed.path);
|
|
559
|
+
if (missing.length === 0) return installed;
|
|
560
|
+
|
|
535
561
|
// A plugin that imports a sibling plugin (IBKR Gateway imports Interactive
|
|
536
|
-
// Brokers) brings it along, from the same registry.
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
562
|
+
// Brokers) brings it along, from the same registry. One that cannot be
|
|
563
|
+
// installed leaves the plugin waiting for it, never imported.
|
|
564
|
+
const peers: string[] = [];
|
|
565
|
+
for (const peer of missing) {
|
|
566
|
+
const peerRepo = [...known.keys()].find((candidate) => pluginDirectoryNames(peer).includes(candidate.split("/")[1] ?? ""));
|
|
567
|
+
if (!peerRepo) continue;
|
|
568
|
+
try {
|
|
569
|
+
const added = await installListedPlugin(peerRepo, shared, known);
|
|
570
|
+
peers.push(...(added.peers ?? []), added.directory);
|
|
571
|
+
} catch (error) {
|
|
572
|
+
if (!shared.quiet) console.error(cliStyles.warning(`Could not install ${peer}: ${error instanceof Error ? error.message : String(error)}`));
|
|
573
|
+
}
|
|
541
574
|
}
|
|
542
|
-
|
|
575
|
+
const withPeers = peers.length > 0 ? { peers } : {};
|
|
576
|
+
if (missingPeerPlugins(installed.path).length > 0) return { ...installed, ...withPeers };
|
|
577
|
+
linkHostPackages(installed.path);
|
|
578
|
+
return { ...await validateInstall(installed.path, installed.directory, shared.quiet === true), ...withPeers };
|
|
543
579
|
}
|
|
544
580
|
|
|
545
581
|
/** Folder names of every installed plugin, clones and links alike. */
|
package/src/plugins/loader.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { reportCrash } from "../telemetry/crash-reports";
|
|
|
8
8
|
import { findAbsorbedPlugin, type AbsorbedPlugin } from "./absorbed";
|
|
9
9
|
import { checkPluginCompatibility, explainPluginLoadError, findMissingHostExport, pluginSourceFiles, readPluginManifest } from "./compat";
|
|
10
10
|
import { installPluginDependencies, missingPluginDependencies } from "./dependencies";
|
|
11
|
-
import { linkHostPackages } from "./host-link";
|
|
11
|
+
import { isLinkedPeerModule, linkHostPackages } from "./host-link";
|
|
12
12
|
import { pluginFromModule, pluginSupportsTarget } from "./plugin-export";
|
|
13
13
|
|
|
14
14
|
const loaderLog = debugLog.createLogger("plugin-loader");
|
|
@@ -40,7 +40,11 @@ export interface LoadedExternalPlugin {
|
|
|
40
40
|
needsGloomberb?: string;
|
|
41
41
|
/** Set when the plugin loaded but does not support the running renderer. */
|
|
42
42
|
unsupportedTarget?: PluginTarget;
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Loaded in a way this session cannot fully apply: new files under modules
|
|
45
|
+
* it already imported, or an import Bun failed before a sibling plugin was
|
|
46
|
+
* linked. Never registered; the next launch loads it.
|
|
47
|
+
*/
|
|
44
48
|
needsRestart?: boolean;
|
|
45
49
|
}
|
|
46
50
|
|
|
@@ -197,6 +201,21 @@ export function pluginsMissingHostExports(): string[] {
|
|
|
197
201
|
return [...missingHostExportFailures].sort();
|
|
198
202
|
}
|
|
199
203
|
|
|
204
|
+
/** Bun's wording when an import does not resolve, from a native import. */
|
|
205
|
+
const UNRESOLVED_MODULE = /Cannot find (?:module|package) '([^']+)'/;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* The specifier an import failed to resolve. Bun puts it on the error as
|
|
209
|
+
* `specifier`; the message is only a fallback, because from Bun 1.4 it names
|
|
210
|
+
* the package alone ("Cannot find package 'peer' imported from …" for
|
|
211
|
+
* `peer/bridge`), and the subpath decides whether the peer has the file.
|
|
212
|
+
*/
|
|
213
|
+
export function unresolvedSpecifier(err: unknown, message: string): string | undefined {
|
|
214
|
+
const specifier = (err as { specifier?: unknown } | null)?.specifier;
|
|
215
|
+
if (typeof specifier === "string" && specifier) return specifier;
|
|
216
|
+
return UNRESOLVED_MODULE.exec(message)?.[1];
|
|
217
|
+
}
|
|
218
|
+
|
|
200
219
|
/** Imported at another commit earlier in this process, with files besides the entry that Bun keeps. */
|
|
201
220
|
function hasStaleModules(pluginDir: string, commit: string | null): boolean {
|
|
202
221
|
if (!importedCommits.has(pluginDir) || importedCommits.get(pluginDir) === commit) return false;
|
|
@@ -289,9 +308,17 @@ export async function loadExternalPlugin(
|
|
|
289
308
|
loaderLog.info(`Loaded external plugin: ${plugin.id} v${plugin.version ?? "0.0.0"}`);
|
|
290
309
|
return { ...base, ...restart, plugin };
|
|
291
310
|
} catch (err) {
|
|
311
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
312
|
+
// A sibling plugin it imports that is linked now but was not when this
|
|
313
|
+
// process first resolved it. Bun keeps that failure until a restart, which
|
|
314
|
+
// is all the plugin needs: not a crash.
|
|
315
|
+
const unresolved = unresolvedSpecifier(err, message);
|
|
316
|
+
if (unresolved && isLinkedPeerModule(pluginDir, unresolved)) {
|
|
317
|
+
loaderLog.info(`${directory} loads after a restart: ${message}`);
|
|
318
|
+
return { ...base, plugin: placeholder, needsRestart: true };
|
|
319
|
+
}
|
|
292
320
|
loaderLog.error(`Failed to load plugin from ${pluginDir}: ${err}`);
|
|
293
321
|
reportCrash(err, { kind: "plugin", plugin: directory });
|
|
294
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
295
322
|
if (findMissingHostExport(message)) missingHostExportFailures.add(directory);
|
|
296
323
|
return {
|
|
297
324
|
...base,
|
|
@@ -22,18 +22,28 @@ export interface NodePluginManagerHooks {
|
|
|
22
22
|
const installer = () => import("./installer");
|
|
23
23
|
|
|
24
24
|
export function createNodePluginManager(target: PluginTarget, hooks: NodePluginManagerHooks = {}): NodePluginManager {
|
|
25
|
-
async function attempt(
|
|
25
|
+
async function attempt(
|
|
26
|
+
run: () => Promise<{ directory: string; kept?: string; changed?: boolean; peers?: string[] }>,
|
|
27
|
+
): Promise<PluginOperationResult> {
|
|
26
28
|
try {
|
|
27
|
-
const { directory, kept, changed } = await run();
|
|
28
|
-
hooks.onChanged?.(join(getPluginsDir(),
|
|
29
|
-
return {
|
|
29
|
+
const { directory, kept, changed, peers } = await run();
|
|
30
|
+
for (const changedDirectory of [...(peers ?? []), directory]) hooks.onChanged?.(join(getPluginsDir(), changedDirectory));
|
|
31
|
+
return {
|
|
32
|
+
ok: true,
|
|
33
|
+
directory,
|
|
34
|
+
...(kept ? { kept } : {}),
|
|
35
|
+
...(changed !== undefined ? { changed } : {}),
|
|
36
|
+
...(peers?.length ? { peers } : {}),
|
|
37
|
+
};
|
|
30
38
|
} catch (error) {
|
|
31
39
|
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
32
40
|
}
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
return {
|
|
36
|
-
|
|
44
|
+
// Through the registry, like `gloomberb install`: a plugin that builds on
|
|
45
|
+
// another brings it along instead of failing to load without it.
|
|
46
|
+
install: (repo, pin) => attempt(async () => (await installer()).installListedPlugin(repo, { quiet: true, ...(pin ? { pin } : {}) })),
|
|
37
47
|
update: (directory, pin) => attempt(async () => (await installer()).updatePlugin(directory, { quiet: true, pin })),
|
|
38
48
|
remove: (directory) => attempt(async () => {
|
|
39
49
|
await (await installer()).removePlugin(directory, { quiet: true });
|
|
@@ -388,7 +388,7 @@ export class PluginRegistry implements PluginRuntimeAccess {
|
|
|
388
388
|
async togglePaneQuickSetting(paneId: string, key: string): Promise<void> {
|
|
389
389
|
const quickSetting = this.resolvePaneQuickSettings(paneId).find((setting) => setting.key === key);
|
|
390
390
|
if (!quickSetting) return;
|
|
391
|
-
await this.applyPaneSettingValue(paneId, quickSetting.field,
|
|
391
|
+
await this.applyPaneSettingValue(paneId, quickSetting.field, quickSetting.nextValue);
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
getCommandPluginId(commandId: string): string | undefined {
|
|
@@ -31,7 +31,9 @@ export interface ResolvedRegistryPaneQuickSetting extends PaneQuickSettingDef {
|
|
|
31
31
|
label: string;
|
|
32
32
|
description?: string;
|
|
33
33
|
value: boolean;
|
|
34
|
-
field: PaneSettingField
|
|
34
|
+
field: PaneSettingField;
|
|
35
|
+
/** What pressing the control writes to the field. */
|
|
36
|
+
nextValue: boolean | string;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export function resolveRegistryPaneQuickSettings(
|
|
@@ -39,17 +41,34 @@ export function resolveRegistryPaneQuickSettings(
|
|
|
39
41
|
): ResolvedRegistryPaneQuickSetting[] {
|
|
40
42
|
if (!resolved?.paneDef.quickSettings?.length) return [];
|
|
41
43
|
|
|
42
|
-
return resolved.paneDef.quickSettings.flatMap((quickSetting) => {
|
|
43
|
-
const field = resolved.settingsDef.fields.find((candidate) =>
|
|
44
|
-
|
|
45
|
-
));
|
|
46
|
-
if (
|
|
44
|
+
return resolved.paneDef.quickSettings.flatMap((quickSetting): ResolvedRegistryPaneQuickSetting[] => {
|
|
45
|
+
const field = resolved.settingsDef.fields.find((candidate) => candidate.key === quickSetting.key);
|
|
46
|
+
if (!field) return [];
|
|
47
|
+
if (quickSetting.visible && !quickSetting.visible(resolved.context)) return [];
|
|
48
|
+
if (quickSetting.onValue != null) {
|
|
49
|
+
if (field.type !== "select") return [];
|
|
50
|
+
const onValue = quickSetting.onValue;
|
|
51
|
+
const offValue = field.options.find((option) => option.value !== onValue)?.value;
|
|
52
|
+
if (offValue == null || !field.options.some((option) => option.value === onValue)) return [];
|
|
53
|
+
const value = resolved.context.settings[quickSetting.key] === onValue;
|
|
54
|
+
return [{
|
|
55
|
+
...quickSetting,
|
|
56
|
+
label: quickSetting.label ?? field.label,
|
|
57
|
+
description: field.description,
|
|
58
|
+
value,
|
|
59
|
+
field,
|
|
60
|
+
nextValue: value ? offValue : onValue,
|
|
61
|
+
}];
|
|
62
|
+
}
|
|
63
|
+
if (field.type !== "toggle") return [];
|
|
64
|
+
const value = resolved.context.settings[quickSetting.key] === true;
|
|
47
65
|
return [{
|
|
48
66
|
...quickSetting,
|
|
49
67
|
label: quickSetting.label ?? field.label,
|
|
50
68
|
description: field.description,
|
|
51
|
-
value
|
|
69
|
+
value,
|
|
52
70
|
field,
|
|
71
|
+
nextValue: !value,
|
|
53
72
|
}];
|
|
54
73
|
});
|
|
55
74
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile, writeFile } from "fs/promises";
|
|
2
|
-
import { join, relative } from "path";
|
|
2
|
+
import { dirname, join, relative, resolve } from "path";
|
|
3
|
+
import type { BunPlugin } from "bun";
|
|
3
4
|
import { TITLEBAR_OVERLAY_HEIGHT_PX } from "../../components/layout/titlebar-overlay";
|
|
4
5
|
|
|
5
6
|
/** Imports whose path ends with the first entry resolve to the second, relative to the view directory. */
|
|
@@ -27,6 +28,13 @@ interface ViewBundleOptions {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
const ELECTROBUN_VIEW_DIR = join(process.cwd(), "src", "renderers", "electrobun", "view");
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Where the world map finds its land data, relative to the map's
|
|
34
|
+
* `basemap.ts`. Only view bundles define it, so the terminal binary, which
|
|
35
|
+
* never draws that map, leaves the data out.
|
|
36
|
+
*/
|
|
37
|
+
export const WORLD_MAP_DATA_SPECIFIER = "./natural-earth/index.chunk.js";
|
|
30
38
|
const DOM_RENDERER_DIR = join(process.cwd(), "src", "renderers", "dom");
|
|
31
39
|
|
|
32
40
|
export function electrobunViewPath(...parts: string[]): string {
|
|
@@ -50,6 +58,7 @@ export async function buildViewBundle({
|
|
|
50
58
|
failureMessage,
|
|
51
59
|
missingEntryMessage,
|
|
52
60
|
}: ViewBundleOptions): Promise<{ script: string; stylesheet: string | null }> {
|
|
61
|
+
const chunks = new Map<string, string>();
|
|
53
62
|
const result = await Bun.build({
|
|
54
63
|
entrypoints: [entrypoint],
|
|
55
64
|
outdir,
|
|
@@ -58,8 +67,15 @@ export async function buildViewBundle({
|
|
|
58
67
|
splitting: false,
|
|
59
68
|
sourcemap,
|
|
60
69
|
minify: true,
|
|
61
|
-
define: {
|
|
62
|
-
|
|
70
|
+
define: {
|
|
71
|
+
"process.env.NODE_ENV": "\"production\"",
|
|
72
|
+
__GLOOM_WORLD_MAP_DATA__: JSON.stringify(WORLD_MAP_DATA_SPECIFIER),
|
|
73
|
+
...define,
|
|
74
|
+
},
|
|
75
|
+
plugins: [
|
|
76
|
+
lazyChunkPlugin(outdir, outdir, chunks),
|
|
77
|
+
...(aliasRules.length > 0 ? [electrobunViewAliasPlugin(aliasRules)] : []),
|
|
78
|
+
],
|
|
63
79
|
});
|
|
64
80
|
|
|
65
81
|
if (!result.success) {
|
|
@@ -69,6 +85,7 @@ export async function buildViewBundle({
|
|
|
69
85
|
|
|
70
86
|
const script = result.outputs.find((output) => output.kind === "entry-point" && output.path.endsWith(".js"));
|
|
71
87
|
if (!script) throw new Error(missingEntryMessage);
|
|
88
|
+
await buildLazyChunks(outdir, chunks, failureMessage);
|
|
72
89
|
|
|
73
90
|
const stylesheet = result.outputs.find((output) => output.path.endsWith(".css"))?.path ?? null;
|
|
74
91
|
if (stylesheet) await writeFile(stylesheet, withTitlebarOverlayHeight(await readFile(stylesheet, "utf8")));
|
|
@@ -122,6 +139,67 @@ ${bootstrapScript}
|
|
|
122
139
|
`;
|
|
123
140
|
}
|
|
124
141
|
|
|
142
|
+
/**
|
|
143
|
+
* The view bundle is one file (no splitting), so a module reached through
|
|
144
|
+
* `import()` would land in it. A module named `*.chunk.ts` and imported as
|
|
145
|
+
* `import("./path/name.chunk.js")` instead ships as its own file at that path
|
|
146
|
+
* next to the importing bundle, fetched the first time it is asked for: large
|
|
147
|
+
* data only some panes draw, such as the world map's coastlines. The terminal
|
|
148
|
+
* and the tests run the source, where the same `import()` loads the module.
|
|
149
|
+
*/
|
|
150
|
+
function lazyChunkPlugin(rootOutdir: string, emitDir: string, chunks: Map<string, string>): BunPlugin {
|
|
151
|
+
return {
|
|
152
|
+
name: "lazy-chunks",
|
|
153
|
+
setup(build) {
|
|
154
|
+
build.onResolve({ filter: /\.chunk(\.js|\.ts)?$/ }, (args) => {
|
|
155
|
+
if (args.kind.startsWith("entry-point") || /[\\/]node_modules[\\/]/.test(args.importer)) return undefined;
|
|
156
|
+
if (args.kind !== "dynamic-import") {
|
|
157
|
+
throw new Error(`${args.path} is a lazy chunk; load it with import() (from ${args.importer})`);
|
|
158
|
+
}
|
|
159
|
+
if (!args.path.startsWith("./") || !args.path.endsWith(".chunk.js")) {
|
|
160
|
+
throw new Error(`Lazy chunk ${args.path} must be imported as "./<path>.chunk.js" (from ${args.importer})`);
|
|
161
|
+
}
|
|
162
|
+
const source = resolve(dirname(args.importer), args.path.replace(/\.js$/, ".ts"));
|
|
163
|
+
const output = resolve(emitDir, args.path);
|
|
164
|
+
if (relative(rootOutdir, output).startsWith("..")) throw new Error(`Lazy chunk ${args.path} would land outside ${rootOutdir}`);
|
|
165
|
+
const existing = chunks.get(output);
|
|
166
|
+
if (existing && existing !== source) throw new Error(`Two lazy chunks emit ${output}: ${existing} and ${source}`);
|
|
167
|
+
chunks.set(output, source);
|
|
168
|
+
return { path: args.path, external: true };
|
|
169
|
+
});
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Builds each lazy chunk on its own, and the chunks those load in turn. */
|
|
175
|
+
async function buildLazyChunks(rootOutdir: string, chunks: Map<string, string>, failureMessage: string): Promise<void> {
|
|
176
|
+
const built = new Set<string>();
|
|
177
|
+
let pending = [...chunks.entries()];
|
|
178
|
+
while (pending.length) {
|
|
179
|
+
const nested = new Map<string, string>();
|
|
180
|
+
for (const [output, source] of pending) {
|
|
181
|
+
if (built.has(output)) continue;
|
|
182
|
+
built.add(output);
|
|
183
|
+
const result = await Bun.build({
|
|
184
|
+
entrypoints: [source],
|
|
185
|
+
outdir: dirname(output),
|
|
186
|
+
naming: relative(dirname(output), output),
|
|
187
|
+
target: "browser",
|
|
188
|
+
format: "esm",
|
|
189
|
+
splitting: false,
|
|
190
|
+
sourcemap: "none",
|
|
191
|
+
minify: true,
|
|
192
|
+
plugins: [lazyChunkPlugin(rootOutdir, dirname(output), nested)],
|
|
193
|
+
});
|
|
194
|
+
if (!result.success) {
|
|
195
|
+
const details = result.logs.map((log) => log.message).filter(Boolean).join("\n");
|
|
196
|
+
throw new Error(`${failureMessage}: lazy chunk ${source}\n${details}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
pending = [...nested.entries()];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
125
203
|
function electrobunViewAliasPlugin(aliasRules: AliasRule[]) {
|
|
126
204
|
return {
|
|
127
205
|
name: "electrobun-view-aliases",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @jsxImportSource react */
|
|
2
|
-
import { memo, type CSSProperties } from "react";
|
|
2
|
+
import { memo, type CSSProperties, type ReactNode } from "react";
|
|
3
3
|
import { TextAttributes } from "../../../ui/host";
|
|
4
4
|
import { DisclosureMarker } from "../../../components/ui/disclosure-marker";
|
|
5
5
|
import type {
|
|
@@ -27,10 +27,26 @@ import {
|
|
|
27
27
|
eventWithCellCoordinates,
|
|
28
28
|
} from "./dom";
|
|
29
29
|
|
|
30
|
-
/** Space between a
|
|
31
|
-
const
|
|
30
|
+
/** Space between a label and its sort marker or the artwork drawn before it. */
|
|
31
|
+
const LABEL_GAP_PX = 4;
|
|
32
32
|
const SORT_MARKER_SIZE_PX = 9;
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Artwork a column or cell draws before its text. It is decoration, so
|
|
36
|
+
* assistive technology skips it and the text stays the only name.
|
|
37
|
+
*/
|
|
38
|
+
function Leading({ children }: { children: ReactNode }) {
|
|
39
|
+
return (
|
|
40
|
+
<span
|
|
41
|
+
aria-hidden="true"
|
|
42
|
+
data-gloom-role="data-table-leading"
|
|
43
|
+
style={{ display: "flex", flex: "none", alignItems: "center" }}
|
|
44
|
+
>
|
|
45
|
+
{children}
|
|
46
|
+
</span>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
34
50
|
function contentJustifyForAlign(align: string | undefined): CSSProperties["justifyContent"] {
|
|
35
51
|
if (align === "right") return "flex-end";
|
|
36
52
|
if (align === "center") return "center";
|
|
@@ -130,7 +146,7 @@ export function WebDataTableHeader<C extends DataTableColumn>({
|
|
|
130
146
|
display: "flex",
|
|
131
147
|
alignItems: "center",
|
|
132
148
|
justifyContent: contentJustifyForAlign(column.align),
|
|
133
|
-
gap: column.label ?
|
|
149
|
+
gap: column.label ? LABEL_GAP_PX : 0,
|
|
134
150
|
backgroundColor: column.headerBackgroundColor ?? CSS_PANEL,
|
|
135
151
|
boxShadow: freezeFirstColumn && columnIndex === 0 ? `-${inlinePaddingPx(horizontalPadding)}px 0 0 ${column.headerBackgroundColor ?? CSS_PANEL}, ${columnGap * WEB_CELL_WIDTH}px 0 0 ${column.headerBackgroundColor ?? CSS_PANEL}` : undefined,
|
|
136
152
|
}}
|
|
@@ -141,6 +157,7 @@ export function WebDataTableHeader<C extends DataTableColumn>({
|
|
|
141
157
|
onHeaderClick(column.id);
|
|
142
158
|
} : undefined}
|
|
143
159
|
>
|
|
160
|
+
{column.headerLeading !== undefined ? <Leading>{column.headerLeading}</Leading> : null}
|
|
144
161
|
<span
|
|
145
162
|
title={column.label || undefined}
|
|
146
163
|
style={{
|
|
@@ -336,6 +353,8 @@ function WebDataTableRowInner<
|
|
|
336
353
|
<div
|
|
337
354
|
key={column.id}
|
|
338
355
|
data-gloom-role="data-table-cell"
|
|
356
|
+
// The instant behind a shortened time ("Wed 11:27"), so a rendered-view report can print it whole.
|
|
357
|
+
data-gloom-cell-instant={cell.value instanceof Date && Number.isFinite(cell.value.getTime()) ? cell.value.toISOString() : undefined}
|
|
339
358
|
style={{
|
|
340
359
|
minWidth: 0,
|
|
341
360
|
position: freezeFirstColumn && columnIndex === 0 ? "sticky" : undefined,
|
|
@@ -392,18 +411,13 @@ function WebDataTableRowInner<
|
|
|
392
411
|
{cell.content}
|
|
393
412
|
</div>
|
|
394
413
|
) : (
|
|
395
|
-
<
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
cell.attributes ?? TextAttributes.NONE,
|
|
403
|
-
)}
|
|
404
|
-
>
|
|
405
|
-
{cell.text}
|
|
406
|
-
</span>
|
|
414
|
+
<CellText
|
|
415
|
+
cell={cell}
|
|
416
|
+
column={column}
|
|
417
|
+
color={selected && (cell.color === undefined || (selectedTextOverridesCellColor && !cell.keepColorWhenSelected))
|
|
418
|
+
? CSS_SELECTED_TEXT
|
|
419
|
+
: cell.color ?? CSS_TEXT}
|
|
420
|
+
/>
|
|
407
421
|
)}
|
|
408
422
|
</div>
|
|
409
423
|
);
|
|
@@ -412,4 +426,26 @@ function WebDataTableRowInner<
|
|
|
412
426
|
);
|
|
413
427
|
}
|
|
414
428
|
|
|
429
|
+
function CellText({ cell, column, color }: { cell: DataTableCell; column: DataTableColumn; color: string }) {
|
|
430
|
+
const style = clippedCellTextStyle(column, color, cell.attributes ?? TextAttributes.NONE);
|
|
431
|
+
if (cell.leading === undefined) return <span title={cell.text} style={style}>{cell.text}</span>;
|
|
432
|
+
return (
|
|
433
|
+
<div
|
|
434
|
+
style={{
|
|
435
|
+
display: "flex",
|
|
436
|
+
alignItems: "center",
|
|
437
|
+
justifyContent: contentJustifyForAlign(column.align),
|
|
438
|
+
gap: LABEL_GAP_PX,
|
|
439
|
+
width: "100%",
|
|
440
|
+
height: "100%",
|
|
441
|
+
minWidth: 0,
|
|
442
|
+
overflow: "hidden",
|
|
443
|
+
}}
|
|
444
|
+
>
|
|
445
|
+
<Leading>{cell.leading}</Leading>
|
|
446
|
+
<span title={cell.text} style={{ ...style, width: "auto", flex: "0 1 auto" }}>{cell.text}</span>
|
|
447
|
+
</div>
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
415
451
|
export const WebDataTableRow = memo(WebDataTableRowInner) as typeof WebDataTableRowInner;
|
|
@@ -345,8 +345,10 @@ export function WebTextField({
|
|
|
345
345
|
focusedBackgroundColor={plain ? "transparent" : resolvedBackgroundColor}
|
|
346
346
|
cursorColor={colors.textBright}
|
|
347
347
|
style={{
|
|
348
|
-
|
|
349
|
-
|
|
348
|
+
// A framed field keeps its text one cell off the frame; a plain one
|
|
349
|
+
// sits flush in the row or band that holds it.
|
|
350
|
+
paddingLeft: plain ? 0 : "var(--cell-w)",
|
|
351
|
+
paddingRight: plain ? 0 : "var(--cell-w)",
|
|
350
352
|
borderRadius: plain ? 0 : CONTROL_RADIUS,
|
|
351
353
|
// The field is taller than a cell, so the input takes the inner
|
|
352
354
|
// height and centers its text on the box's own line.
|
|
@@ -581,8 +583,10 @@ export function WebDialogFrame({
|
|
|
581
583
|
</Box>
|
|
582
584
|
{children}
|
|
583
585
|
{footer && (
|
|
586
|
+
// Sized by its line, not one cell: a cell-high box with this padding
|
|
587
|
+
// left the key line hanging out of its bottom.
|
|
584
588
|
<Box
|
|
585
|
-
|
|
589
|
+
flexShrink={0}
|
|
586
590
|
style={{
|
|
587
591
|
borderTop: `1px solid ${panelBorder(colors)}`,
|
|
588
592
|
paddingTop: 8,
|
|
@@ -14,6 +14,7 @@ const ICONS: Record<IconName, ReactNode> = {
|
|
|
14
14
|
),
|
|
15
15
|
close: <path d="M3 3L9 9M9 3L3 9" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />,
|
|
16
16
|
zap: <path d="M7.1 1.2 2.7 6.5h3.1l-.7 4.3 4.4-5.5H6.4l.7-4.1Z" fill="currentColor" />,
|
|
17
|
+
sqrt: <path d="M1.5 6.6h1.6l1.8 3.6L7.6 2h3" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" />,
|
|
17
18
|
lock: (
|
|
18
19
|
<>
|
|
19
20
|
<rect x="2.5" y="5.5" width="7" height="5" rx="1.2" fill="currentColor" />
|
|
@@ -5,6 +5,7 @@ import { TextAttributes } from "../../../ui";
|
|
|
5
5
|
import type { ListRowState, ListViewItem, ListViewProps } from "../../../components/ui/list-view";
|
|
6
6
|
import { blendHex, hoverBg, type ThemeColors } from "../../../theme/colors";
|
|
7
7
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
8
|
+
import { WEB_CELL_HEIGHT } from "../../../theme/font-scale";
|
|
8
9
|
import { isInsideDialogSurface } from "../host/focus-scope";
|
|
9
10
|
import { isEditableKeyboardTarget } from "../key-event";
|
|
10
11
|
import {
|
|
@@ -58,6 +59,10 @@ function DefaultDesktopRow({
|
|
|
58
59
|
);
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
const FRAMED_LIST_PADDING_PX = 4;
|
|
63
|
+
/** What a framed list adds above and below its rows: padding and a 1px border on each side. */
|
|
64
|
+
const FRAMED_LIST_CHROME_PX = 2 * (FRAMED_LIST_PADDING_PX + 1);
|
|
65
|
+
|
|
61
66
|
function listRowStyle(selected: boolean, disabled: boolean, colors: ThemeColors): CSSProperties {
|
|
62
67
|
return {
|
|
63
68
|
borderRadius: CONTROL_RADIUS,
|
|
@@ -109,6 +114,16 @@ export function WebListView({
|
|
|
109
114
|
const tabStopIndex = selectedIndex >= 0 && items[selectedIndex] && !items[selectedIndex].disabled
|
|
110
115
|
? selectedIndex : items.findIndex((item) => !item.disabled);
|
|
111
116
|
const effectiveSurface = surface ?? (scrollable ? "framed" : "plain");
|
|
117
|
+
// `height` counts terminal rows. A list that is not meant to scroll takes
|
|
118
|
+
// only the rows it has, up to that many; one with more rows than that
|
|
119
|
+
// scrolls inside the height instead of drawing over whatever follows it.
|
|
120
|
+
const rowsHeight = items.length === 0 ? 1 : items.length * rowHeight + (items.length - 1) * rowGap;
|
|
121
|
+
const overflowsHeight = !scrollable && height != null && rowsHeight > height;
|
|
122
|
+
const scrolls = scrollable || overflowsHeight;
|
|
123
|
+
// The frame's padding and border sit outside the rows it was asked to hold.
|
|
124
|
+
const scrollHeight = overflowsHeight
|
|
125
|
+
? `${height * WEB_CELL_HEIGHT + (effectiveSurface === "plain" ? 0 : FRAMED_LIST_CHROME_PX)}px`
|
|
126
|
+
: height;
|
|
112
127
|
const frameStyle = effectiveSurface === "plain"
|
|
113
128
|
? {
|
|
114
129
|
border: "none",
|
|
@@ -119,12 +134,12 @@ export function WebListView({
|
|
|
119
134
|
: {
|
|
120
135
|
border: `1px solid ${panelBorder(colors)}`,
|
|
121
136
|
borderRadius: CONTROL_RADIUS,
|
|
122
|
-
padding:
|
|
137
|
+
padding: FRAMED_LIST_PADDING_PX,
|
|
123
138
|
backgroundColor: subtlePanelFill(colors),
|
|
124
139
|
};
|
|
125
140
|
|
|
126
141
|
useEffect(() => {
|
|
127
|
-
if (!
|
|
142
|
+
if (!scrolls || !autoScrollToIndex || activeScrollIndex < 0) return;
|
|
128
143
|
const scrollBox = scrollRef.current;
|
|
129
144
|
if (!scrollBox) return;
|
|
130
145
|
const safeIndex = Math.min(activeScrollIndex, items.length - 1);
|
|
@@ -136,16 +151,16 @@ export function WebListView({
|
|
|
136
151
|
} else if (rowBottom > scrollBox.scrollTop + viewportHeight) {
|
|
137
152
|
scrollBox.scrollTo(rowBottom - viewportHeight);
|
|
138
153
|
}
|
|
139
|
-
}, [activeScrollIndex, autoScrollToIndex, items.length, rowHeight, rowStride,
|
|
154
|
+
}, [activeScrollIndex, autoScrollToIndex, items.length, rowHeight, rowStride, scrolls]);
|
|
140
155
|
|
|
141
156
|
useEffect(() => {
|
|
142
|
-
if (!
|
|
157
|
+
if (!scrolls) return;
|
|
143
158
|
const scrollBox = scrollRef.current;
|
|
144
159
|
if (!scrollBox) return;
|
|
145
160
|
if (scrollBox.verticalScrollBar) {
|
|
146
161
|
scrollBox.verticalScrollBar.visible = items.length * rowStride - rowGap > (scrollBox.viewport?.height ?? 0);
|
|
147
162
|
}
|
|
148
|
-
}, [items.length, height, flexGrow, rowGap, rowStride,
|
|
163
|
+
}, [items.length, height, flexGrow, rowGap, rowStride, scrolls]);
|
|
149
164
|
|
|
150
165
|
// The dialog or pane around the list moves its cursor (j/k, Home/End). A row
|
|
151
166
|
// Tab or a press left focused follows it, or Space and Enter would act on the
|
|
@@ -156,8 +171,8 @@ export function WebListView({
|
|
|
156
171
|
const active = document.activeElement;
|
|
157
172
|
if (!list || !active || !list.contains(active) || isEditableKeyboardTarget(active)) return;
|
|
158
173
|
const row = list.querySelectorAll<HTMLElement>('[role="option"]')[selectedIndex];
|
|
159
|
-
if (row && !row.contains(active)) row.focus({ preventScroll:
|
|
160
|
-
}, [listDomId,
|
|
174
|
+
if (row && !row.contains(active)) row.focus({ preventScroll: scrolls });
|
|
175
|
+
}, [listDomId, scrolls, selectedIndex]);
|
|
161
176
|
|
|
162
177
|
const rows = items.length === 0
|
|
163
178
|
? (
|
|
@@ -233,11 +248,21 @@ export function WebListView({
|
|
|
233
248
|
});
|
|
234
249
|
|
|
235
250
|
return (
|
|
236
|
-
<Box
|
|
237
|
-
{
|
|
251
|
+
<Box
|
|
252
|
+
id={listDomId}
|
|
253
|
+
flexDirection="column"
|
|
254
|
+
height={scrollable ? height : undefined}
|
|
255
|
+
// A list sized by its container gives up height to it, and scrolls.
|
|
256
|
+
minHeight={scrollable && height == null ? 0 : undefined}
|
|
257
|
+
flexGrow={flexGrow}
|
|
258
|
+
gap={1}
|
|
259
|
+
role="listbox"
|
|
260
|
+
aria-label={remoteLabel}
|
|
261
|
+
>
|
|
262
|
+
{scrolls ? (
|
|
238
263
|
<ScrollBox
|
|
239
264
|
ref={scrollRef}
|
|
240
|
-
height={
|
|
265
|
+
height={scrollHeight}
|
|
241
266
|
flexGrow={flexGrow}
|
|
242
267
|
scrollY
|
|
243
268
|
focusable={false}
|