gloomberb 0.3.7 → 0.4.1
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 +19 -8
- package/package.json +1 -1
- package/src/app.tsx +45 -69
- package/src/cli/base-converter.ts +31 -0
- package/src/cli/commands/search.ts +11 -3
- package/src/cli/commands/ticker.ts +22 -11
- package/src/cli/context.ts +27 -32
- package/src/cli/helpers.ts +1 -4
- package/src/cli/index.ts +140 -123
- package/src/cli/registry.test.ts +226 -0
- package/src/cli/registry.ts +201 -0
- package/src/cli.test.ts +219 -0
- package/src/components/chart/chart-controller.ts +309 -0
- package/src/components/chart/chart-data.ts +5 -6
- package/src/components/chart/chart-pane-settings.ts +27 -0
- package/src/components/chart/chart-resolution.test.ts +56 -0
- package/src/components/chart/chart-resolution.ts +362 -0
- package/src/components/chart/chart-types.ts +12 -4
- package/src/components/chart/chart-viewport.test.ts +25 -0
- package/src/components/chart/chart-viewport.ts +28 -0
- package/src/components/chart/comparison-chart-data.ts +20 -27
- package/src/components/chart/comparison-stock-chart.tsx +374 -99
- package/src/components/chart/stock-chart-renderer-switch.test.tsx +124 -0
- package/src/components/chart/stock-chart.tsx +455 -106
- package/src/components/command-bar/__snapshots__/command-bar.test.tsx.snap +4 -4
- package/src/components/command-bar/command-bar.test.tsx +650 -5
- package/src/components/command-bar/command-bar.tsx +363 -63
- package/src/components/command-bar/command-registry.ts +8 -0
- package/src/components/command-bar/helpers.test.ts +23 -1
- package/src/components/command-bar/helpers.ts +14 -5
- package/src/components/command-bar/pane-template-display.ts +12 -0
- package/src/components/command-bar/root-shortcuts.ts +2 -1
- package/src/components/command-bar/workflow-ops.ts +4 -2
- package/src/components/detail-feed-view.test.tsx +124 -49
- package/src/components/detail-feed-view.tsx +396 -160
- package/src/components/layout/floating-pane.tsx +4 -2
- package/src/components/layout/header.tsx +3 -3
- package/src/components/layout/pane-header.tsx +26 -2
- package/src/components/layout/pane-sizing.ts +6 -0
- package/src/components/layout/pane.tsx +5 -1
- package/src/components/layout/shell.test.tsx +77 -5
- package/src/components/layout/shell.tsx +67 -52
- package/src/components/layout/status-bar.test.tsx +66 -0
- package/src/components/layout/status-bar.tsx +26 -5
- package/src/components/onboarding/onboarding-wizard.test.tsx +65 -0
- package/src/components/onboarding/onboarding-wizard.tsx +5 -6
- package/src/components/ticker-list-table.test.tsx +83 -0
- package/src/components/ticker-list-table.tsx +181 -97
- package/src/components/ui/data-table.tsx +50 -5
- package/src/components/ui/index.ts +1 -0
- package/src/components/ui/page-stack-view.tsx +60 -0
- package/src/components/use-double-click-activation.ts +31 -0
- package/src/index.tsx +10 -10
- package/src/market-data/coordinator.test.ts +92 -4
- package/src/market-data/coordinator.ts +32 -5
- package/src/market-data/hooks.test.tsx +120 -0
- package/src/market-data/hooks.tsx +53 -16
- package/src/market-data/request-types.ts +4 -2
- package/src/market-data/selectors.ts +24 -58
- package/src/plugins/builtin/chat-controller.test.ts +400 -3
- package/src/plugins/builtin/chat-controller.ts +328 -35
- package/src/plugins/builtin/chat.test.tsx +118 -6
- package/src/plugins/builtin/chat.tsx +180 -116
- package/src/plugins/builtin/comparison-chart.test.tsx +66 -5
- package/src/plugins/builtin/comparison-chart.tsx +21 -1
- package/src/plugins/builtin/layout-manager.tsx +9 -0
- package/src/plugins/builtin/news.tsx +1 -11
- package/src/plugins/builtin/portfolio-list/cli/commands.ts +656 -0
- package/src/plugins/builtin/portfolio-list/command-bar.ts +122 -0
- package/src/plugins/builtin/portfolio-list/header.tsx +16 -34
- package/src/plugins/builtin/portfolio-list/index.tsx +5 -0
- package/src/plugins/builtin/portfolio-list/metrics.test.ts +61 -0
- package/src/plugins/builtin/portfolio-list/metrics.ts +2 -2
- package/src/plugins/builtin/portfolio-list/mutations.test.ts +187 -0
- package/src/plugins/builtin/portfolio-list/mutations.ts +226 -0
- package/src/plugins/builtin/portfolio-list/pane.tsx +39 -17
- package/src/plugins/builtin/portfolio-list/table.tsx +11 -2
- package/src/plugins/builtin/portfolio-list/use-throttled-cursor-symbol.test.tsx +163 -0
- package/src/plugins/builtin/portfolio-list/use-throttled-cursor-symbol.ts +81 -0
- package/src/plugins/builtin/sec.tsx +1 -11
- package/src/plugins/builtin/ticker-detail/chart-tab.tsx +13 -2
- package/src/plugins/builtin/ticker-detail/financials-tab.tsx +21 -0
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +45 -10
- package/src/plugins/builtin/ticker-detail/pane.tsx +35 -17
- package/src/plugins/builtin/ticker-detail/settings.ts +19 -1
- package/src/plugins/builtin/ticker-detail.test.tsx +47 -0
- package/src/plugins/catalog.ts +65 -0
- package/src/plugins/ibkr/broker-adapter.ts +28 -0
- package/src/plugins/ibkr/gateway-service.test.ts +67 -1
- package/src/plugins/ibkr/gateway-service.ts +147 -7
- package/src/plugins/ibkr/index.tsx +7 -1
- package/src/plugins/pane-manager.test.ts +1 -1
- package/src/plugins/plugin-runtime.tsx +27 -7
- package/src/plugins/prediction-markets/cli.ts +28 -0
- package/src/plugins/prediction-markets/controller-data.ts +132 -17
- package/src/plugins/prediction-markets/controller.ts +142 -122
- package/src/plugins/prediction-markets/index.tsx +7 -1
- package/src/plugins/prediction-markets/launch.ts +51 -16
- package/src/plugins/prediction-markets/metrics.ts +9 -5
- package/src/plugins/prediction-markets/pane.test.tsx +197 -57
- package/src/plugins/prediction-markets/pane.tsx +80 -155
- package/src/plugins/prediction-markets/services/fetch.ts +4 -0
- package/src/plugins/prediction-markets/table.tsx +6 -3
- package/src/plugins/prediction-markets/test-helpers.tsx +20 -5
- package/src/plugins/prediction-markets/types.ts +0 -1
- package/src/plugins/registry.ts +23 -0
- package/src/sources/gloomberb-cloud.test.ts +29 -0
- package/src/sources/gloomberb-cloud.ts +89 -1
- package/src/sources/provider-router.test.ts +265 -3
- package/src/sources/provider-router.ts +239 -11
- package/src/sources/yahoo-finance.test.ts +26 -0
- package/src/sources/yahoo-finance.ts +54 -3
- package/src/state/app-context-selector.test.tsx +99 -0
- package/src/state/app-context.test.ts +18 -0
- package/src/state/app-context.tsx +170 -65
- package/src/state/selectors.ts +25 -0
- package/src/theme/colors.ts +8 -8
- package/src/theme/themes.test.ts +2 -0
- package/src/theme/themes.ts +22 -10
- package/src/types/broker.ts +21 -0
- package/src/types/config.ts +17 -1
- package/src/types/data-provider.ts +18 -0
- package/src/types/financials.ts +31 -1
- package/src/types/plugin.ts +70 -0
- package/src/updater.test.ts +2 -0
- package/src/utils/api-client.test.ts +57 -0
- package/src/utils/api-client.ts +47 -12
- package/src/utils/back-navigation.ts +27 -0
- package/src/utils/format.test.ts +14 -0
- package/src/utils/format.ts +3 -3
- package/src/utils/market-status.ts +46 -1
- package/src/utils/quote-freshness.ts +127 -0
- package/src/utils/quote-resolution.test.ts +277 -0
- package/src/utils/quote-resolution.ts +641 -0
- package/src/utils/slugify.ts +3 -0
- package/src/utils/timestamp.ts +25 -0
- package/src/version.ts +1 -1
- package/src/cli/commands/portfolio.ts +0 -210
- package/src/cli/commands/watchlist.ts +0 -210
- package/src/plugins/builtin/data-providers.ts +0 -16
- package/src/sources/exchange-rates.ts +0 -18
- package/src/utils/ascii-chart.ts +0 -172
- package/src/utils/ticker-tokenizer.test.ts +0 -48
|
@@ -9,7 +9,9 @@ import {
|
|
|
9
9
|
createInitialState,
|
|
10
10
|
type AppAction,
|
|
11
11
|
} from "../../state/app-context";
|
|
12
|
+
import { MarketDataCoordinator, setSharedMarketDataCoordinator } from "../../market-data/coordinator";
|
|
12
13
|
import { cloneLayout, createDefaultConfig, type AppConfig } from "../../types/config";
|
|
14
|
+
import type { DataProvider } from "../../types/data-provider";
|
|
13
15
|
import type { PricePoint, TickerFinancials } from "../../types/financials";
|
|
14
16
|
import type { TickerRecord } from "../../types/ticker";
|
|
15
17
|
import { StockChart } from "./stock-chart";
|
|
@@ -19,6 +21,7 @@ const TEST_PANE_ID = "ticker-detail:test";
|
|
|
19
21
|
let testSetup: Awaited<ReturnType<typeof createTestRenderer>> | undefined;
|
|
20
22
|
let root: ReturnType<typeof createRoot> | undefined;
|
|
21
23
|
let harnessDispatch: ((action: AppAction) => void) | null = null;
|
|
24
|
+
let sharedCoordinator: MarketDataCoordinator | null = null;
|
|
22
25
|
const actEnvironment = globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean };
|
|
23
26
|
|
|
24
27
|
function makeTicker(symbol: string): TickerRecord {
|
|
@@ -100,8 +103,58 @@ async function flushFrames(count = 2) {
|
|
|
100
103
|
}
|
|
101
104
|
}
|
|
102
105
|
|
|
106
|
+
async function emitKeypress(event: { name?: string; sequence?: string }) {
|
|
107
|
+
await act(async () => {
|
|
108
|
+
testSetup!.renderer.keyInput.emit("keypress", {
|
|
109
|
+
ctrl: false,
|
|
110
|
+
meta: false,
|
|
111
|
+
option: false,
|
|
112
|
+
shift: false,
|
|
113
|
+
eventType: "press",
|
|
114
|
+
repeated: false,
|
|
115
|
+
...event,
|
|
116
|
+
} as never);
|
|
117
|
+
await testSetup!.renderOnce();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function makeProvider(historyBySymbol: Record<string, PricePoint[]>): DataProvider {
|
|
122
|
+
return {
|
|
123
|
+
id: "test-provider",
|
|
124
|
+
name: "Test Provider",
|
|
125
|
+
getTickerFinancials: async (symbol) => ({
|
|
126
|
+
annualStatements: [],
|
|
127
|
+
quarterlyStatements: [],
|
|
128
|
+
priceHistory: historyBySymbol[symbol] ?? [],
|
|
129
|
+
}),
|
|
130
|
+
getQuote: async (symbol) => ({
|
|
131
|
+
symbol,
|
|
132
|
+
price: historyBySymbol[symbol]?.[historyBySymbol[symbol]!.length - 1]?.close ?? 0,
|
|
133
|
+
currency: "USD",
|
|
134
|
+
change: 0,
|
|
135
|
+
changePercent: 0,
|
|
136
|
+
lastUpdated: Date.now(),
|
|
137
|
+
}),
|
|
138
|
+
getExchangeRate: async () => 1,
|
|
139
|
+
search: async () => [],
|
|
140
|
+
getNews: async () => [],
|
|
141
|
+
getArticleSummary: async () => null,
|
|
142
|
+
getPriceHistory: async (symbol) => historyBySymbol[symbol] ?? [],
|
|
143
|
+
getChartResolutionSupport: async () => [
|
|
144
|
+
{ resolution: "5m", maxRange: "1W" },
|
|
145
|
+
{ resolution: "15m", maxRange: "1M" },
|
|
146
|
+
{ resolution: "1h", maxRange: "3M" },
|
|
147
|
+
{ resolution: "1d", maxRange: "5Y" },
|
|
148
|
+
{ resolution: "1wk", maxRange: "ALL" },
|
|
149
|
+
{ resolution: "1mo", maxRange: "ALL" },
|
|
150
|
+
],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
103
154
|
afterEach(() => {
|
|
104
155
|
harnessDispatch = null;
|
|
156
|
+
sharedCoordinator = null;
|
|
157
|
+
setSharedMarketDataCoordinator(null);
|
|
105
158
|
if (root) {
|
|
106
159
|
act(() => {
|
|
107
160
|
root!.unmount();
|
|
@@ -116,6 +169,40 @@ afterEach(() => {
|
|
|
116
169
|
});
|
|
117
170
|
|
|
118
171
|
describe("StockChart renderer switching", () => {
|
|
172
|
+
test("keeps range and resolution controls visible when history is empty", async () => {
|
|
173
|
+
const symbol = "AAPL";
|
|
174
|
+
const config = makeChartConfig(symbol);
|
|
175
|
+
const ticker = makeTicker(symbol);
|
|
176
|
+
const provider = makeProvider({ [symbol]: [] });
|
|
177
|
+
sharedCoordinator = new MarketDataCoordinator(provider);
|
|
178
|
+
setSharedMarketDataCoordinator(sharedCoordinator);
|
|
179
|
+
const financials: TickerFinancials = {
|
|
180
|
+
annualStatements: [],
|
|
181
|
+
quarterlyStatements: [],
|
|
182
|
+
priceHistory: [],
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
actEnvironment.IS_REACT_ACT_ENVIRONMENT = true;
|
|
186
|
+
testSetup = await createTestRenderer({ width: 120, height: 32 });
|
|
187
|
+
root = createRoot(testSetup.renderer);
|
|
188
|
+
act(() => {
|
|
189
|
+
root!.render(
|
|
190
|
+
<ChartHarness
|
|
191
|
+
config={config}
|
|
192
|
+
ticker={ticker}
|
|
193
|
+
financials={financials}
|
|
194
|
+
/>,
|
|
195
|
+
);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
await flushFrames();
|
|
199
|
+
const frame = testSetup.captureCharFrame();
|
|
200
|
+
expect(frame).toContain("No price history available.");
|
|
201
|
+
expect(frame).toContain("1:1D");
|
|
202
|
+
expect(frame).toContain("2:1W");
|
|
203
|
+
expect(frame).toContain("AUTO");
|
|
204
|
+
});
|
|
205
|
+
|
|
119
206
|
test("switches from braille to kitty without crashing text updates", async () => {
|
|
120
207
|
const symbol = "AAPL";
|
|
121
208
|
const config = makeChartConfig(symbol);
|
|
@@ -162,4 +249,41 @@ describe("StockChart renderer switching", () => {
|
|
|
162
249
|
await flushFrames();
|
|
163
250
|
expect(testSetup.captureCharFrame()).toContain("AAPL");
|
|
164
251
|
});
|
|
252
|
+
|
|
253
|
+
test("applies preset hotkeys without reverting to the previous stored range", async () => {
|
|
254
|
+
const symbol = "AAPL";
|
|
255
|
+
const config = makeChartConfig(symbol);
|
|
256
|
+
const ticker = makeTicker(symbol);
|
|
257
|
+
const provider = makeProvider({ [symbol]: makeHistory(180) });
|
|
258
|
+
sharedCoordinator = new MarketDataCoordinator(provider);
|
|
259
|
+
setSharedMarketDataCoordinator(sharedCoordinator);
|
|
260
|
+
const financials: TickerFinancials = {
|
|
261
|
+
annualStatements: [],
|
|
262
|
+
quarterlyStatements: [],
|
|
263
|
+
priceHistory: makeHistory(180),
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
actEnvironment.IS_REACT_ACT_ENVIRONMENT = true;
|
|
267
|
+
testSetup = await createTestRenderer({ width: 120, height: 32 });
|
|
268
|
+
root = createRoot(testSetup.renderer);
|
|
269
|
+
act(() => {
|
|
270
|
+
root!.render(
|
|
271
|
+
<ChartHarness
|
|
272
|
+
config={config}
|
|
273
|
+
ticker={ticker}
|
|
274
|
+
financials={financials}
|
|
275
|
+
/>,
|
|
276
|
+
);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
await flushFrames(3);
|
|
280
|
+
expect(testSetup.captureCharFrame()).toContain("AAPL - 1W");
|
|
281
|
+
|
|
282
|
+
await emitKeypress({ name: "3", sequence: "3" });
|
|
283
|
+
await flushFrames(3);
|
|
284
|
+
|
|
285
|
+
const frame = testSetup.captureCharFrame();
|
|
286
|
+
expect(frame).toContain("AAPL - 15M");
|
|
287
|
+
expect(frame).not.toContain("AAPL - 1W");
|
|
288
|
+
});
|
|
165
289
|
});
|