gloomberb 0.9.3 → 0.9.5
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 +1 -0
- package/package.json +3 -2
- package/patches/@opentui%2Fcore@0.3.2.patch +231 -29
- package/patches/react-reconciler@0.33.0.patch +10 -0
- package/src/app/runtime/desktop-menu.ts +5 -1
- package/src/app/runtime/ticker-refresh.ts +4 -1
- package/src/app.tsx +10 -1
- package/src/brokers/account-cache.ts +1 -1
- package/src/brokers/sync-broker-instance.test.ts +107 -0
- package/src/brokers/sync-broker-instance.ts +22 -10
- package/src/cli/desktop-pane-shot.ts +2 -1
- package/src/cli/entry.ts +8 -1
- package/src/cli/native-smoke.ts +5 -0
- package/src/cli/pane-functions/screenshot.ts +13 -1
- package/src/components/chart/bar-chart-renderer.test.ts +108 -3
- package/src/components/chart/bar-chart-renderer.ts +226 -27
- package/src/components/chart/core/pointer.ts +32 -6
- package/src/components/chart/native/bitmap-support.test.ts +27 -0
- package/src/components/chart/native/bitmap-support.ts +55 -0
- package/src/components/chart/native/kitty/index.test.ts +47 -0
- package/src/components/chart/native/surface/visibility.ts +8 -1
- package/src/components/chart/price-axis-labels.tsx +3 -1
- package/src/components/chart/static/bar-chart-surface.test.tsx +97 -0
- package/src/components/chart/static/bar-chart-surface.tsx +151 -28
- package/src/components/chart/static/chart/axis-overlays.tsx +243 -0
- package/src/components/chart/static/chart/bitmap.ts +16 -9
- package/src/components/chart/static/chart/surface.test.tsx +92 -0
- package/src/components/chart/static/chart/surface.tsx +167 -24
- package/src/components/chart/stock-chart/index.test.ts +25 -0
- package/src/components/command-bar/layout-items/current-layout.ts +5 -1
- package/src/components/command-bar/list/view.tsx +1 -1
- package/src/components/command-bar/theme-picker.tsx +1 -1
- package/src/components/data-table/view.tsx +0 -12
- package/src/components/layout/detached-pane-shell.tsx +6 -3
- package/src/components/layout/floating-pane.tsx +6 -5
- package/src/components/layout/pane/content.tsx +20 -8
- package/src/components/layout/pane/footer/registration.tsx +6 -2
- package/src/components/layout/pane/frame.tsx +4 -4
- package/src/components/layout/pane/header.tsx +45 -4
- package/src/components/layout/pane/index.tsx +6 -4
- package/src/components/layout/pane/sizing.test.ts +43 -0
- package/src/components/layout/pane/sizing.ts +13 -4
- package/src/components/layout/shell/action-menu-overlay.tsx +1 -1
- package/src/components/layout/shell/cursor-occlusion.ts +204 -0
- package/src/components/layout/shell/drag/runtime.ts +9 -2
- package/src/components/layout/shell/index.test.tsx +92 -2
- package/src/components/layout/shell/index.tsx +45 -3
- package/src/components/layout/shell/layout-state.test.ts +33 -0
- package/src/components/layout/shell/layout-state.ts +4 -9
- package/src/components/layout/shell/pane/layers.tsx +10 -4
- package/src/components/layout/shell/visible-layout.ts +17 -0
- package/src/components/layout/status-bar.test.tsx +6 -1
- package/src/components/layout/status-bar.tsx +10 -6
- package/src/components/onboarding/onboarding-steps.tsx +8 -28
- package/src/components/onboarding/onboarding-wizard.test.tsx +13 -12
- package/src/components/onboarding/onboarding-wizard.tsx +2 -4
- package/src/components/onboarding/portfolio-step/index.tsx +0 -12
- package/src/components/onboarding/portfolio-step/types.ts +1 -3
- package/src/components/onboarding/wizard-keyboard.ts +2 -5
- package/src/components/pane-settings-dialog/desktop.tsx +1 -1
- package/src/components/price-performance.tsx +1 -1
- package/src/components/price-sparkline/view.tsx +15 -14
- package/src/components/speedometer-gauge/terminal.tsx +18 -15
- package/src/components/table-view-shared.tsx +12 -14
- package/src/components/ticker/list-table-view.tsx +1 -7
- package/src/components/ticker/list-table.test.tsx +0 -4
- package/src/components/ui/data-table/opentui/index.tsx +29 -22
- package/src/components/ui/data-table/types.ts +10 -4
- package/src/components/ui/fields.tsx +10 -3
- package/src/components/ui/list-view.tsx +1 -1
- package/src/components/ui/page-stack-view.tsx +6 -2
- package/src/components/ui/table-layout.test.ts +25 -0
- package/src/components/ui/table-layout.ts +22 -6
- package/src/components/ui/tabs.tsx +27 -12
- package/src/components/ui/ui.test.tsx +87 -9
- package/src/core/state/app/layout-reducer.ts +2 -2
- package/src/plugins/builtin/account-management/form-components.tsx +2 -2
- package/src/plugins/builtin/alerts/pane.tsx +1 -1
- package/src/plugins/builtin/analytics/index.test.tsx +6 -2
- package/src/plugins/builtin/analytics/pane-model.ts +43 -8
- package/src/plugins/builtin/buildout/cells.tsx +1 -1
- package/src/plugins/builtin/buildout/pane/index.tsx +1 -1
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -1
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +1 -1
- package/src/plugins/builtin/chat/message/terminal.tsx +2 -2
- package/src/plugins/builtin/chat/sidebar.tsx +1 -1
- package/src/plugins/builtin/chat/status-widget.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-actions.tsx +2 -2
- package/src/plugins/builtin/correlation/matrix/symbol-cell.tsx +1 -1
- package/src/plugins/builtin/debug/index.tsx +3 -4
- package/src/plugins/builtin/help/components.tsx +1 -1
- package/src/plugins/builtin/holders/treemap.tsx +1 -1
- package/src/plugins/builtin/kelly-sizer/constants.ts +3 -0
- package/src/plugins/builtin/kelly-sizer/fields.ts +214 -0
- package/src/plugins/builtin/kelly-sizer/index.test.tsx +197 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +47 -0
- package/src/plugins/builtin/kelly-sizer/model.test.ts +152 -0
- package/src/plugins/builtin/kelly-sizer/model.ts +580 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +558 -0
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +71 -0
- package/src/plugins/builtin/kelly-sizer/sections.tsx +142 -0
- package/src/plugins/builtin/kelly-sizer/state.ts +67 -0
- package/src/plugins/builtin/kelly-sizer/test-support.tsx +174 -0
- package/src/plugins/builtin/kelly-sizer/types.ts +156 -0
- package/src/plugins/builtin/kelly-sizer/view.test.tsx +77 -0
- package/src/plugins/builtin/kelly-sizer/view.tsx +375 -0
- package/src/plugins/builtin/layout-manager/index.tsx +5 -1
- package/src/plugins/builtin/options/table.ts +5 -5
- package/src/plugins/builtin/options/view.test.tsx +141 -4
- package/src/plugins/builtin/options/view.tsx +76 -15
- package/src/plugins/builtin/portfolio-list/account-metrics.test.ts +26 -1
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +14 -0
- package/src/plugins/builtin/portfolio-list/index.test.ts +23 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +2 -0
- package/src/plugins/builtin/portfolio-list/summary/index.test.ts +59 -1
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +36 -5
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/content.tsx +149 -48
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph/model.ts +25 -2
- package/src/plugins/builtin/ticker-detail/data-panes/fundamental-graph.tsx +5 -4
- package/src/plugins/builtin/ticker-detail/data-panes.test.ts +16 -0
- package/src/plugins/builtin/ticker-detail/index.test.tsx +143 -0
- package/src/plugins/catalog-ui.ts +2 -0
- package/src/plugins/ibkr/broker-adapter.ts +19 -0
- package/src/plugins/ibkr/config.test.ts +31 -2
- package/src/plugins/ibkr/config.ts +9 -2
- package/src/plugins/ibkr/flex/index.test.ts +18 -9
- package/src/plugins/ibkr/flex/index.ts +30 -0
- package/src/plugins/ibkr/flex/statement-client.ts +68 -14
- package/src/plugins/ibkr/gateway/account-loaders.ts +1 -1
- package/src/plugins/ibkr/gateway/account-summary.ts +1 -0
- package/src/plugins/ibkr/gateway/service/index.test.ts +8 -0
- package/src/plugins/ibkr/trade/ticket-panel.tsx +1 -1
- package/src/plugins/pane-manager/gridlock.ts +13 -5
- package/src/plugins/pane-manager/layout-state.ts +25 -0
- package/src/plugins/pane-manager.test.ts +33 -0
- package/src/plugins/pane-manager.ts +6 -1
- package/src/plugins/prediction-markets/chart.tsx +10 -4
- package/src/plugins/prediction-markets/detail/book.tsx +141 -96
- package/src/plugins/prediction-markets/detail/overview.tsx +3 -0
- package/src/plugins/prediction-markets/detail/pane.tsx +71 -64
- package/src/plugins/prediction-markets/detail/shared.tsx +19 -0
- package/src/plugins/prediction-markets/detail/trades.tsx +64 -19
- package/src/plugins/prediction-markets/detail.test.tsx +50 -0
- package/src/plugins/prediction-markets/pane.test.tsx +43 -0
- package/src/plugins/prediction-markets/pane.tsx +50 -22
- package/src/plugins/prediction-markets/test-helpers.tsx +41 -23
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +13 -2
- package/src/renderers/electrobun/view/data-table/index.tsx +19 -12
- package/src/renderers/electrobun/view/data-table/row.tsx +32 -18
- package/src/renderers/electrobun/view/desktop/controls.tsx +11 -5
- package/src/renderers/electrobun/view/host/box.tsx +6 -1
- package/src/renderers/electrobun/view/host/input.tsx +115 -18
- package/src/renderers/electrobun/view/host/style.ts +1 -0
- package/src/renderers/electrobun/view/host/tabs.tsx +7 -2
- package/src/renderers/electrobun/view/styles.css +18 -0
- package/src/renderers/opentui/host.tsx +17 -1
- package/src/renderers/opentui/native-smoke.ts +1 -0
- package/src/renderers/opentui/ui-host.tsx +57 -25
- package/src/sources/provider-router/batches.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +5 -0
- package/src/sources/provider-router/financials.ts +11 -23
- package/src/sources/provider-router/index.test.ts +189 -0
- package/src/sources/provider-router/primary.ts +3 -2
- package/src/sources/sec-edgar.test.ts +83 -0
- package/src/sources/sec-edgar.ts +231 -0
- package/src/sources/yahoo-finance.test.ts +51 -0
- package/src/sources/yahoo-finance.ts +49 -1
- package/src/state/app/context/index.test.tsx +5 -8
- package/src/types/broker.ts +1 -0
- package/src/types/config.ts +10 -0
- package/src/types/trading.ts +2 -0
- package/src/ui/host.tsx +16 -0
- package/src/ui/index.tsx +2 -0
- package/src/utils/financial-statements.ts +23 -0
- package/src/version.ts +1 -1
- package/src/components/onboarding/portfolio-step/manual-name-panel.tsx +0 -62
|
@@ -17,6 +17,7 @@ describe("YahooFinanceClient exchange aliases", () => {
|
|
|
17
17
|
provider.fetchAssetProfile = async () => undefined;
|
|
18
18
|
provider.fetchQuoteSupplement = async () => ({});
|
|
19
19
|
provider.fetchExtendedHoursData = async () => ({});
|
|
20
|
+
provider.secClient.getFinancialStatements = async () => null;
|
|
20
21
|
provider.fetchTimeseries = async () => [
|
|
21
22
|
point("annualAccountsReceivable", 7_450_000_000),
|
|
22
23
|
point("annualInventory", 4_880_000_000),
|
|
@@ -52,6 +53,56 @@ describe("YahooFinanceClient exchange aliases", () => {
|
|
|
52
53
|
});
|
|
53
54
|
});
|
|
54
55
|
|
|
56
|
+
test("supplements US Yahoo financials with deeper SEC statement history", async () => {
|
|
57
|
+
const provider = new YahooFinanceClient() as any;
|
|
58
|
+
const point = (type: string, date: string, value: number) => ({
|
|
59
|
+
meta: { type: [type] },
|
|
60
|
+
[type]: [{ asOfDate: date, reportedValue: { raw: value } }],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
provider.fetchChart = async () => ({
|
|
64
|
+
meta: { currency: "USD", regularMarketPrice: 100, shortName: "AMD" },
|
|
65
|
+
history: [{ date: new Date("2025-12-31T00:00:00Z"), close: 100 }],
|
|
66
|
+
});
|
|
67
|
+
provider.fetchAssetProfile = async () => undefined;
|
|
68
|
+
provider.fetchQuoteSupplement = async () => ({});
|
|
69
|
+
provider.fetchExtendedHoursData = async () => ({});
|
|
70
|
+
provider.fetchTimeseries = async () => [
|
|
71
|
+
point("annualTotalRevenue", "2025-12-31", 200),
|
|
72
|
+
point("quarterlyTotalRevenue", "2025-12-31", 60),
|
|
73
|
+
];
|
|
74
|
+
provider.secClient.getFinancialStatements = async (ticker: string) => {
|
|
75
|
+
expect(ticker).toBe("AMD");
|
|
76
|
+
return {
|
|
77
|
+
annualStatements: [
|
|
78
|
+
{ date: "2023-12-31", totalRevenue: 100 },
|
|
79
|
+
{ date: "2024-12-31", totalRevenue: 150 },
|
|
80
|
+
{ date: "2025-12-31", totalRevenue: 190, netIncome: 40 },
|
|
81
|
+
],
|
|
82
|
+
quarterlyStatements: [
|
|
83
|
+
{ date: "2025-03-31", totalRevenue: 45 },
|
|
84
|
+
{ date: "2025-06-30", totalRevenue: 50 },
|
|
85
|
+
{ date: "2025-09-30", totalRevenue: 55 },
|
|
86
|
+
{ date: "2025-12-31", totalRevenue: 58, netIncome: 12 },
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const financials = await provider.getTickerFinancials("AMD", "NASDAQ");
|
|
92
|
+
|
|
93
|
+
expect(financials.annualStatements.map((row: any) => [row.date, row.totalRevenue, row.netIncome])).toEqual([
|
|
94
|
+
["2023-12-31", 100, undefined],
|
|
95
|
+
["2024-12-31", 150, undefined],
|
|
96
|
+
["2025-12-31", 200, 40],
|
|
97
|
+
]);
|
|
98
|
+
expect(financials.quarterlyStatements.map((row: any) => [row.date, row.totalRevenue, row.netIncome])).toEqual([
|
|
99
|
+
["2025-03-31", 45, undefined],
|
|
100
|
+
["2025-06-30", 50, undefined],
|
|
101
|
+
["2025-09-30", 55, undefined],
|
|
102
|
+
["2025-12-31", 60, 12],
|
|
103
|
+
]);
|
|
104
|
+
});
|
|
105
|
+
|
|
55
106
|
test("tries the Taipei Exchange suffix for TPEX tickers", () => {
|
|
56
107
|
expect(getYahooSymbolsToTry("3105", "TPEX")).toEqual(["3105.TWO", "3105.TW"]);
|
|
57
108
|
});
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import type { InstrumentSearchResult } from "../types/instrument";
|
|
9
9
|
import { parseOptionSymbol } from "../utils/options";
|
|
10
10
|
import { SecEdgarClient } from "./sec-edgar";
|
|
11
|
+
import { mergeFinancialStatementRows } from "../utils/financial-statements";
|
|
11
12
|
import { YahooHttpClient } from "./yahoo-finance/http";
|
|
12
13
|
import {
|
|
13
14
|
normalizeSubUnitCurrency,
|
|
@@ -42,6 +43,21 @@ import {
|
|
|
42
43
|
loadYahooTickerFinancials,
|
|
43
44
|
} from "./yahoo-finance/snapshots";
|
|
44
45
|
|
|
46
|
+
const SEC_STATEMENT_SUPPLEMENT_EXCHANGES = new Set([
|
|
47
|
+
"",
|
|
48
|
+
"AMEX",
|
|
49
|
+
"ARCA",
|
|
50
|
+
"BATS",
|
|
51
|
+
"BYX",
|
|
52
|
+
"IEX",
|
|
53
|
+
"NASDAQ",
|
|
54
|
+
"NMS",
|
|
55
|
+
"NYSE",
|
|
56
|
+
"NYSEARCA",
|
|
57
|
+
"OTC",
|
|
58
|
+
"PINK",
|
|
59
|
+
]);
|
|
60
|
+
|
|
45
61
|
export class YahooFinanceClient implements DataProvider {
|
|
46
62
|
readonly id = "yahoo";
|
|
47
63
|
readonly name = "Yahoo Finance";
|
|
@@ -50,6 +66,38 @@ export class YahooFinanceClient implements DataProvider {
|
|
|
50
66
|
|
|
51
67
|
constructor(private readonly http = new YahooHttpClient()) {}
|
|
52
68
|
|
|
69
|
+
private shouldSupplementSecStatements(ticker: string, exchange: string, financials: TickerFinancials): boolean {
|
|
70
|
+
if (!/^[A-Z0-9.-]+$/i.test(ticker.trim())) return false;
|
|
71
|
+
if (ticker.includes(".")) return false;
|
|
72
|
+
const normalizedExchange = exchange.trim().toUpperCase();
|
|
73
|
+
return SEC_STATEMENT_SUPPLEMENT_EXCHANGES.has(normalizedExchange)
|
|
74
|
+
&& (financials.quote?.currency ?? "USD").toUpperCase() === "USD";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private async supplementSecStatements(
|
|
78
|
+
ticker: string,
|
|
79
|
+
exchange: string,
|
|
80
|
+
financials: TickerFinancials,
|
|
81
|
+
): Promise<TickerFinancials> {
|
|
82
|
+
if (!this.shouldSupplementSecStatements(ticker, exchange, financials)) return financials;
|
|
83
|
+
try {
|
|
84
|
+
const secStatements = await this.secClient.getFinancialStatements(ticker);
|
|
85
|
+
if (
|
|
86
|
+
!secStatements
|
|
87
|
+
|| (secStatements.annualStatements.length === 0 && secStatements.quarterlyStatements.length === 0)
|
|
88
|
+
) {
|
|
89
|
+
return financials;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
...financials,
|
|
93
|
+
annualStatements: mergeFinancialStatementRows(financials.annualStatements, secStatements.annualStatements),
|
|
94
|
+
quarterlyStatements: mergeFinancialStatementRows(financials.quarterlyStatements, secStatements.quarterlyStatements),
|
|
95
|
+
};
|
|
96
|
+
} catch {
|
|
97
|
+
return financials;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
53
101
|
private async fetchChart(symbol: string, range: string, interval = "1d", includePrePost = false) {
|
|
54
102
|
return fetchYahooChart(this.http, symbol, range, interval, includePrePost);
|
|
55
103
|
}
|
|
@@ -90,7 +138,7 @@ export class YahooFinanceClient implements DataProvider {
|
|
|
90
138
|
fetchTimeseries: (targetSymbol, types, period1) => this.fetchTimeseries(targetSymbol, types, period1),
|
|
91
139
|
providerId: this.id,
|
|
92
140
|
});
|
|
93
|
-
return result;
|
|
141
|
+
return await this.supplementSecStatements(ticker, exchange, result);
|
|
94
142
|
} catch (err) {
|
|
95
143
|
lastError = err;
|
|
96
144
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import { cloneLayout, createDefaultConfig } from "../../../types/config";
|
|
2
|
+
import { cloneLayout, createBlankLayout, createDefaultConfig } from "../../../types/config";
|
|
3
3
|
import { appReducer, createInitialState } from "./index";
|
|
4
4
|
|
|
5
5
|
describe("appReducer command bar state", () => {
|
|
@@ -150,11 +150,10 @@ describe("appReducer command bar state", () => {
|
|
|
150
150
|
|
|
151
151
|
const noUndoOnFreshLayout = appReducer(state, { type: "UNDO_LAYOUT" });
|
|
152
152
|
expect(noUndoOnFreshLayout.config.activeLayoutIndex).toBe(newLayoutIndex);
|
|
153
|
-
expect(noUndoOnFreshLayout.config.layout.
|
|
154
|
-
|
|
155
|
-
: null).toBe(defaultRatio);
|
|
153
|
+
expect(noUndoOnFreshLayout.config.layout).toEqual(createBlankLayout());
|
|
154
|
+
expect(noUndoOnFreshLayout.focusedPaneId).toBeNull();
|
|
156
155
|
|
|
157
|
-
const secondLayout = cloneLayout(
|
|
156
|
+
const secondLayout = cloneLayout(initial.config.layout);
|
|
158
157
|
if (!secondLayout.dockRoot || secondLayout.dockRoot.kind !== "split") {
|
|
159
158
|
throw new Error("expected split dock root");
|
|
160
159
|
}
|
|
@@ -172,9 +171,7 @@ describe("appReducer command bar state", () => {
|
|
|
172
171
|
const backToSecond = appReducer(firstUndone, { type: "SWITCH_LAYOUT", index: newLayoutIndex });
|
|
173
172
|
const secondUndone = appReducer(backToSecond, { type: "UNDO_LAYOUT" });
|
|
174
173
|
expect(secondUndone.config.activeLayoutIndex).toBe(newLayoutIndex);
|
|
175
|
-
expect(secondUndone.config.layout.
|
|
176
|
-
? secondUndone.config.layout.dockRoot.ratio
|
|
177
|
-
: null).toBe(defaultRatio);
|
|
174
|
+
expect(secondUndone.config.layout).toEqual(createBlankLayout());
|
|
178
175
|
});
|
|
179
176
|
|
|
180
177
|
test("tracks manual update-check feedback", () => {
|
package/src/types/broker.ts
CHANGED
|
@@ -85,6 +85,7 @@ export interface BrokerAdapter {
|
|
|
85
85
|
readonly cachePolicy?: CachePolicyMap;
|
|
86
86
|
validate(instance: BrokerInstanceConfig): Promise<boolean>;
|
|
87
87
|
importPositions(instance: BrokerInstanceConfig): Promise<BrokerPosition[]>;
|
|
88
|
+
importPortfolioSnapshot?(instance: BrokerInstanceConfig): Promise<{ accounts: BrokerAccount[]; positions: BrokerPosition[] }>;
|
|
88
89
|
configSchema: BrokerConfigField[];
|
|
89
90
|
connect?(instance: BrokerInstanceConfig): Promise<void>;
|
|
90
91
|
disconnect?(instance: BrokerInstanceConfig): Promise<void>;
|
package/src/types/config.ts
CHANGED
|
@@ -309,6 +309,12 @@ const DEFAULT_MONITOR_LAYOUT: LayoutConfig = {
|
|
|
309
309
|
};
|
|
310
310
|
|
|
311
311
|
export const DEFAULT_LAYOUT = DEFAULT_HOME_LAYOUT;
|
|
312
|
+
const BLANK_LAYOUT: LayoutConfig = {
|
|
313
|
+
dockRoot: null,
|
|
314
|
+
instances: [],
|
|
315
|
+
floating: [],
|
|
316
|
+
detached: [],
|
|
317
|
+
};
|
|
312
318
|
|
|
313
319
|
let nextPaneInstanceSeq = 0;
|
|
314
320
|
|
|
@@ -594,6 +600,10 @@ export function cloneLayout(layout: LayoutConfig): LayoutConfig {
|
|
|
594
600
|
};
|
|
595
601
|
}
|
|
596
602
|
|
|
603
|
+
export function createBlankLayout(): LayoutConfig {
|
|
604
|
+
return cloneLayout(BLANK_LAYOUT);
|
|
605
|
+
}
|
|
606
|
+
|
|
597
607
|
export function findPaneInstance(layout: LayoutConfig, instanceId: string): PaneInstanceConfig | undefined {
|
|
598
608
|
return layout.instances.find((instance) => instance.instanceId === instanceId);
|
|
599
609
|
}
|
package/src/types/trading.ts
CHANGED
|
@@ -16,7 +16,9 @@ export interface BrokerAccount {
|
|
|
16
16
|
currency?: string;
|
|
17
17
|
source?: "gateway" | "flex";
|
|
18
18
|
updatedAt?: number;
|
|
19
|
+
asOfDate?: string;
|
|
19
20
|
netLiquidation?: number;
|
|
21
|
+
grossPositionValue?: number;
|
|
20
22
|
totalCashValue?: number;
|
|
21
23
|
settledCash?: number;
|
|
22
24
|
buyingPower?: number;
|
package/src/ui/host.tsx
CHANGED
|
@@ -143,12 +143,22 @@ export interface TextareaRenderable extends InputRenderable {
|
|
|
143
143
|
clearLineHighlights?(lineIdx: number): void;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
export interface NativeCursorState {
|
|
147
|
+
x: number;
|
|
148
|
+
y: number;
|
|
149
|
+
visible: boolean;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export type NativePostProcessFn = (buffer: unknown, deltaTime: number) => void;
|
|
153
|
+
|
|
146
154
|
export interface NativeRendererHost {
|
|
147
155
|
terminalWidth: number;
|
|
148
156
|
terminalHeight: number;
|
|
149
157
|
resolution: PixelResolution | null;
|
|
150
158
|
capabilities?: unknown;
|
|
151
159
|
isDestroyed?: boolean;
|
|
160
|
+
currentFocusedRenderable?: unknown;
|
|
161
|
+
currentFocusedEditor?: unknown;
|
|
152
162
|
keyInput?: {
|
|
153
163
|
on(event: string, handler: (...args: any[]) => void): void;
|
|
154
164
|
off(event: string, handler: (...args: any[]) => void): void;
|
|
@@ -160,8 +170,13 @@ export interface NativeRendererHost {
|
|
|
160
170
|
registerLifecyclePass(renderable: unknown): void;
|
|
161
171
|
unregisterLifecyclePass(renderable: unknown): void;
|
|
162
172
|
getSelection?(): { getSelectedText(): string } | null;
|
|
173
|
+
getCursorState?(): NativeCursorState;
|
|
174
|
+
setCursorPosition?(x: number, y: number, visible?: boolean): void;
|
|
175
|
+
addPostProcessFn?(processFn: NativePostProcessFn): void;
|
|
176
|
+
removePostProcessFn?(processFn: NativePostProcessFn): void;
|
|
163
177
|
copyToClipboardOSC52?(text: string): boolean;
|
|
164
178
|
write?(data: string | Uint8Array): boolean;
|
|
179
|
+
captureMouseRenderable?(renderable: unknown): void;
|
|
165
180
|
}
|
|
166
181
|
|
|
167
182
|
interface BoxProps {
|
|
@@ -244,6 +259,7 @@ export interface HostTabsProps {
|
|
|
244
259
|
closeMode?: "active" | "always";
|
|
245
260
|
addLabel?: string;
|
|
246
261
|
onAdd?: () => void;
|
|
262
|
+
focused?: boolean;
|
|
247
263
|
palette: HostTabsPalette;
|
|
248
264
|
}
|
|
249
265
|
|
package/src/ui/index.tsx
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FinancialStatement } from "../types/financials";
|
|
2
|
+
|
|
3
|
+
export function mergeFinancialStatementRows(
|
|
4
|
+
primaryRows: FinancialStatement[],
|
|
5
|
+
fallbackRows: FinancialStatement[],
|
|
6
|
+
): FinancialStatement[] {
|
|
7
|
+
if (primaryRows.length === 0) return fallbackRows;
|
|
8
|
+
if (fallbackRows.length === 0) return primaryRows;
|
|
9
|
+
|
|
10
|
+
const fallbackByDate = new Map(fallbackRows.map((row) => [row.date, row]));
|
|
11
|
+
const primaryDates = new Set(primaryRows.map((row) => row.date));
|
|
12
|
+
const mergedRows = primaryRows.map((row) => ({
|
|
13
|
+
...fallbackByDate.get(row.date),
|
|
14
|
+
...row,
|
|
15
|
+
date: row.date,
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
for (const row of fallbackRows) {
|
|
19
|
+
if (!primaryDates.has(row.date)) mergedRows.push(row);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return mergedRows.sort((left, right) => left.date.localeCompare(right.date));
|
|
23
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.9.
|
|
1
|
+
export const VERSION = "0.9.5";
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import type { RefObject } from "react";
|
|
2
|
-
import { Box, Text, TextAttributes, type InputRenderable } from "../../../ui";
|
|
3
|
-
import { colors } from "../../../theme/colors";
|
|
4
|
-
import { TextField } from "../../ui";
|
|
5
|
-
|
|
6
|
-
export function ManualPortfolioNamePanel({
|
|
7
|
-
portfolioName,
|
|
8
|
-
onNameChange,
|
|
9
|
-
editing,
|
|
10
|
-
inputRef,
|
|
11
|
-
}: {
|
|
12
|
-
portfolioName: string;
|
|
13
|
-
onNameChange: (name: string) => void;
|
|
14
|
-
editing: boolean;
|
|
15
|
-
inputRef: RefObject<InputRenderable | null>;
|
|
16
|
-
}) {
|
|
17
|
-
return (
|
|
18
|
-
<Box flexDirection="column" paddingX={2}>
|
|
19
|
-
<Box height={1}>
|
|
20
|
-
<Text fg={colors.textBright} attributes={TextAttributes.BOLD}>{"Name your portfolio"}</Text>
|
|
21
|
-
</Box>
|
|
22
|
-
<Box height={1} />
|
|
23
|
-
<Box height={1}>
|
|
24
|
-
<Text fg={colors.textDim}>{"Create watchlists later."}</Text>
|
|
25
|
-
</Box>
|
|
26
|
-
<Box height={2} />
|
|
27
|
-
<Box height={1}>
|
|
28
|
-
<Text fg={colors.text}>{"Portfolio name:"}</Text>
|
|
29
|
-
</Box>
|
|
30
|
-
<Box height={1}>
|
|
31
|
-
{editing ? (
|
|
32
|
-
<TextField
|
|
33
|
-
inputRef={inputRef}
|
|
34
|
-
value={portfolioName}
|
|
35
|
-
placeholder="Main Portfolio"
|
|
36
|
-
focused
|
|
37
|
-
backgroundColor={colors.panel}
|
|
38
|
-
textColor={colors.text}
|
|
39
|
-
placeholderColor={colors.textDim}
|
|
40
|
-
onChange={onNameChange}
|
|
41
|
-
onSubmit={() => {}}
|
|
42
|
-
/>
|
|
43
|
-
) : (
|
|
44
|
-
<Text fg={colors.textBright} attributes={TextAttributes.BOLD}>
|
|
45
|
-
{`> ${portfolioName}`}
|
|
46
|
-
</Text>
|
|
47
|
-
)}
|
|
48
|
-
</Box>
|
|
49
|
-
<Box height={2} />
|
|
50
|
-
<Box height={1} flexDirection="row">
|
|
51
|
-
<Text fg={colors.textDim}>{"After setup, use the command bar ("}</Text>
|
|
52
|
-
<Text fg={colors.text}>{"Ctrl+P"}</Text>
|
|
53
|
-
<Text fg={colors.textDim}>{") and"}</Text>
|
|
54
|
-
</Box>
|
|
55
|
-
<Box height={1} flexDirection="row">
|
|
56
|
-
<Text fg={colors.textDim}>{"type "}</Text>
|
|
57
|
-
<Text fg={colors.text} attributes={TextAttributes.BOLD}>{"DES AAPL"}</Text>
|
|
58
|
-
<Text fg={colors.textDim}>{" to open security details for a stock or ETF."}</Text>
|
|
59
|
-
</Box>
|
|
60
|
-
</Box>
|
|
61
|
-
);
|
|
62
|
-
}
|