gloomberb 0.18.2 → 0.18.4
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 +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { AppConfig } from "../types/config";
|
|
2
2
|
import type { Portfolio, PortfolioCash, TickerPosition, TickerRecord, Watchlist } from "../types/ticker";
|
|
3
|
-
import { resolveCurrencyUnit, US_CENTS } from "../utils/currency-units";
|
|
3
|
+
import { normalizeHeldCurrencyCode, resolveCurrencyUnit, US_CENTS } from "../utils/currency-units";
|
|
4
4
|
import { slugifyName } from "../utils/slugify";
|
|
5
5
|
import { parseCollectionRef } from "../team/collections";
|
|
6
6
|
import { findNamedCollection } from "./collection-name";
|
|
7
7
|
import { isFuturesTicker } from "./futures-positions";
|
|
8
|
-
import { manualPortfolioLots } from "./manual-lots";
|
|
8
|
+
import { manualPortfolioLots, mergeLotCostTerms, type LotCostFxConflict } from "./manual-lots";
|
|
9
9
|
|
|
10
10
|
export interface DeleteWatchlistResult {
|
|
11
11
|
config: AppConfig;
|
|
@@ -39,15 +39,41 @@ export interface SetManualPortfolioPositionInput {
|
|
|
39
39
|
* read does not unsize it.
|
|
40
40
|
*/
|
|
41
41
|
multiplier?: number;
|
|
42
|
-
/**
|
|
43
|
-
|
|
42
|
+
/**
|
|
43
|
+
* The purchase date, YYYY-MM-DD. Null clears it; left out, the lots keep
|
|
44
|
+
* theirs (several, their earliest: mergeLotCostTerms).
|
|
45
|
+
*/
|
|
46
|
+
dateAcquired?: string | null;
|
|
44
47
|
/**
|
|
45
48
|
* The rate the cost was bought at: one unit of `currency` in `costFx.currency`.
|
|
46
|
-
* Null clears it; left out,
|
|
49
|
+
* Null clears it; left out, manual lots in the same currency keep theirs
|
|
50
|
+
* (several, weighted by cost), and lots whose rates cannot become one
|
|
51
|
+
* refuse the set (LotCostFxMergeError).
|
|
47
52
|
*/
|
|
48
53
|
costFx?: { rate: number; currency: string } | null;
|
|
49
54
|
}
|
|
50
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Several lots replaced by one position whose cost FX rate would be inferred
|
|
58
|
+
* from theirs, when theirs cannot honestly become one (mergeLotCostTerms):
|
|
59
|
+
* the set is refused until the position's own rate is given or cleared.
|
|
60
|
+
*/
|
|
61
|
+
export class LotCostFxMergeError extends Error {
|
|
62
|
+
constructor(readonly lotCount: number, readonly conflict: LotCostFxConflict, ratedCount: number) {
|
|
63
|
+
super(lotCostFxMergeMessage(lotCount, conflict, ratedCount));
|
|
64
|
+
this.name = "LotCostFxMergeError";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function lotCostFxMergeMessage(lotCount: number, conflict: LotCostFxConflict, ratedCount: number): string {
|
|
69
|
+
if (conflict === "lot-currencies") return `The ${lotCount} lots are in different currencies, so one position cannot keep the FX rate their costs were bought at.`;
|
|
70
|
+
if (conflict === "rate-currencies") return `The ${lotCount} lots' costs were converted into different currencies, so one position cannot keep their FX rates.`;
|
|
71
|
+
const rated = ratedCount === 1
|
|
72
|
+
? "1 converts its cost at the FX rate it was bought at"
|
|
73
|
+
: `${ratedCount} convert their cost at the FX rate they were bought at`;
|
|
74
|
+
return `Of the ${lotCount} lots, ${rated} and ${lotCount - ratedCount} at today's, so one position cannot keep their rates.`;
|
|
75
|
+
}
|
|
76
|
+
|
|
51
77
|
/** What a position's size counts, as its field and messages name it. */
|
|
52
78
|
export type PositionQuantityLabel = "Contracts" | "Shares";
|
|
53
79
|
|
|
@@ -112,7 +138,11 @@ export function resolveManualPositionCurrency(
|
|
|
112
138
|
baseCurrency: string | undefined,
|
|
113
139
|
contractCurrency?: string | null,
|
|
114
140
|
): string {
|
|
115
|
-
|
|
141
|
+
// Pence typed as GBp stay pence: upper-cased they would read as pounds. A listing's own GBp is
|
|
142
|
+
// what its quote is shown in once converted, pounds, so a blank currency still saves GBP.
|
|
143
|
+
const typed = rawCurrency?.trim();
|
|
144
|
+
if (typed) return normalizeHeldCurrencyCode(typed);
|
|
145
|
+
return (contractCurrency?.trim() || ticker.metadata.currency || portfolio.currency || baseCurrency || "USD").toUpperCase();
|
|
116
146
|
}
|
|
117
147
|
|
|
118
148
|
/** A plain ISO code in major units (AUD), else null: pence-type units, US cents and free text never total a portfolio. */
|
|
@@ -140,10 +170,11 @@ export function hasOpenPortfolioPositions(portfolioId: string, tickers: Iterable
|
|
|
140
170
|
/**
|
|
141
171
|
* Whether a manual portfolio's currency follows its holdings. Only with the
|
|
142
172
|
* default USD base: a base currency the user chose is what manual portfolios
|
|
143
|
-
* total in. Team portfolios keep the currency the team gave them
|
|
173
|
+
* total in. Team portfolios keep the currency the team gave them, and one
|
|
174
|
+
* created in a currency keeps that.
|
|
144
175
|
*/
|
|
145
176
|
function takesHoldingsCurrency(config: AppConfig, portfolio: Portfolio): boolean {
|
|
146
|
-
return isManualPortfolio(portfolio) && !portfolio.teamId && config.baseCurrency.trim().toUpperCase() === "USD";
|
|
177
|
+
return isManualPortfolio(portfolio) && !portfolio.teamId && !portfolio.fixedCurrency && config.baseCurrency.trim().toUpperCase() === "USD";
|
|
147
178
|
}
|
|
148
179
|
|
|
149
180
|
function withPortfolioCurrency(config: AppConfig, portfolioId: string, currency: string): AppConfig {
|
|
@@ -239,10 +270,15 @@ export function clearPortfolioTargetWeights(
|
|
|
239
270
|
};
|
|
240
271
|
}
|
|
241
272
|
|
|
273
|
+
/**
|
|
274
|
+
* A new manual portfolio in `baseCurrency`, or, with `fixedCurrency`, in
|
|
275
|
+
* `currency` for good (Portfolio.fixedCurrency).
|
|
276
|
+
*/
|
|
242
277
|
export function createManualPortfolio(
|
|
243
278
|
config: AppConfig,
|
|
244
279
|
name: string,
|
|
245
280
|
baseCurrency: string,
|
|
281
|
+
{ fixedCurrency }: { fixedCurrency?: string } = {},
|
|
246
282
|
): { config: AppConfig; portfolio: Portfolio } {
|
|
247
283
|
const trimmedName = name.trim();
|
|
248
284
|
if (!trimmedName) {
|
|
@@ -258,11 +294,9 @@ export function createManualPortfolio(
|
|
|
258
294
|
throw new Error(`Portfolio "${trimmedName}" already exists.`);
|
|
259
295
|
}
|
|
260
296
|
|
|
261
|
-
const portfolio: Portfolio =
|
|
262
|
-
id,
|
|
263
|
-
name: trimmedName,
|
|
264
|
-
currency: (baseCurrency || config.baseCurrency || "USD").toUpperCase(),
|
|
265
|
-
};
|
|
297
|
+
const portfolio: Portfolio = fixedCurrency
|
|
298
|
+
? { id, name: trimmedName, currency: fixedCurrency.toUpperCase(), fixedCurrency: true }
|
|
299
|
+
: { id, name: trimmedName, currency: (baseCurrency || config.baseCurrency || "USD").toUpperCase() };
|
|
266
300
|
|
|
267
301
|
return {
|
|
268
302
|
config: {
|
|
@@ -399,7 +433,7 @@ export function setManualPortfolioPosition(
|
|
|
399
433
|
portfolioId: string,
|
|
400
434
|
input: SetManualPortfolioPositionInput,
|
|
401
435
|
): SetManualPortfolioPositionResult {
|
|
402
|
-
const nextCurrency = input.currency
|
|
436
|
+
const nextCurrency = normalizeHeldCurrencyCode(input.currency);
|
|
403
437
|
const sharesError = validatePositionShares(input.shares, positionQuantityLabel(ticker));
|
|
404
438
|
if (sharesError) throw new Error(sharesError);
|
|
405
439
|
if (!Number.isFinite(input.avgCost)) {
|
|
@@ -411,14 +445,18 @@ export function setManualPortfolioPosition(
|
|
|
411
445
|
|
|
412
446
|
const replacedPositions = ticker.metadata.positions.filter((position) => position.portfolio === portfolioId);
|
|
413
447
|
const replacedPositionCount = replacedPositions.length;
|
|
414
|
-
// Editing a
|
|
415
|
-
//
|
|
416
|
-
const
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
const keptCostFx =
|
|
420
|
-
|
|
421
|
-
|
|
448
|
+
// Editing a snapshot (for example after a split) changes neither its purchase date nor, while its
|
|
449
|
+
// currency stays, the rate its cost was bought at. Several manual lots keep theirs merged.
|
|
450
|
+
const manual = replacedPositions.length > 0 && replacedPositions.every((position) => position.broker === "manual");
|
|
451
|
+
const kept = manual ? mergeLotCostTerms(replacedPositions) : {};
|
|
452
|
+
const dateAcquired = input.dateAcquired === undefined ? kept.dateAcquired : input.dateAcquired;
|
|
453
|
+
const keptCostFx = kept.costFx && kept.currency === nextCurrency ? kept.costFx : null;
|
|
454
|
+
// Lots in this currency with a rate that cannot become the position's: refused rather than dropped or guessed.
|
|
455
|
+
const ratedHere = replacedPositions.filter((position) =>
|
|
456
|
+
normalizeHeldCurrencyCode(position.currency) === nextCurrency && position.costFxRate != null && position.costFxCurrency);
|
|
457
|
+
if (input.costFx === undefined && kept.costFxConflict && ratedHere.length > 0) {
|
|
458
|
+
throw new LotCostFxMergeError(replacedPositions.length, kept.costFxConflict, replacedPositions.filter((position) => position.costFxRate != null && position.costFxCurrency).length);
|
|
459
|
+
}
|
|
422
460
|
const costFx = input.costFx === undefined ? keptCostFx : input.costFx;
|
|
423
461
|
if (costFx && !(Number.isFinite(costFx.rate) && costFx.rate > 0)) throw new Error("The cost FX rate must be a positive number.");
|
|
424
462
|
// A contract's size does not change with the count held; one the lots agree on carries over.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import type { AppConfig } from "../types/config";
|
|
2
|
+
import type { TickerMetadata, TickerPosition, TickerRecord } from "../types/ticker";
|
|
3
|
+
import { listingSuffixVenue, tickerHasListingSuffix } from "../sources/listing-symbols";
|
|
4
|
+
import { canonicalExchange, parsePublicTickerKey, publicTickerKey } from "../utils/exchanges";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A lot as the fields sync keeps of it (`sanitizePosition`), so a copy that
|
|
8
|
+
* went through sync, or through an older build, reads as the same lot.
|
|
9
|
+
*/
|
|
10
|
+
function lotFingerprint(lot: TickerPosition): string {
|
|
11
|
+
const costFx = lot.costFxRate != null && lot.costFxCurrency ? [lot.costFxRate, lot.costFxCurrency] : [null, null];
|
|
12
|
+
return JSON.stringify([
|
|
13
|
+
lot.portfolio, lot.shares, lot.avgCost ?? null, lot.currency ?? null, lot.dateAcquired ?? null, ...costFx,
|
|
14
|
+
lot.broker, lot.side ?? null, lot.multiplier ?? null,
|
|
15
|
+
]);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface SuffixedListingMerge {
|
|
19
|
+
/** The rows to save: each listing's row with what its suffixed rows held, then those rows emptied. */
|
|
20
|
+
saves: TickerRecord[];
|
|
21
|
+
/**
|
|
22
|
+
* Each suffixed row's key to its listing row's key: the rows merged now,
|
|
23
|
+
* and ones merged before, whose targets an older copy of the config may
|
|
24
|
+
* still name.
|
|
25
|
+
*/
|
|
26
|
+
moved: Map<string, string>;
|
|
27
|
+
/** Custom fields a suffixed row held another value for than its listing's row did: kept on the suffixed row. */
|
|
28
|
+
keptCustom: Array<{ from: string; into: string; fields: string[] }>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isFiled(metadata: TickerMetadata): boolean {
|
|
32
|
+
return metadata.portfolios.length > 0 || metadata.watchlists.length > 0 || metadata.positions.length > 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A broker's row: the broker keys what it reports, and its next sync writes there again. */
|
|
36
|
+
function isBrokerRow(metadata: TickerMetadata): boolean {
|
|
37
|
+
return (metadata.broker_contracts ?? []).length > 0 || metadata.positions.some((position) => position.broker !== "manual");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function union(left: readonly string[], right: readonly string[]): string[] {
|
|
41
|
+
return [...new Set([...left, ...right])];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isEmptyValue(value: unknown): boolean {
|
|
45
|
+
return value == null || (typeof value === "string" && value.trim() === "");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The listing's custom fields with the suffixed row's: the listing's value
|
|
50
|
+
* where it has one, else the suffixed row's. A field both hold with other
|
|
51
|
+
* values keeps the listing's, and the suffixed row's value stays with it.
|
|
52
|
+
*/
|
|
53
|
+
function mergeCustom(listing: Record<string, unknown>, suffixed: Record<string, unknown>) {
|
|
54
|
+
const custom = { ...listing };
|
|
55
|
+
const kept: Record<string, unknown> = {};
|
|
56
|
+
for (const [field, value] of Object.entries(suffixed)) {
|
|
57
|
+
if (isEmptyValue(value)) continue;
|
|
58
|
+
if (isEmptyValue(custom[field])) custom[field] = value;
|
|
59
|
+
else if (JSON.stringify(custom[field]) !== JSON.stringify(value)) kept[field] = value;
|
|
60
|
+
}
|
|
61
|
+
return { custom, kept };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The key of a listing's row (SYMBOL on VENUE): the row saved there already,
|
|
66
|
+
* under the bare symbol or a venue key, else, when `create`, the venue's key
|
|
67
|
+
* (GARAN:BIST, SHOP:XTSE). A merge never takes the bare key, so typing SHOP
|
|
68
|
+
* still means the US listing. Null when there is none to take, or the
|
|
69
|
+
* venue's key holds another venue's row.
|
|
70
|
+
*/
|
|
71
|
+
function listingKey(
|
|
72
|
+
symbol: string,
|
|
73
|
+
exchange: string,
|
|
74
|
+
rows: ReadonlyMap<string, TickerRecord>,
|
|
75
|
+
keysBySymbol: ReadonlyMap<string, readonly string[]>,
|
|
76
|
+
create: boolean,
|
|
77
|
+
): string | null {
|
|
78
|
+
const onVenue = (key: string) => canonicalExchange(rows.get(key)?.metadata.exchange) === exchange;
|
|
79
|
+
const venueKey = publicTickerKey(symbol, exchange);
|
|
80
|
+
if (onVenue(symbol)) return symbol;
|
|
81
|
+
if (onVenue(venueKey)) return venueKey;
|
|
82
|
+
const named = keysBySymbol.get(symbol)?.find((key) => !!parsePublicTickerKey(key).exchange && onVenue(key));
|
|
83
|
+
if (named) return named;
|
|
84
|
+
return create && !rows.has(venueKey) ? venueKey : null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Rows a portfolio or watchlist holds under a vendor's suffixed key (GARAN.IS
|
|
89
|
+
* on BIST) merged into their listing's own row (GARAN on BIST), which is made
|
|
90
|
+
* when there is none (`listingKey`): memberships, tags and custom fields
|
|
91
|
+
* (`mergeCustom`) join, and lots are added, each once: the listing's row
|
|
92
|
+
* records what it took (`mergedLots`), so a copy sync brings back is not
|
|
93
|
+
* counted twice. The suffixed row stays, emptied, for a link or a layout that
|
|
94
|
+
* names it. A broker's row is the broker's to key and stays as it is, and so
|
|
95
|
+
* does a suffix no saved venue confirms (`listingSuffixVenue`: MKC.V on NYSE
|
|
96
|
+
* is a share class). Null when no suffixed row has a listing's row.
|
|
97
|
+
*/
|
|
98
|
+
export function mergeSuffixedListings(tickers: readonly TickerRecord[]): SuffixedListingMerge | null {
|
|
99
|
+
const rows = new Map(tickers.map((ticker) => [ticker.metadata.ticker, ticker] as const));
|
|
100
|
+
const keysBySymbol = new Map<string, string[]>();
|
|
101
|
+
const index = (key: string) => {
|
|
102
|
+
const { symbol } = parsePublicTickerKey(key);
|
|
103
|
+
keysBySymbol.set(symbol, [...keysBySymbol.get(symbol) ?? [], key]);
|
|
104
|
+
};
|
|
105
|
+
for (const key of rows.keys()) index(key);
|
|
106
|
+
const listings = new Set<string>();
|
|
107
|
+
const emptied = new Set<string>();
|
|
108
|
+
const moved = new Map<string, string>();
|
|
109
|
+
const keptCustom: SuffixedListingMerge["keptCustom"] = [];
|
|
110
|
+
for (const { metadata: suffixed } of tickers) {
|
|
111
|
+
if (isBrokerRow(suffixed)) continue;
|
|
112
|
+
const parsed = parsePublicTickerKey(suffixed.ticker);
|
|
113
|
+
if (!tickerHasListingSuffix(parsed.symbol)) continue;
|
|
114
|
+
const venue = listingSuffixVenue(parsed.symbol, parsed.exchange ?? suffixed.exchange);
|
|
115
|
+
if (!venue) continue;
|
|
116
|
+
const filed = isFiled(suffixed);
|
|
117
|
+
const key = listingKey(venue.symbol, venue.exchange, rows, keysBySymbol, filed);
|
|
118
|
+
if (!key) continue;
|
|
119
|
+
moved.set(suffixed.ticker, key);
|
|
120
|
+
if (!filed) continue;
|
|
121
|
+
const existing = rows.get(key)?.metadata;
|
|
122
|
+
if (!existing) index(key);
|
|
123
|
+
const { mergedLots: _lots, broker_contracts: _contracts, ...rest } = suffixed;
|
|
124
|
+
const listing: TickerMetadata = existing ?? {
|
|
125
|
+
...rest, ticker: key, exchange: venue.exchange, portfolios: [], watchlists: [], positions: [], tags: [], custom: {},
|
|
126
|
+
};
|
|
127
|
+
// Lots the listing's row took from this key before count once: a copy brought back is not added again.
|
|
128
|
+
const taken = [...listing.mergedLots?.[suffixed.ticker] ?? []];
|
|
129
|
+
const unseen = [...taken];
|
|
130
|
+
const added: TickerPosition[] = [];
|
|
131
|
+
for (const lot of suffixed.positions) {
|
|
132
|
+
const fingerprint = lotFingerprint(lot);
|
|
133
|
+
const seen = unseen.indexOf(fingerprint);
|
|
134
|
+
if (seen >= 0) {
|
|
135
|
+
unseen.splice(seen, 1);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
added.push(lot);
|
|
139
|
+
taken.push(fingerprint);
|
|
140
|
+
}
|
|
141
|
+
const { custom, kept } = mergeCustom(listing.custom, suffixed.custom);
|
|
142
|
+
if (Object.keys(kept).length > 0) keptCustom.push({ from: suffixed.ticker, into: key, fields: Object.keys(kept) });
|
|
143
|
+
rows.set(key, {
|
|
144
|
+
metadata: {
|
|
145
|
+
...listing,
|
|
146
|
+
name: listing.name || suffixed.name,
|
|
147
|
+
currency: listing.currency || suffixed.currency,
|
|
148
|
+
portfolios: union(listing.portfolios, [...suffixed.portfolios, ...added.map((lot) => lot.portfolio)]),
|
|
149
|
+
watchlists: union(listing.watchlists, suffixed.watchlists),
|
|
150
|
+
positions: [...listing.positions, ...added],
|
|
151
|
+
tags: union(listing.tags, suffixed.tags),
|
|
152
|
+
custom,
|
|
153
|
+
...taken.length > 0 ? { mergedLots: { ...listing.mergedLots, [suffixed.ticker]: taken } } : {},
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
rows.set(suffixed.ticker, { metadata: { ...suffixed, portfolios: [], watchlists: [], positions: [], tags: [], custom: kept } });
|
|
157
|
+
listings.add(key);
|
|
158
|
+
emptied.add(suffixed.ticker);
|
|
159
|
+
}
|
|
160
|
+
if (moved.size === 0) return null;
|
|
161
|
+
// The listings' rows first: saved in this order, a stop between them loses nothing.
|
|
162
|
+
return { saves: [...listings, ...emptied].map((key) => rows.get(key)!), moved, keptCustom };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* The config with each portfolio's target for a suffixed key moved to its
|
|
167
|
+
* listing's row, added to any target that row had: the two rows' share of
|
|
168
|
+
* the portfolio is one listing's. The same config when no target moved.
|
|
169
|
+
*/
|
|
170
|
+
export function moveTargetWeights(config: AppConfig, moved: ReadonlyMap<string, string>): AppConfig {
|
|
171
|
+
let changed = false;
|
|
172
|
+
const portfolios = config.portfolios.map((portfolio) => {
|
|
173
|
+
const targets = portfolio.targetWeights;
|
|
174
|
+
if (!targets || ![...moved.keys()].some((key) => key in targets)) return portfolio;
|
|
175
|
+
const next = { ...targets };
|
|
176
|
+
for (const [from, to] of moved) {
|
|
177
|
+
if (!(from in next)) continue;
|
|
178
|
+
next[to] = (next[to] ?? 0) + next[from]!;
|
|
179
|
+
delete next[from];
|
|
180
|
+
}
|
|
181
|
+
changed = true;
|
|
182
|
+
return { ...portfolio, targetWeights: next };
|
|
183
|
+
});
|
|
184
|
+
return changed ? { ...config, portfolios } : config;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* `mergeSuffixedListings` for a saved profile: the config with its targets
|
|
189
|
+
* moved is saved first, then the rows, the listings' before the ones they
|
|
190
|
+
* took from, so a stop at any point leaves nothing a second run does not
|
|
191
|
+
* finish. The profile comes back as it now is; null when nothing changed.
|
|
192
|
+
*/
|
|
193
|
+
export async function mergeSavedSuffixedListings(
|
|
194
|
+
tickers: readonly TickerRecord[],
|
|
195
|
+
config: AppConfig,
|
|
196
|
+
save: { config: (config: AppConfig) => Promise<void>; tickers: (rows: TickerRecord[]) => Promise<void> },
|
|
197
|
+
): Promise<{ tickers: TickerRecord[]; config: AppConfig; keptCustom: SuffixedListingMerge["keptCustom"] } | null> {
|
|
198
|
+
const merge = mergeSuffixedListings(tickers);
|
|
199
|
+
if (!merge) return null;
|
|
200
|
+
const nextConfig = moveTargetWeights(config, merge.moved);
|
|
201
|
+
if (merge.saves.length === 0 && nextConfig === config) return null;
|
|
202
|
+
if (nextConfig !== config) await save.config(nextConfig);
|
|
203
|
+
if (merge.saves.length > 0) await save.tickers(merge.saves);
|
|
204
|
+
const saved = new Map(merge.saves.map((row) => [row.metadata.ticker, row] as const));
|
|
205
|
+
const kept = tickers.map((ticker) => saved.get(ticker.metadata.ticker) ?? ticker);
|
|
206
|
+
const keys = new Set(tickers.map((ticker) => ticker.metadata.ticker));
|
|
207
|
+
const added = merge.saves.filter((row) => !keys.has(row.metadata.ticker));
|
|
208
|
+
return { tickers: [...kept, ...added], config: nextConfig, keptCustom: merge.keptCustom };
|
|
209
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Portfolio } from "../types/ticker";
|
|
2
|
+
import { isManualPortfolio } from "./mutations";
|
|
3
|
+
|
|
4
|
+
const CURRENCY_CODE = /^[A-Z]{3}$/;
|
|
5
|
+
|
|
6
|
+
function currencyCode(value: string | undefined): string | null {
|
|
7
|
+
const code = value?.trim().toUpperCase() ?? "";
|
|
8
|
+
return CURRENCY_CODE.test(code) ? code : null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The currency a portfolio's totals, market values and P&L are in. A broker
|
|
13
|
+
* portfolio uses its account currency, and a manual one created in a
|
|
14
|
+
* currency that currency. Another manual portfolio uses its stored currency
|
|
15
|
+
* with the default USD base (its first holding sets it, see
|
|
16
|
+
* adoptFirstPositionCurrency); a base currency the user chose is what manual
|
|
17
|
+
* portfolios and watchlists total in.
|
|
18
|
+
*/
|
|
19
|
+
export function resolvePortfolioTotalsCurrency(portfolio: Portfolio | null | undefined, baseCurrency: string): string {
|
|
20
|
+
const base = currencyCode(baseCurrency) ?? "USD";
|
|
21
|
+
if (!portfolio) return base;
|
|
22
|
+
if (isManualPortfolio(portfolio) && !portfolio.fixedCurrency && base !== "USD") return base;
|
|
23
|
+
return currencyCode(portfolio.currency) ?? base;
|
|
24
|
+
}
|
|
@@ -44,7 +44,9 @@ exports[`the runtime exports of every public subpath are the reviewed ones 1`] =
|
|
|
44
44
|
"BulletList",
|
|
45
45
|
"Button",
|
|
46
46
|
"ButtonActionScope",
|
|
47
|
+
"COUNTRY_FLAG_CELLS",
|
|
47
48
|
"Card",
|
|
49
|
+
"ChartRead",
|
|
48
50
|
"ChartStrip",
|
|
49
51
|
"ChartTableHeader",
|
|
50
52
|
"Checkbox",
|
|
@@ -53,6 +55,8 @@ exports[`the runtime exports of every public subpath are the reviewed ones 1`] =
|
|
|
53
55
|
"ColumnGridPair",
|
|
54
56
|
"CompositeChart",
|
|
55
57
|
"ConfirmDialog",
|
|
58
|
+
"CountryFlag",
|
|
59
|
+
"CountryFlagLead",
|
|
56
60
|
"CurveSurface",
|
|
57
61
|
"DELAYED_SEGMENT",
|
|
58
62
|
"DataTable",
|
|
@@ -168,6 +172,7 @@ exports[`the runtime exports of every public subpath are the reviewed ones 1`] =
|
|
|
168
172
|
"statGridRows",
|
|
169
173
|
"staticSeries",
|
|
170
174
|
"unavailableText",
|
|
175
|
+
"useChartReadRows",
|
|
171
176
|
"useChartTableLayout",
|
|
172
177
|
"useChartTableSelection",
|
|
173
178
|
"useExternalLinkFooter",
|
|
@@ -183,8 +188,11 @@ exports[`the runtime exports of every public subpath are the reviewed ones 1`] =
|
|
|
183
188
|
"usePaneTabs",
|
|
184
189
|
"usePaneTicker",
|
|
185
190
|
"useQueryBarSearch",
|
|
191
|
+
"useRowNotes",
|
|
186
192
|
"useTableLoadMore",
|
|
187
193
|
"useTickerRowPaneMenu",
|
|
194
|
+
"withCountryFlag",
|
|
195
|
+
"withFlagRoom",
|
|
188
196
|
],
|
|
189
197
|
"./dialog": [
|
|
190
198
|
"DialogHostProvider",
|
|
@@ -383,6 +391,9 @@ exports[`the runtime exports of every public subpath are the reviewed ones 1`] =
|
|
|
383
391
|
"SERIES_FREQUENCIES",
|
|
384
392
|
"TIME_RANGES",
|
|
385
393
|
"TIME_RANGE_ORDER",
|
|
394
|
+
"aggregatePriceBars",
|
|
395
|
+
"chartBarSizeSource",
|
|
396
|
+
"chartBarSizeStepMs",
|
|
386
397
|
"clampTimeRangeToMaxRange",
|
|
387
398
|
"defineSeries",
|
|
388
399
|
"describeSeriesUnits",
|
|
@@ -396,11 +407,14 @@ exports[`the runtime exports of every public subpath are the reviewed ones 1`] =
|
|
|
396
407
|
"getSupportedPresetResolution",
|
|
397
408
|
"inferSeriesFrequency",
|
|
398
409
|
"intersectChartResolutionSupport",
|
|
410
|
+
"isChartResolution",
|
|
399
411
|
"isIntradayResolution",
|
|
412
|
+
"isManualChartResolution",
|
|
400
413
|
"isRangePresetSupported",
|
|
401
414
|
"isValidSeriesUnit",
|
|
402
415
|
"normalizeChartResolution",
|
|
403
416
|
"normalizeChartResolutionSupport",
|
|
417
|
+
"parseChartBarSize",
|
|
404
418
|
"parseSeriesCsv",
|
|
405
419
|
"sortChartResolutions",
|
|
406
420
|
"validateSeriesDefinition",
|
|
@@ -11,19 +11,22 @@ export {
|
|
|
11
11
|
CHART_RESOLUTIONS, TIME_RANGES,
|
|
12
12
|
} from "../time-series/range";
|
|
13
13
|
export type {
|
|
14
|
-
ChartDateWindow, ChartResolution, TimeRange,
|
|
14
|
+
ChartBarSizeUnit, ChartDateWindow, ChartResolution, CustomChartResolution, TimeRange,
|
|
15
15
|
} from "../time-series/range";
|
|
16
16
|
export {
|
|
17
|
-
CHART_RESOLUTION_STEP_MS,
|
|
18
|
-
getBestSupportedResolutionForVisibleWindow, getChartResolutionLabel,
|
|
19
|
-
getNextBufferRange, getPresetResolution, getSupportedChartResolutionsForViewport,
|
|
20
|
-
getSupportedPresetResolution, getSupportMaxRange, intersectChartResolutionSupport,
|
|
21
|
-
isIntradayResolution, isRangePresetSupported, normalizeChartResolution,
|
|
22
|
-
normalizeChartResolutionSupport, sortChartResolutions, TIME_RANGE_ORDER,
|
|
17
|
+
CHART_RESOLUTION_STEP_MS, chartBarSizeSource, chartBarSizeStepMs, clampTimeRangeToMaxRange,
|
|
18
|
+
DEFAULT_CHART_RESOLUTION_SUPPORT, getBestSupportedResolutionForVisibleWindow, getChartResolutionLabel,
|
|
19
|
+
getExpandedBufferRange, getNextBufferRange, getPresetResolution, getSupportedChartResolutionsForViewport,
|
|
20
|
+
getSupportedPresetResolution, getSupportMaxRange, intersectChartResolutionSupport, isChartResolution,
|
|
21
|
+
isIntradayResolution, isManualChartResolution, isRangePresetSupported, normalizeChartResolution,
|
|
22
|
+
normalizeChartResolutionSupport, parseChartBarSize, sortChartResolutions, TIME_RANGE_ORDER,
|
|
23
23
|
} from "../time-series/resolution";
|
|
24
24
|
export type {
|
|
25
|
-
ChartResolutionSupport, ManualChartResolution,
|
|
25
|
+
ChartBarSize, ChartResolutionSupport, ManualChartResolution,
|
|
26
26
|
} from "../time-series/resolution";
|
|
27
|
+
// Bars of a size the source does not serve, built from its shorter ones the way the chart builds them.
|
|
28
|
+
export { aggregatePriceBars } from "../time-series/bar-aggregation";
|
|
29
|
+
export type { AggregatedPricePoint, BarAggregationListing } from "../time-series/bar-aggregation";
|
|
27
30
|
|
|
28
31
|
// The resolved shape itself: what a chart-series capability returns and what
|
|
29
32
|
// the composite chart draws. A plugin that answers `chartSeriesProvider`
|
package/src/remote/schema.ts
CHANGED
|
@@ -375,7 +375,7 @@ export const REMOTE_OPERATIONS: RemoteOperationSchema[] = [
|
|
|
375
375
|
];
|
|
376
376
|
|
|
377
377
|
export const REMOTE_AGENT_HELP = {
|
|
378
|
-
title: "
|
|
378
|
+
title: "Gloom remote control guide",
|
|
379
379
|
quickStart: [
|
|
380
380
|
"Read app://snapshot once to orient; it includes schema, current layout, panes, command bar state, and semantic UI nodes.",
|
|
381
381
|
"Prefer app-level operations such as app.search, layout.setGrid, layout.closeFloating, and ticker.pin before falling back to ui.invoke.",
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "../../types/config";
|
|
17
17
|
import { researchEntryFromSearch } from "./research-entry";
|
|
18
18
|
import { BROWSER_STORAGE_KEYS, SafeJsonStorage, type StorageLike } from "../../data/json-storage";
|
|
19
|
+
import { stopBootFrameRecorders } from "../dom/boot-frame";
|
|
19
20
|
|
|
20
21
|
export const BROWSER_DATA_DIR = "browser://local";
|
|
21
22
|
|
|
@@ -168,6 +169,8 @@ export function createBrowserConfigStore(storage: StorageLike, search = ""): Con
|
|
|
168
169
|
return config;
|
|
169
170
|
},
|
|
170
171
|
async resetAllData(dataDir) {
|
|
172
|
+
// Before the keys go, or the frame saved as the page closes would bring the old layout back.
|
|
173
|
+
stopBootFrameRecorders();
|
|
171
174
|
for (const key of Object.values(BROWSER_STORAGE_KEYS)) {
|
|
172
175
|
try { storage.removeItem(key); } catch {}
|
|
173
176
|
}
|
|
@@ -9,6 +9,8 @@ import { getBrowserPlugins } from "../../plugins/catalog-browser";
|
|
|
9
9
|
import { DomErrorBoundary, DomHostProviders } from "../dom/dom-host-providers";
|
|
10
10
|
import { installFocusScopeRelease } from "../dom/host/focus-scope";
|
|
11
11
|
import { installDomMarketDataFrames } from "../dom/data-frames";
|
|
12
|
+
import { releaseBootFrameWhenDrawn, startBootFrameRecorder } from "../dom/boot-frame";
|
|
13
|
+
import { BROWSER_STORAGE_KEYS } from "../../data/json-storage";
|
|
12
14
|
import { createBrowserAppServices } from "./app-services";
|
|
13
15
|
import {
|
|
14
16
|
installBrowserFetchTransports,
|
|
@@ -69,7 +71,11 @@ if (!rootElement) throw new Error("Missing root element");
|
|
|
69
71
|
const appRootElement = rootElement;
|
|
70
72
|
appRootElement.tabIndex = -1;
|
|
71
73
|
const root = createRoot(appRootElement);
|
|
72
|
-
|
|
74
|
+
// The page drew the last session's layout, or the bare shell, before this
|
|
75
|
+
// script loaded (dom/boot-frame.ts); it stays until the app has drawn its own.
|
|
76
|
+
const releaseBootFrame = releaseBootFrameWhenDrawn(document, appRootElement);
|
|
77
|
+
/** How long after the app mounts the launch frame stays at most. */
|
|
78
|
+
const BOOT_FRAME_RELEASE_FALLBACK_MS = 4_000;
|
|
73
79
|
|
|
74
80
|
async function boot(): Promise<void> {
|
|
75
81
|
// Read before anything can save a workspace or tidy the address.
|
|
@@ -145,7 +151,7 @@ async function boot(): Promise<void> {
|
|
|
145
151
|
root.render(
|
|
146
152
|
<DomErrorBoundary label="Browser renderer crashed" fallback={(error) => (
|
|
147
153
|
<div className="gloom-fatal">
|
|
148
|
-
<h1>
|
|
154
|
+
<h1>Gloom crashed</h1>
|
|
149
155
|
<pre>{error instanceof Error ? error.message : String(error)}</pre>
|
|
150
156
|
<button onClick={() => window.location.reload()}>Reload</button>
|
|
151
157
|
</div>
|
|
@@ -163,10 +169,24 @@ async function boot(): Promise<void> {
|
|
|
163
169
|
</DomErrorBoundary>,
|
|
164
170
|
);
|
|
165
171
|
appRootElement.focus({ preventScroll: true });
|
|
172
|
+
// A layout with neither panes nor a status bar has nothing to wait for.
|
|
173
|
+
window.setTimeout(releaseBootFrame, BOOT_FRAME_RELEASE_FALLBACK_MS);
|
|
174
|
+
startBootFrameRecorder({
|
|
175
|
+
doc: document,
|
|
176
|
+
root: appRootElement,
|
|
177
|
+
save: (frame) => {
|
|
178
|
+
try {
|
|
179
|
+
localStorage.setItem(BROWSER_STORAGE_KEYS.bootFrame, JSON.stringify(frame));
|
|
180
|
+
} catch {
|
|
181
|
+
// Intentional ignore: storage full or blocked; the next launch draws the bare shell.
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
});
|
|
166
185
|
}
|
|
167
186
|
|
|
168
187
|
void boot().catch((error) => {
|
|
169
188
|
reportCrash(error, { kind: "uncaught" });
|
|
170
189
|
const message = error instanceof Error ? error.message : String(error);
|
|
171
|
-
|
|
190
|
+
releaseBootFrame();
|
|
191
|
+
root.render(<div className="gloom-fatal"><h1>Gloom failed to start</h1><pre>{message}</pre></div>);
|
|
172
192
|
});
|