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,3 +1,5 @@
|
|
|
1
|
+
import { readdir, rm } from "fs/promises";
|
|
2
|
+
import { basename, dirname, join } from "path";
|
|
1
3
|
import type Electrobun from "electrobun/bun";
|
|
2
4
|
import type { UpdateStatusEntry } from "electrobun/bun";
|
|
3
5
|
import type { UpdateChannel } from "../../../../types/config";
|
|
@@ -15,6 +17,20 @@ import {
|
|
|
15
17
|
type GitHubReleaseListing,
|
|
16
18
|
} from "../../../../updater/github-releases";
|
|
17
19
|
import { stagedUpdateFitsChannel } from "../../../../updater/channel";
|
|
20
|
+
import {
|
|
21
|
+
classifyUpdateError,
|
|
22
|
+
httpStatusFailureCode,
|
|
23
|
+
type UpdateFailure,
|
|
24
|
+
type UpdateFailureCode,
|
|
25
|
+
} from "../../../../updater/failure";
|
|
26
|
+
import {
|
|
27
|
+
forgetStagedUpdate,
|
|
28
|
+
noteUpdateApplying,
|
|
29
|
+
noteUpdateStaged,
|
|
30
|
+
reportUpdateFailure,
|
|
31
|
+
type UpdateInstallKind,
|
|
32
|
+
} from "../../../../telemetry/update-failures";
|
|
33
|
+
import { logFailure } from "../../../../utils/log-failure";
|
|
18
34
|
import { compareSemver, isPrereleaseVersion } from "../../../../utils/semver";
|
|
19
35
|
import { VERSION } from "../../../../version";
|
|
20
36
|
|
|
@@ -27,7 +43,14 @@ type ElectrobunUpdater = typeof Electrobun.Updater;
|
|
|
27
43
|
*/
|
|
28
44
|
export type ElectrobunUpdaterApi = Pick<
|
|
29
45
|
ElectrobunUpdater,
|
|
30
|
-
|
|
46
|
+
| "checkForUpdate"
|
|
47
|
+
| "downloadUpdate"
|
|
48
|
+
| "applyUpdate"
|
|
49
|
+
| "updateInfo"
|
|
50
|
+
| "clearStatusHistory"
|
|
51
|
+
| "getStatusHistory"
|
|
52
|
+
| "onStatusChange"
|
|
53
|
+
| "setUpdateSource"
|
|
31
54
|
> & {
|
|
32
55
|
localInfo: Pick<ElectrobunUpdater["localInfo"], "channel" | "baseUrl">;
|
|
33
56
|
};
|
|
@@ -37,12 +60,111 @@ type ListReleases = () => Promise<GitHubReleaseListing[]>;
|
|
|
37
60
|
|
|
38
61
|
const NIGHTLY_RELEASE_WINDOW = 30;
|
|
39
62
|
|
|
63
|
+
/** A step that failed for a reason known where it was thrown. */
|
|
64
|
+
class DesktopUpdateError extends Error {
|
|
65
|
+
constructor(message: string, readonly code: UpdateFailureCode) {
|
|
66
|
+
super(message);
|
|
67
|
+
this.name = "DesktopUpdateError";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** `<app>.previous` and `<app>.previous-<suffix>`: what an install moves the old app to. */
|
|
72
|
+
function isUpdateAside(entry: string, appName: string): boolean {
|
|
73
|
+
if (!entry.startsWith(`${appName}.previous`)) return false;
|
|
74
|
+
const rest = entry.slice(appName.length + ".previous".length);
|
|
75
|
+
return rest === "" || /^-[0-9a-z]+(?:-\d+)?$/.test(rest);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Removes the copies of the app an install moved aside and could not remove
|
|
80
|
+
* then (the Electrobun patch's `replaceAppBundle`), from beside the app this
|
|
81
|
+
* process runs from: starting from it means the install that left them worked.
|
|
82
|
+
* macOS keeps the app in its bundle, Linux in `<app data>/app` (`bin/bun`
|
|
83
|
+
* inside it); Windows installs through its own script and leaves none.
|
|
84
|
+
* Resolves to the paths it removed.
|
|
85
|
+
*/
|
|
86
|
+
export async function removeUpdateAsides(
|
|
87
|
+
execPath: string = process.execPath,
|
|
88
|
+
platform: string = process.platform,
|
|
89
|
+
): Promise<string[]> {
|
|
90
|
+
const app = platform === "darwin"
|
|
91
|
+
? /^(.*?\.app)\/Contents\/MacOS\/[^/]+$/.exec(execPath)?.[1]
|
|
92
|
+
: platform === "linux" && basename(dirname(execPath)) === "bin" ? dirname(dirname(execPath)) : undefined;
|
|
93
|
+
if (!app) return [];
|
|
94
|
+
const folder = dirname(app);
|
|
95
|
+
const removed: string[] = [];
|
|
96
|
+
for (const entry of await readdir(folder).catch(() => [] as string[])) {
|
|
97
|
+
if (!isUpdateAside(entry, basename(app))) continue;
|
|
98
|
+
const path = join(folder, entry);
|
|
99
|
+
// One that still cannot be removed (another user's) is tried again at the next start.
|
|
100
|
+
const done = await rm(path, { recursive: true, force: true }).then(() => true, logFailure("desktop-update", "Could not remove an old copy of the app", false));
|
|
101
|
+
if (done) removed.push(path);
|
|
102
|
+
}
|
|
103
|
+
return removed;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Where the running app sits, for update failure reports and for what an
|
|
108
|
+
* install that cannot replace it means. Electrobun replaces the macOS bundle
|
|
109
|
+
* the app runs from; on Windows and Linux it always installs into its own
|
|
110
|
+
* folder under the user's app data.
|
|
111
|
+
*/
|
|
112
|
+
export function detectDesktopInstallKind(
|
|
113
|
+
execPath: string = process.execPath,
|
|
114
|
+
platform: string = process.platform,
|
|
115
|
+
homeDir: string = process.env.HOME ?? "",
|
|
116
|
+
): UpdateInstallKind {
|
|
117
|
+
if (platform !== "darwin") return platform === "win32" || platform === "linux" ? "desktop-app-data" : "unknown";
|
|
118
|
+
const bundle = /^(.*?\.app)\/Contents\//.exec(execPath)?.[1];
|
|
119
|
+
if (!bundle) return "unknown";
|
|
120
|
+
if (bundle.includes("/AppTranslocation/")) return "desktop-translocated";
|
|
121
|
+
if (bundle.startsWith("/Volumes/")) return "desktop-volume";
|
|
122
|
+
if (bundle.startsWith("/Applications/") || (homeDir && bundle.startsWith(`${homeDir}/Applications/`))) return "desktop-applications";
|
|
123
|
+
return "desktop-elsewhere";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* On macOS a bundle that cannot be replaced where it runs (a disk image, the
|
|
128
|
+
* read-only copy App Translocation runs, another volume) is fixed by moving
|
|
129
|
+
* the app to Applications, which is what the header then says. Anywhere else
|
|
130
|
+
* a move across disks keeps its own reason: from Applications, moving the app
|
|
131
|
+
* again would not help.
|
|
132
|
+
*/
|
|
133
|
+
function installFailureCode(code: UpdateFailureCode, installKind: UpdateInstallKind): UpdateFailureCode {
|
|
134
|
+
const movable = installKind === "desktop-translocated" || installKind === "desktop-volume";
|
|
135
|
+
if (movable && (code === "permission_denied" || code === "read_only" || code === "wrong_location" || code === "cross_device")) return "wrong_location";
|
|
136
|
+
return code;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Why Electrobun's check failed. It returns one message for every failure, so
|
|
141
|
+
* the status it emitted just before says whether the server answered (with
|
|
142
|
+
* which status) or could not be reached.
|
|
143
|
+
*/
|
|
144
|
+
function checkFailureCode(error: string, history: UpdateStatusEntry[]): UpdateFailureCode {
|
|
145
|
+
const last = history.at(-1);
|
|
146
|
+
const status = last?.status === "error" ? /HTTP (\d{3})/.exec(last.message)?.[1] : undefined;
|
|
147
|
+
if (status) return httpStatusFailureCode(Number(status));
|
|
148
|
+
if (/Invalid update\.json/i.test(error)) return "bad_response";
|
|
149
|
+
const code = classifyUpdateError(error);
|
|
150
|
+
// "Failed to fetch update info" with no status before it: the request itself threw.
|
|
151
|
+
return code === "unknown" ? "offline" : code;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Why a download that Electrobun returned from did not leave an update ready. */
|
|
155
|
+
function downloadFailureCode(error: string, lastErrorStatus: UpdateStatusEntry | null): UpdateFailure {
|
|
156
|
+
if (/zstd/i.test(error)) return { phase: "verify", code: "corrupt" };
|
|
157
|
+
if (lastErrorStatus?.message.startsWith("Failed to download:")) return { phase: "download", code: "http_error" };
|
|
158
|
+
const code = classifyUpdateError(error);
|
|
159
|
+
return { phase: "download", code: code === "unknown" ? "interrupted" : code };
|
|
160
|
+
}
|
|
161
|
+
|
|
40
162
|
async function listGitHubReleases(): Promise<GitHubReleaseListing[]> {
|
|
41
163
|
const response = await fetch(`${GITHUB_RELEASES_API_URL}?per_page=${NIGHTLY_RELEASE_WINDOW}`, {
|
|
42
164
|
headers: { Accept: "application/vnd.github+json" },
|
|
43
165
|
signal: AbortSignal.timeout(10_000),
|
|
44
166
|
});
|
|
45
|
-
if (!response.ok) throw new
|
|
167
|
+
if (!response.ok) throw new DesktopUpdateError(`GitHub returned ${response.status}`, httpStatusFailureCode(response.status));
|
|
46
168
|
const data: unknown = await response.json();
|
|
47
169
|
if (!Array.isArray(data)) throw new Error("GitHub returned an unexpected releases payload");
|
|
48
170
|
return data as GitHubReleaseListing[];
|
|
@@ -88,6 +210,12 @@ function hasDesktopManifest(release: GitHubReleaseListing): boolean {
|
|
|
88
210
|
return release.assets?.some((asset) => asset.name === manifest) === true;
|
|
89
211
|
}
|
|
90
212
|
|
|
213
|
+
/**
|
|
214
|
+
* The progress an Electrobun status means. An `error` status is left to the
|
|
215
|
+
* caller: during a download Electrobun emits some it recovers from (a patch
|
|
216
|
+
* that does not apply falls back to the full download), so only the outcome
|
|
217
|
+
* says whether the download failed.
|
|
218
|
+
*/
|
|
91
219
|
function mapDesktopUpdateStatus(entry: UpdateStatusEntry): UpdateProgress | null {
|
|
92
220
|
const progress = entry.details?.progress;
|
|
93
221
|
switch (entry.status) {
|
|
@@ -120,11 +248,6 @@ function mapDesktopUpdateStatus(entry: UpdateStatusEntry): UpdateProgress | null
|
|
|
120
248
|
// once `updateInfo().updateReady` confirms it.
|
|
121
249
|
case "complete":
|
|
122
250
|
return { phase: "done", message: "Update installed, restarting..." };
|
|
123
|
-
case "error":
|
|
124
|
-
return {
|
|
125
|
-
phase: "error",
|
|
126
|
-
error: entry.details?.errorMessage || entry.message,
|
|
127
|
-
};
|
|
128
251
|
default:
|
|
129
252
|
return null;
|
|
130
253
|
}
|
|
@@ -133,9 +256,12 @@ function mapDesktopUpdateStatus(entry: UpdateStatusEntry): UpdateProgress | null
|
|
|
133
256
|
export function createElectrobunDesktopUpdater(
|
|
134
257
|
updater: ElectrobunUpdaterApi,
|
|
135
258
|
{
|
|
259
|
+
installKind = detectDesktopInstallKind(),
|
|
136
260
|
listReleases = listGitHubReleases,
|
|
137
261
|
runningVersion = VERSION,
|
|
138
262
|
}: {
|
|
263
|
+
/** Where the app runs from, which an install that cannot replace it is blamed on. */
|
|
264
|
+
installKind?: UpdateInstallKind;
|
|
139
265
|
listReleases?: ListReleases;
|
|
140
266
|
/** The version of the installed app, which a download checks as. */
|
|
141
267
|
runningVersion?: string;
|
|
@@ -152,6 +278,15 @@ export function createElectrobunDesktopUpdater(
|
|
|
152
278
|
/** An apply is under way, or finished and the app is quitting. */
|
|
153
279
|
let applyInProgress = false;
|
|
154
280
|
|
|
281
|
+
/** The error progress for a failed step, reported to error tracking on the way. */
|
|
282
|
+
function failed(failure: UpdateFailure, error: string, release?: { version?: string; channel?: UpdateChannel } | null): UpdateProgress {
|
|
283
|
+
reportUpdateFailure(failure, {
|
|
284
|
+
targetVersion: release?.version,
|
|
285
|
+
channel: release?.channel === "nightly" ? "nightly" : "stable",
|
|
286
|
+
});
|
|
287
|
+
return { phase: "error", error, failure };
|
|
288
|
+
}
|
|
289
|
+
|
|
155
290
|
/**
|
|
156
291
|
* Forgets a downloaded update `updateChannel` does not allow: a nightly
|
|
157
292
|
* build staged before the switch back to stable. Electrobun's own ready
|
|
@@ -159,7 +294,10 @@ export function createElectrobunDesktopUpdater(
|
|
|
159
294
|
* a restart cannot install it, and its files go with the next download.
|
|
160
295
|
*/
|
|
161
296
|
function dropStagedMisfit(updateChannel: UpdateChannel): void {
|
|
162
|
-
if (readyRelease && !applyInProgress && !stagedUpdateFitsChannel(readyRelease, updateChannel))
|
|
297
|
+
if (readyRelease && !applyInProgress && !stagedUpdateFitsChannel(readyRelease, updateChannel)) {
|
|
298
|
+
readyRelease = null;
|
|
299
|
+
forgetStagedUpdate();
|
|
300
|
+
}
|
|
163
301
|
}
|
|
164
302
|
|
|
165
303
|
async function releaseInfo(updateInfo: { version?: string; hash?: string }, currentVersion: string): Promise<ReleaseInfo> {
|
|
@@ -177,6 +315,13 @@ export function createElectrobunDesktopUpdater(
|
|
|
177
315
|
};
|
|
178
316
|
}
|
|
179
317
|
|
|
318
|
+
/** Electrobun's check, with the failure it ended in named. */
|
|
319
|
+
async function checkElectrobun(): Promise<Awaited<ReturnType<ElectrobunUpdaterApi["checkForUpdate"]>> | { error: string; code: UpdateFailureCode }> {
|
|
320
|
+
const info = await updater.checkForUpdate();
|
|
321
|
+
if (!info.error) return info;
|
|
322
|
+
return { error: info.error, code: checkFailureCode(info.error, updater.getStatusHistory()) };
|
|
323
|
+
}
|
|
324
|
+
|
|
180
325
|
/**
|
|
181
326
|
* Nightly: the highest version among the newest releases that has this
|
|
182
327
|
* platform's desktop manifest, nightly or stable, fetched from that release's
|
|
@@ -192,8 +337,8 @@ export function createElectrobunDesktopUpdater(
|
|
|
192
337
|
const baseUrl = githubReleaseDownloadBaseUrl(target.tag_name);
|
|
193
338
|
updater.setUpdateSource({ channel: filesChannel, baseUrl });
|
|
194
339
|
|
|
195
|
-
const info = await
|
|
196
|
-
if (info
|
|
340
|
+
const info = await checkElectrobun();
|
|
341
|
+
if ("code" in info) throw new DesktopUpdateError(info.error, info.code);
|
|
197
342
|
// The same build as the one installed.
|
|
198
343
|
if (!info.updateAvailable) return { kind: "current" };
|
|
199
344
|
|
|
@@ -210,7 +355,11 @@ export function createElectrobunDesktopUpdater(
|
|
|
210
355
|
};
|
|
211
356
|
}
|
|
212
357
|
|
|
213
|
-
|
|
358
|
+
/**
|
|
359
|
+
* The check, without reporting: a download runs it first and reports what
|
|
360
|
+
* went wrong itself.
|
|
361
|
+
*/
|
|
362
|
+
async function checkQuietly(currentVersion: string, updateChannel: UpdateChannel): Promise<UpdateCheckResult> {
|
|
214
363
|
dropStagedMisfit(updateChannel);
|
|
215
364
|
// A downloaded update the channel still allows stays the answer until the
|
|
216
365
|
// user restarts into it, and asking Electrobun again would discard its
|
|
@@ -229,9 +378,9 @@ export function createElectrobunDesktopUpdater(
|
|
|
229
378
|
|
|
230
379
|
// Stable is the release version.json names, as it always was.
|
|
231
380
|
updater.setUpdateSource(null);
|
|
232
|
-
const info = await
|
|
233
|
-
if (info
|
|
234
|
-
return { kind: "error", error: info.error };
|
|
381
|
+
const info = await checkElectrobun();
|
|
382
|
+
if ("code" in info) {
|
|
383
|
+
return { kind: "error", error: info.error, failure: { phase: "check", code: info.code } };
|
|
235
384
|
}
|
|
236
385
|
if (!info.updateAvailable) {
|
|
237
386
|
return { kind: "current" };
|
|
@@ -247,13 +396,21 @@ export function createElectrobunDesktopUpdater(
|
|
|
247
396
|
release: await releaseInfo(info, currentVersion),
|
|
248
397
|
};
|
|
249
398
|
} catch (error) {
|
|
399
|
+
const code = error instanceof DesktopUpdateError ? error.code : classifyUpdateError(error);
|
|
250
400
|
return {
|
|
251
401
|
kind: "error",
|
|
252
402
|
error: error instanceof Error ? error.message : "Desktop update check failed",
|
|
403
|
+
failure: { phase: "check", code },
|
|
253
404
|
};
|
|
254
405
|
}
|
|
255
406
|
}
|
|
256
407
|
|
|
408
|
+
async function check(currentVersion: string, updateChannel: UpdateChannel = "stable"): Promise<UpdateCheckResult> {
|
|
409
|
+
const result = await checkQuietly(currentVersion, updateChannel);
|
|
410
|
+
if (result.kind === "error" && result.failure) reportUpdateFailure(result.failure, { channel: updateChannel });
|
|
411
|
+
return result;
|
|
412
|
+
}
|
|
413
|
+
|
|
257
414
|
async function download(
|
|
258
415
|
release: Pick<ReleaseInfo, "channel">,
|
|
259
416
|
onProgress: (progress: UpdateProgress) => void,
|
|
@@ -277,17 +434,25 @@ export function createElectrobunDesktopUpdater(
|
|
|
277
434
|
}
|
|
278
435
|
|
|
279
436
|
downloadInProgress = true;
|
|
437
|
+
/** The last error Electrobun emitted on the way, which may or may not have ended the download. */
|
|
438
|
+
let lastErrorStatus: UpdateStatusEntry | null = null;
|
|
439
|
+
/** The release the download is for, once the check has found it. */
|
|
440
|
+
let target: ReleaseInfo | null = null;
|
|
280
441
|
updater.clearStatusHistory();
|
|
281
442
|
updater.onStatusChange((entry) => {
|
|
443
|
+
if (entry.status === "error") {
|
|
444
|
+
lastErrorStatus = entry;
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
282
447
|
const progress = mapDesktopUpdateStatus(entry);
|
|
283
448
|
if (progress) onProgress(progress);
|
|
284
449
|
});
|
|
285
450
|
|
|
286
451
|
try {
|
|
287
452
|
onProgress({ phase: "downloading", percent: 0 });
|
|
288
|
-
const result = await
|
|
453
|
+
const result = await checkQuietly(runningVersion, updateChannel);
|
|
289
454
|
if (result.kind === "error") {
|
|
290
|
-
onProgress({ phase: "
|
|
455
|
+
onProgress(failed(result.failure ?? { phase: "check", code: "unknown" }, result.error, { channel: updateChannel }));
|
|
291
456
|
return;
|
|
292
457
|
}
|
|
293
458
|
if (result.kind !== "available") {
|
|
@@ -297,27 +462,31 @@ export function createElectrobunDesktopUpdater(
|
|
|
297
462
|
});
|
|
298
463
|
return;
|
|
299
464
|
}
|
|
465
|
+
target = result.release;
|
|
300
466
|
|
|
301
467
|
await updater.downloadUpdate();
|
|
302
468
|
const updateInfo = updater.updateInfo();
|
|
303
469
|
if (updateInfo?.error) {
|
|
304
|
-
onProgress(
|
|
470
|
+
onProgress(failed(downloadFailureCode(updateInfo.error, lastErrorStatus), updateInfo.error, result.release));
|
|
305
471
|
return;
|
|
306
472
|
}
|
|
307
473
|
if (!updateInfo?.updateReady) {
|
|
308
|
-
onProgress({ phase: "
|
|
474
|
+
onProgress(failed({ phase: "download", code: "interrupted" }, "Desktop update did not finish downloading.", result.release));
|
|
309
475
|
return;
|
|
310
476
|
}
|
|
311
477
|
|
|
312
478
|
// Downloaded, not installed: applying relaunches the app, and that waits
|
|
313
479
|
// for the user's explicit request (`apply`).
|
|
314
480
|
readyRelease = result.release;
|
|
481
|
+
noteUpdateStaged(result.release.version, updateChannel);
|
|
315
482
|
onProgress({ phase: "ready", canRestart: true });
|
|
316
483
|
} catch (error) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
484
|
+
const code = classifyUpdateError(error);
|
|
485
|
+
onProgress(failed(
|
|
486
|
+
{ phase: "download", code: code === "unknown" ? "interrupted" : code },
|
|
487
|
+
error instanceof Error ? error.message : "Desktop update failed",
|
|
488
|
+
{ version: target?.version, channel: updateChannel },
|
|
489
|
+
));
|
|
321
490
|
} finally {
|
|
322
491
|
downloadInProgress = false;
|
|
323
492
|
updater.onStatusChange(null);
|
|
@@ -327,11 +496,13 @@ export function createElectrobunDesktopUpdater(
|
|
|
327
496
|
async function apply(onProgress: (progress: UpdateProgress) => void): Promise<void> {
|
|
328
497
|
if (applyInProgress || downloadInProgress) return;
|
|
329
498
|
if (!readyRelease || !updater.updateInfo()?.updateReady) {
|
|
499
|
+
const missing = readyRelease;
|
|
330
500
|
readyRelease = null;
|
|
331
|
-
onProgress({ phase: "
|
|
501
|
+
onProgress(failed({ phase: "apply", code: "staged_missing" }, "The downloaded update is no longer available.", missing));
|
|
332
502
|
return;
|
|
333
503
|
}
|
|
334
504
|
|
|
505
|
+
const target = readyRelease;
|
|
335
506
|
applyInProgress = true;
|
|
336
507
|
let relaunching = false;
|
|
337
508
|
let reportedError = false;
|
|
@@ -339,7 +510,19 @@ export function createElectrobunDesktopUpdater(
|
|
|
339
510
|
if (progress.phase === "error") reportedError = true;
|
|
340
511
|
onProgress(progress);
|
|
341
512
|
};
|
|
513
|
+
const installFailed = (error: unknown, message: string) => {
|
|
514
|
+
// Electrobun names the system error in its message ("Failed to replace app: EACCES: ...").
|
|
515
|
+
const code = installFailureCode(classifyUpdateError(error), installKind);
|
|
516
|
+
report(failed({ phase: relaunching ? "relaunch" : "apply", code }, message, target));
|
|
517
|
+
};
|
|
518
|
+
// Kept before Electrobun quits the app, so the next launch can tell whether it took.
|
|
519
|
+
noteUpdateApplying(target.version, target.channel === "nightly" ? "nightly" : "stable");
|
|
342
520
|
updater.onStatusChange((entry) => {
|
|
521
|
+
if (entry.status === "error") {
|
|
522
|
+
const message = entry.details?.errorMessage || entry.message;
|
|
523
|
+
installFailed(message, message);
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
343
526
|
if (entry.status === "launching-new-version" || entry.status === "complete") relaunching = true;
|
|
344
527
|
const progress = mapDesktopUpdateStatus(entry);
|
|
345
528
|
if (progress) report(progress);
|
|
@@ -348,16 +531,13 @@ export function createElectrobunDesktopUpdater(
|
|
|
348
531
|
try {
|
|
349
532
|
report({ phase: "replacing" });
|
|
350
533
|
await updater.applyUpdate();
|
|
351
|
-
// Electrobun returns without a status when it
|
|
352
|
-
//
|
|
534
|
+
// Electrobun returns without a status when it finds nothing to install:
|
|
535
|
+
// the downloaded files are gone, or hold no app.
|
|
353
536
|
if (!relaunching && !reportedError) {
|
|
354
|
-
report({ phase: "
|
|
537
|
+
report(failed({ phase: "apply", code: "staged_missing" }, "Desktop update could not be installed.", target));
|
|
355
538
|
}
|
|
356
539
|
} catch (error) {
|
|
357
|
-
|
|
358
|
-
phase: "error",
|
|
359
|
-
error: error instanceof Error ? error.message : "Desktop update failed",
|
|
360
|
-
});
|
|
540
|
+
installFailed(error, error instanceof Error ? error.message : "Desktop update failed");
|
|
361
541
|
} finally {
|
|
362
542
|
updater.onStatusChange(null);
|
|
363
543
|
}
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
loadExternalPlugin,
|
|
15
15
|
} from "../../../plugins/loader";
|
|
16
16
|
import { createNodePluginManager } from "../../../plugins/manager-node";
|
|
17
|
+
import { deactivatePluginForRemoval } from "../../../plugins/marketplace/deactivation";
|
|
17
18
|
import { readPluginIcon } from "../../../plugins/plugin-icon";
|
|
18
19
|
import type { PluginRegistry } from "../../../plugins/registry";
|
|
19
20
|
import { desktopRendererCapabilityManifests } from "./desktop/initialization";
|
|
@@ -157,6 +158,33 @@ export async function collectExternalPluginBundles(): Promise<DesktopExternalPlu
|
|
|
157
158
|
return bundles;
|
|
158
159
|
}
|
|
159
160
|
|
|
161
|
+
let prefetchedBundles: Promise<DesktopExternalPluginBundle[]> | null = null;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Starts compiling every plugin for the view before it asks. The bundle cache
|
|
165
|
+
* above lives in memory, so the first window of a launch always compiles;
|
|
166
|
+
* started at launch, that runs while the view loads its own bundle.
|
|
167
|
+
*/
|
|
168
|
+
export function prefetchExternalPluginBundles(): void {
|
|
169
|
+
if (prefetchedBundles) return;
|
|
170
|
+
const bundles = collectExternalPluginBundles();
|
|
171
|
+
// The view's request reports a failure; this one only must not go unhandled.
|
|
172
|
+
bundles.catch(() => {
|
|
173
|
+
// Intentional ignore: the window that takes these bundles reports the failure.
|
|
174
|
+
});
|
|
175
|
+
prefetchedBundles = bundles;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The bundles for a window: the launch's prefetch once, then a new collection,
|
|
180
|
+
* which the mtime cache keeps cheap, so a later window sees plugins installed since.
|
|
181
|
+
*/
|
|
182
|
+
export function takeExternalPluginBundles(): Promise<DesktopExternalPluginBundle[]> {
|
|
183
|
+
const prefetched = prefetchedBundles;
|
|
184
|
+
prefetchedBundles = null;
|
|
185
|
+
return prefetched ?? collectExternalPluginBundles();
|
|
186
|
+
}
|
|
187
|
+
|
|
160
188
|
/** One plugin, compiled fresh, so the view can activate what was just installed or updated. */
|
|
161
189
|
export function bundleExternalPluginDirectory(directory: string): Promise<DesktopExternalPluginBundle | null> {
|
|
162
190
|
return bundlePluginDirectory(join(getPluginsDir(), directory), { fresh: true });
|
|
@@ -209,12 +237,6 @@ export function deactivateExternalPlugin(
|
|
|
209
237
|
registry: PluginRegistry,
|
|
210
238
|
pluginId: string,
|
|
211
239
|
): { capabilityManifests: ReturnType<typeof desktopRendererCapabilityManifests> } {
|
|
212
|
-
|
|
213
|
-
try {
|
|
214
|
-
registry.unregister(pluginId);
|
|
215
|
-
} catch (error) {
|
|
216
|
-
log.error(`Deactivating ${pluginId} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
240
|
+
deactivatePluginForRemoval(registry, pluginId);
|
|
219
241
|
return { capabilityManifests: desktopRendererCapabilityManifests(registry.capabilities) };
|
|
220
242
|
}
|
|
@@ -6,6 +6,7 @@ import { ELECTROBUN_CONTEXT_MENU_ACTION } from "../shared/protocol";
|
|
|
6
6
|
import { contextMenuSelectionMessage } from "./context-menu/click";
|
|
7
7
|
import { applicationMenuCommand, createApplicationMenuGate } from "./application-menu/click";
|
|
8
8
|
import { DesktopBackend } from "./desktop/backend";
|
|
9
|
+
import { startDesktopBackend } from "./desktop/initialization";
|
|
9
10
|
import {
|
|
10
11
|
MAIN_WINDOW_MIN_SIZE,
|
|
11
12
|
defaultMainWindowFrame,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
} from "./window/frame";
|
|
14
15
|
import { MAIN_WINDOW_RPC_KEY } from "./window/focus";
|
|
15
16
|
import { createAppWindow } from "./window/create";
|
|
17
|
+
import { desktopBootFramePath, desktopBootFramePreload, readDesktopBootFrame } from "./window/boot-frame";
|
|
16
18
|
import { getWindowFrame } from "./window/events";
|
|
17
19
|
import {
|
|
18
20
|
fitWindowFrameToDisplays,
|
|
@@ -135,13 +137,21 @@ function scheduleRememberedWindow(): void {
|
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
const mainWindow = createAppWindow({
|
|
138
|
-
title: "
|
|
140
|
+
title: "Gloom",
|
|
139
141
|
frame: initialMainWindowFrame,
|
|
140
142
|
rpc: mainRpc,
|
|
141
143
|
minSize: MAIN_WINDOW_MIN_SIZE,
|
|
142
144
|
onFrameChange: scheduleRememberedWindow,
|
|
145
|
+
// The layout the window last drew, which its page draws before its script
|
|
146
|
+
// has loaded (dom/boot-frame.ts).
|
|
147
|
+
preload: desktopBootFramePreload(readDesktopBootFrame(desktopBootFramePath())),
|
|
143
148
|
});
|
|
144
149
|
backend.mainWindow = mainWindow;
|
|
150
|
+
// The window is loading its view; the services it will ask for start now
|
|
151
|
+
// rather than when it asks. Its `init` reports a failure, and retries.
|
|
152
|
+
startDesktopBackend(backend).catch((error) => {
|
|
153
|
+
console.error("[desktop] startup failed", error instanceof Error ? error.stack ?? error.message : String(error));
|
|
154
|
+
});
|
|
145
155
|
if (rememberedWindow?.fullscreen) {
|
|
146
156
|
try { mainWindow.setFullScreen(true); } catch { /* the framed window is still the one they sized */ }
|
|
147
157
|
} else if (rememberedWindow?.maximized) {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
2
|
+
import { dirname, join } from "path";
|
|
3
|
+
import { getGloomberbDirs } from "../../../../data/config/home";
|
|
4
|
+
import { isBootFrame, type BootFrame } from "../../../dom/boot-frame-page";
|
|
5
|
+
import { DESKTOP_BOOT_FRAME_GLOBAL } from "../../shared/boot-frame";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The main window's launch frame lives beside the remembered window frame:
|
|
9
|
+
* read before the config, and drawn for this machine's screen.
|
|
10
|
+
*/
|
|
11
|
+
const FILE_NAME = "desktop-boot-frame.json";
|
|
12
|
+
|
|
13
|
+
export function desktopBootFramePath(env: NodeJS.ProcessEnv = process.env): string {
|
|
14
|
+
return join(dirname(getGloomberbDirs(env).configFile), FILE_NAME);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function readDesktopBootFrame(path: string): BootFrame | null {
|
|
18
|
+
try {
|
|
19
|
+
const frame: unknown = JSON.parse(readFileSync(path, "utf8"));
|
|
20
|
+
return isBootFrame(frame) ? frame : null;
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface BootFrameSender {
|
|
27
|
+
/** The main window's view; a popped-out pane's draws no frame. */
|
|
28
|
+
mainWindow: boolean;
|
|
29
|
+
/** A session is up. After all data was reset there is none until the next launch. */
|
|
30
|
+
session: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Keeps the frame a view sent, if it may: from the main window, while a
|
|
35
|
+
* session is up, and of the right shape and size. A closing window's last
|
|
36
|
+
* frame, sent after a reset, is dropped. Returns whether it was written.
|
|
37
|
+
*/
|
|
38
|
+
export function saveDesktopBootFrame(path: string, frame: unknown, sender: BootFrameSender): boolean {
|
|
39
|
+
if (!sender.mainWindow || !sender.session || !isBootFrame(frame)) return false;
|
|
40
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
41
|
+
const temporary = `${path}.${process.pid}.tmp`;
|
|
42
|
+
writeFileSync(temporary, JSON.stringify(frame));
|
|
43
|
+
renameSync(temporary, path);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Forgets the frame, with the rest of the data on a reset. It sits beside
|
|
49
|
+
* the config, which a custom data folder is not, so removing the data folder
|
|
50
|
+
* alone could leave it behind.
|
|
51
|
+
*/
|
|
52
|
+
export function removeDesktopBootFrame(path: string): void {
|
|
53
|
+
rmSync(path, { force: true });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The main window's preload: the frame its page draws before its script
|
|
58
|
+
* loads, or null for the bare shell. Set either way, which is how the page
|
|
59
|
+
* tells the main window from a popped-out pane's.
|
|
60
|
+
*/
|
|
61
|
+
export function desktopBootFramePreload(frame: BootFrame | null): string {
|
|
62
|
+
const json = JSON.stringify(frame)
|
|
63
|
+
.replace(/</g, "\\u003c")
|
|
64
|
+
.replace(/\u2028/g, "\\u2028")
|
|
65
|
+
.replace(/\u2029/g, "\\u2029");
|
|
66
|
+
return `window.${DESKTOP_BOOT_FRAME_GLOBAL} = ${json};`;
|
|
67
|
+
}
|
|
@@ -51,17 +51,20 @@ interface AppWindowOptions {
|
|
|
51
51
|
minSize: WindowMinimumSize;
|
|
52
52
|
/** Runs after each move or resize has been applied to the cached frame. */
|
|
53
53
|
onFrameChange?: () => void;
|
|
54
|
+
/** Script run in the page before its own. */
|
|
55
|
+
preload?: string;
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
/**
|
|
57
59
|
* Opens a window on the app view with this platform's chrome and icon, keeps
|
|
58
60
|
* its cached frame current as it moves, and holds it to `minSize` on resize.
|
|
59
61
|
*/
|
|
60
|
-
export function createAppWindow({ title, frame, rpc, minSize, onFrameChange }: AppWindowOptions): BrowserWindow {
|
|
62
|
+
export function createAppWindow({ title, frame, rpc, minSize, onFrameChange, preload }: AppWindowOptions): BrowserWindow {
|
|
61
63
|
const window = new BrowserWindow({
|
|
62
64
|
title,
|
|
63
65
|
frame,
|
|
64
66
|
url: "views://mainview/index.html",
|
|
67
|
+
...(preload ? { preload } : {}),
|
|
65
68
|
renderer: desktopWindowRenderer(),
|
|
66
69
|
rpc,
|
|
67
70
|
styleMask: desktopWindowStyleMask(),
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the main window's page finds the launch frame (dom/boot-frame.ts):
|
|
3
|
+
* the Bun process sets it in the window's preload, before the page's own
|
|
4
|
+
* scripts run. A window it is not set in, one holding a popped-out pane,
|
|
5
|
+
* draws no frame.
|
|
6
|
+
*/
|
|
7
|
+
export const DESKTOP_BOOT_FRAME_GLOBAL = "__gloomDesktopBootFrame";
|
|
@@ -10,6 +10,7 @@ import type { CapabilityManifest } from "../../../capabilities";
|
|
|
10
10
|
import type { PluginOperationResult, PluginPin } from "../../../plugins/marketplace/store";
|
|
11
11
|
import type { RemoteControlRequest, RemoteControlResponse } from "../../../remote/types";
|
|
12
12
|
import type { HttpProxyRequestEnvelope, HttpProxyResponseEnvelope } from "../../../utils/http-proxy-response";
|
|
13
|
+
import type { BootFrame } from "../../dom/boot-frame-page";
|
|
13
14
|
|
|
14
15
|
export const ELECTROBUN_CONTEXT_MENU_ACTION = "gloom.context-menu.select";
|
|
15
16
|
|
|
@@ -27,6 +28,8 @@ export interface ElectrobunBackendInit {
|
|
|
27
28
|
hostName?: string;
|
|
28
29
|
windowKind: "main" | "detached";
|
|
29
30
|
paneId?: string;
|
|
31
|
+
/** What the launch's plugin seed could not install, for the main window to say once. */
|
|
32
|
+
pluginSeedNotice?: { body: string; type: "error" | "info" };
|
|
30
33
|
/** What the view needs to send crash reports and usage counts the same way the Bun process would. */
|
|
31
34
|
telemetry: ElectrobunTelemetryInit;
|
|
32
35
|
}
|
|
@@ -203,7 +206,7 @@ interface DesktopBackendRequestMap {
|
|
|
203
206
|
"host.exit": { request: null; response: null };
|
|
204
207
|
"host.windowControl": { request: { action: DesktopWindowControlAction }; response: null };
|
|
205
208
|
"host.windowFullscreen": { request: null; response: boolean };
|
|
206
|
-
"host.openExternal": { request: { url: string }; response:
|
|
209
|
+
"host.openExternal": { request: { url: string }; response: boolean };
|
|
207
210
|
"host.copyText": { request: { text: string }; response: null };
|
|
208
211
|
"host.focusWindow": { request: null; response: null };
|
|
209
212
|
"host.copyPngImage": { request: { pngBase64: string }; response: null };
|
|
@@ -217,6 +220,8 @@ interface DesktopBackendRequestMap {
|
|
|
217
220
|
response: null;
|
|
218
221
|
};
|
|
219
222
|
"host.showContextMenu": { request: { menu: DesktopContextMenuItem[] }; response: boolean };
|
|
223
|
+
/** The layout the main window draws at the next launch before its script loads (dom/boot-frame.ts). Only the main window's is kept. */
|
|
224
|
+
"host.saveBootFrame": { request: { frame: BootFrame }; response: null };
|
|
220
225
|
/** The unread count for the Dock icon badge: `""` (none), `"1"` to `"99"` or `"99+"`. Only the main window's is applied. */
|
|
221
226
|
"host.setAppBadge": { request: { label: string }; response: null };
|
|
222
227
|
/** `channel` absent (an older view) means stable. */
|
|
@@ -185,7 +185,7 @@ async function restoreShotCloudSession(): Promise<void> {
|
|
|
185
185
|
|
|
186
186
|
/**
|
|
187
187
|
* Runs an asset-data request in the Bun process so the page sees exactly what
|
|
188
|
-
* `
|
|
188
|
+
* `gloom fn` sees. The page can only reach the cloud API on its own, and
|
|
189
189
|
* the cloud is one source among several: analyst rating price targets and part
|
|
190
190
|
* of the corporate action history come from providers the router merges in.
|
|
191
191
|
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { setConfigStoreHost, type ConfigStoreHost } from "../../../data/config/store";
|
|
2
|
+
import { stopBootFrameRecorders } from "../../dom/boot-frame";
|
|
2
3
|
import type { AppConfig } from "../../../types/config";
|
|
3
4
|
import { backendRequest, getElectrobunBackendInitSnapshot } from "./backend-rpc";
|
|
4
5
|
|
|
@@ -20,6 +21,8 @@ const electrobunConfigStoreHost: ConfigStoreHost = {
|
|
|
20
21
|
return config;
|
|
21
22
|
},
|
|
22
23
|
async resetAllData(dataDir: string) {
|
|
24
|
+
// Before the reset, or the frame saved as the window closes would bring the old layout back.
|
|
25
|
+
stopBootFrameRecorders();
|
|
23
26
|
await backendRequest("config.resetAllData", { dataDir });
|
|
24
27
|
},
|
|
25
28
|
async exportConfig(config: AppConfig, destPath: string) {
|