@luxalgo/vela 0.5.0
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/LICENSE +201 -0
- package/NOTICE +28 -0
- package/README.md +135 -0
- package/dist/DataProvider-DKNDHpNv.d.cts +134 -0
- package/dist/DataProvider-Dzd-Erlk.d.ts +134 -0
- package/dist/chunk-7UFX5ZIG.js +5976 -0
- package/dist/chunk-GYD2THPV.js +252 -0
- package/dist/chunk-KCCZNKH7.js +19137 -0
- package/dist/chunk-KM6LHB3Y.js +76 -0
- package/dist/chunk-OVQKKXLZ.js +3978 -0
- package/dist/chunk-Q3XQHLIH.js +7 -0
- package/dist/chunk-RHIDOUFL.js +698 -0
- package/dist/contributions-hX3EUyjG.d.ts +1528 -0
- package/dist/contributions-o1GRKPI_.d.cts +1528 -0
- package/dist/history-Dzxz-MQj.d.ts +298 -0
- package/dist/history-LJkz4-sS.d.cts +298 -0
- package/dist/icons-BZYbJXSV.d.cts +10 -0
- package/dist/icons-BZYbJXSV.d.ts +10 -0
- package/dist/index.cjs +25294 -0
- package/dist/index.d.cts +1189 -0
- package/dist/index.d.ts +1189 -0
- package/dist/index.js +5 -0
- package/dist/keymap-CGOz5F5f.d.cts +64 -0
- package/dist/keymap-CGOz5F5f.d.ts +64 -0
- package/dist/options-Q-576hIi.d.cts +1545 -0
- package/dist/options-Q-576hIi.d.ts +1545 -0
- package/dist/plugin-D94muTV-.d.cts +405 -0
- package/dist/plugin-aGUD1epn.d.ts +405 -0
- package/dist/plugin.cjs +5967 -0
- package/dist/plugin.d.cts +7 -0
- package/dist/plugin.d.ts +7 -0
- package/dist/plugin.js +3 -0
- package/dist/providers/binance.cjs +390 -0
- package/dist/providers/binance.d.cts +62 -0
- package/dist/providers/binance.d.ts +62 -0
- package/dist/providers/binance.js +388 -0
- package/dist/providers/coinbase.cjs +462 -0
- package/dist/providers/coinbase.d.cts +59 -0
- package/dist/providers/coinbase.d.ts +59 -0
- package/dist/providers/coinbase.js +460 -0
- package/dist/providers/hyperliquid.cjs +361 -0
- package/dist/providers/hyperliquid.d.cts +54 -0
- package/dist/providers/hyperliquid.d.ts +54 -0
- package/dist/providers/hyperliquid.js +359 -0
- package/dist/side-panel-CT9ZwIGz.d.cts +63 -0
- package/dist/side-panel-CT9ZwIGz.d.ts +63 -0
- package/dist/ui.cjs +1030 -0
- package/dist/ui.d.cts +188 -0
- package/dist/ui.d.ts +188 -0
- package/dist/ui.js +3 -0
- package/dist/vela.global.js +26509 -0
- package/dist/vela.global.min.js +230 -0
- package/dist/widget.cjs +31178 -0
- package/dist/widget.d.cts +799 -0
- package/dist/widget.d.ts +799 -0
- package/dist/widget.js +1060 -0
- package/dist/workspace.cjs +31692 -0
- package/dist/workspace.d.cts +579 -0
- package/dist/workspace.d.ts +579 -0
- package/dist/workspace.js +1694 -0
- package/package.json +95 -0
|
@@ -0,0 +1,1528 @@
|
|
|
1
|
+
import { s as Millis, ab as InputSchema, aa as IndicatorMeta, P as PriceStyle, O as OHLCV, l as InputValue, j as IndicatorModel, i as MoveTarget, ax as SeriesSpec, a8 as Fill, B as Background, ap as PriceLine, _ as DrawingLine, W as DrawingBox, Z as DrawingLabel, a2 as DrawingPolyline, $ as DrawingLinefill, a4 as DrawingTable, f as IndicatorStatus, a as VisibleRange, c as VelaTheme, u as DrawingTypeKey, t as SnapMode, a0 as DrawingMode, I as IChartRenderer, R as RendererCapabilities, n as LegendActionView, U as Unsubscribe, C as CrosshairEvent, q as DataWindowReadout, m as SymbolPickerFn, aJ as PaneInfo, S as SerializedDrawing, a7 as DrawingsOption, D as Drawing, b as VelaOptions, A as AddIndicatorOptions, al as MarketSwitch, ak as MarketSnapshot, V as VisibleRangePreset, T as ThemeName } from './options-Q-576hIi.cjs';
|
|
2
|
+
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-DKNDHpNv.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A strategy's broker state at ONE bar — the flat summary a host reads while a script
|
|
6
|
+
* runs. Distinct from {@link TradeExecution}, which is a single order FILL the renderer
|
|
7
|
+
* paints: this is the account, not the drawing.
|
|
8
|
+
*
|
|
9
|
+
* Neutral by design: an engine translates its own vocabulary into these names, so host
|
|
10
|
+
* code reads the same fields whatever language the strategy was written in.
|
|
11
|
+
*/
|
|
12
|
+
interface StrategyState {
|
|
13
|
+
/** Signed contracts held (positive = long, negative = short, 0 = flat). */
|
|
14
|
+
position: number;
|
|
15
|
+
/** Average entry price of the open position (0 when flat). */
|
|
16
|
+
avgPrice: number;
|
|
17
|
+
/** Account value: capital + realized + unrealized. */
|
|
18
|
+
equity: number;
|
|
19
|
+
/** Unrealized P&L of the open position. */
|
|
20
|
+
openPnl: number;
|
|
21
|
+
/** Realized P&L, gross profit minus gross loss. */
|
|
22
|
+
netPnl: number;
|
|
23
|
+
grossProfit: number;
|
|
24
|
+
grossLoss: number;
|
|
25
|
+
/** Closed-trade outcome counts. */
|
|
26
|
+
wins: number;
|
|
27
|
+
losses: number;
|
|
28
|
+
even: number;
|
|
29
|
+
/** Largest peak-to-trough equity drop / trough-to-peak rise, in account currency. */
|
|
30
|
+
maxDrawdown: number;
|
|
31
|
+
maxRunup: number;
|
|
32
|
+
initialCapital: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* One ROUND TRIP of a strategy: an entry, and the exit that closed it when there is one.
|
|
36
|
+
* Coarser than {@link TradeExecution} (a fill) on purpose — this is what a host tabulates,
|
|
37
|
+
* exports, or reconciles against a broker.
|
|
38
|
+
*/
|
|
39
|
+
interface StrategyTrade {
|
|
40
|
+
/** Stable within a run; shared with the fills' `tradeId`. */
|
|
41
|
+
id: string;
|
|
42
|
+
side: 'long' | 'short';
|
|
43
|
+
/** Contracts (magnitude — `side` carries the direction). */
|
|
44
|
+
qty: number;
|
|
45
|
+
entry: StrategyFill;
|
|
46
|
+
/** Absent while the trade is still open. */
|
|
47
|
+
exit?: StrategyFill;
|
|
48
|
+
/** Still open at the last computed bar. */
|
|
49
|
+
open: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** One side of a {@link StrategyTrade}. */
|
|
52
|
+
interface StrategyFill {
|
|
53
|
+
/** The order id the script used (Pine's `strategy.entry("Long", …)`). */
|
|
54
|
+
id: string;
|
|
55
|
+
time: Millis;
|
|
56
|
+
price: number;
|
|
57
|
+
comment?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A cache-backed data gateway the engine uses to fetch ANY `(symbol, timeframe)`
|
|
62
|
+
* series it needs — the main series stays in-memory, but secondary series
|
|
63
|
+
* (Pine `request.security` HTF/LTF/cross-symbol) are fetched + cached through
|
|
64
|
+
* this so they get real, correctly-resolved data (no aggregation; timeframes
|
|
65
|
+
* kept separate). Provided by the orchestrator, backed by `MarketDataFeed`.
|
|
66
|
+
*/
|
|
67
|
+
type FetchSeries = (symbol: string, timeframe: string, range: BarRange) => Promise<OHLCV[]>;
|
|
68
|
+
/** The chart's visible bar-time window (epoch ms of the left/right edges). */
|
|
69
|
+
interface VisibleBarRange {
|
|
70
|
+
left: number;
|
|
71
|
+
right: number;
|
|
72
|
+
}
|
|
73
|
+
interface EngineAlert {
|
|
74
|
+
id: string;
|
|
75
|
+
message: string;
|
|
76
|
+
title?: string;
|
|
77
|
+
time: number;
|
|
78
|
+
barIndex: number;
|
|
79
|
+
freq?: string;
|
|
80
|
+
}
|
|
81
|
+
interface EngineWarning {
|
|
82
|
+
message: string;
|
|
83
|
+
method?: string;
|
|
84
|
+
bar: number;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* A source script that has been parsed (inputs + declaration metadata extracted)
|
|
88
|
+
* and is ready to execute. `token` is engine-internal and opaque to core — the
|
|
89
|
+
* engine reads it back in `execute()`.
|
|
90
|
+
*/
|
|
91
|
+
interface PreparedScript {
|
|
92
|
+
/** The language that produced this (the engine's `language`). */
|
|
93
|
+
language: string;
|
|
94
|
+
inputs: InputSchema[];
|
|
95
|
+
meta: IndicatorMeta;
|
|
96
|
+
/**
|
|
97
|
+
* Whether the script references a viewport built-in (e.g. Pine
|
|
98
|
+
* `chart.left_visible_bar_time`). Detected statically at prepare; an engine
|
|
99
|
+
* may refine it in place after the first run.
|
|
100
|
+
*/
|
|
101
|
+
reactsToViewport: boolean;
|
|
102
|
+
readonly token: unknown;
|
|
103
|
+
}
|
|
104
|
+
/** What an engine can do — lets the orchestrator route without engine-specific checks. */
|
|
105
|
+
interface EngineCapabilities {
|
|
106
|
+
/** Can maintain a persistent incremental context for live ticks (vs a full re-run). */
|
|
107
|
+
streaming: boolean;
|
|
108
|
+
/** Understands viewport-dependent execution (`chart.*_visible_bar_time`-style). */
|
|
109
|
+
visibleRange: boolean;
|
|
110
|
+
/** Exposes an inputs schema (drives the renderer's settings dialog). */
|
|
111
|
+
inputs: boolean;
|
|
112
|
+
}
|
|
113
|
+
/** Market context an execution needs. Vela owns the bars; this is the metadata. */
|
|
114
|
+
interface ExecutionMarket {
|
|
115
|
+
symbol: string;
|
|
116
|
+
timeframe: string;
|
|
117
|
+
/** Provider symbol metadata (Pine `syminfo.*`). May be absent or partial: the feed
|
|
118
|
+
* fetches it asynchronously (the `MarketDataFeed.symbolInfo` port is synchronous), so
|
|
119
|
+
* the first run can see a synthesized fallback and later runs the real values. */
|
|
120
|
+
symbolInfo?: SymbolInfo;
|
|
121
|
+
/** The chart's active price style. An engine adapter encodes a bar-transforming style
|
|
122
|
+
* into the chart's ticker identity (the extended ticker `"SYM;heikinashi"` — see
|
|
123
|
+
* `chartTickerOf`), from which chart-type builtins derive. The BARS an execution
|
|
124
|
+
* receives are already the style's view — this is metadata, not a request to
|
|
125
|
+
* transform. Optional; engines may ignore it. */
|
|
126
|
+
chartStyle?: PriceStyle;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* One execution request. Vela owns the bars and passes them in — the engine
|
|
130
|
+
* never fetches market data. `mode: 'static'` runs on demand (and re-runs when
|
|
131
|
+
* the session is poked); `mode: 'live'` keeps a streaming context that emits per
|
|
132
|
+
* tick (only requested when `capabilities.streaming`).
|
|
133
|
+
*/
|
|
134
|
+
interface ExecutionRequest {
|
|
135
|
+
prepared: PreparedScript;
|
|
136
|
+
market: ExecutionMarket;
|
|
137
|
+
/** The initial bar snapshot. */
|
|
138
|
+
bars: OHLCV[];
|
|
139
|
+
/** Live accessor to Vela's canonical array (read on each re-run / tick). */
|
|
140
|
+
getBars?: () => OHLCV[];
|
|
141
|
+
/**
|
|
142
|
+
* Fetch a secondary `(symbol, timeframe)` series (Pine `request.security`
|
|
143
|
+
* HTF/LTF/cross-symbol). Cache-backed by Vela's data feed. Absent ≡ no
|
|
144
|
+
* gateway (secondary fetches degrade to empty).
|
|
145
|
+
*/
|
|
146
|
+
fetchSeries?: FetchSeries;
|
|
147
|
+
inputs?: Record<string, InputValue>;
|
|
148
|
+
visibleRange?: VisibleBarRange;
|
|
149
|
+
mode: 'static' | 'live';
|
|
150
|
+
/**
|
|
151
|
+
* Where the chart's history load stands at session start. `'backfill'` = older
|
|
152
|
+
* chunks are still streaming in (the bars snapshot is a PARTIAL history); the
|
|
153
|
+
* engine decides run policy — the bundled engines defer their first run until
|
|
154
|
+
* the `'complete'` notification, a progressive engine may run immediately.
|
|
155
|
+
* Absent ≡ `'complete'` (history fully loaded — today's behavior).
|
|
156
|
+
*/
|
|
157
|
+
historyState?: 'backfill' | 'complete';
|
|
158
|
+
}
|
|
159
|
+
/** The event sink. `onModel` fires on the first run and on every re-run / live tick. */
|
|
160
|
+
interface ExecutionHandlers {
|
|
161
|
+
onModel(model: IndicatorModel): void;
|
|
162
|
+
onAlert?(alert: EngineAlert): void;
|
|
163
|
+
onWarning?(warning: EngineWarning): void;
|
|
164
|
+
onError?(error: Error): void;
|
|
165
|
+
/** A `static` run finished; not fired for an open live stream. */
|
|
166
|
+
onDone?(): void;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Why the chart's bars changed, carried on {@link ExecutionSession.notifyBars}.
|
|
170
|
+
* `'backfill'` = older history chunks prepended (the load is still in progress);
|
|
171
|
+
* `'complete'` = the history backfill just finished (fires once). `undefined` =
|
|
172
|
+
* a live tick / new bar at the tail — today's meaning. Run policy is the
|
|
173
|
+
* ENGINE's: the bundled engines skip `'backfill'` and run on `'complete'`/ticks;
|
|
174
|
+
* a progressive engine may re-run on every reason.
|
|
175
|
+
*/
|
|
176
|
+
type BarsChangeReason = 'backfill' | 'complete';
|
|
177
|
+
/** A running execution — the control surface the orchestrator drives. */
|
|
178
|
+
/** A read-only, serializable snapshot of a running script's execution context. */
|
|
179
|
+
interface EngineContextSnapshot {
|
|
180
|
+
language: string;
|
|
181
|
+
/** 'computing' while a static run is in flight, 'streaming' on a live session, 'idle' after done/stop. */
|
|
182
|
+
phase: 'idle' | 'computing' | 'streaming';
|
|
183
|
+
/** Index of the last computed bar. */
|
|
184
|
+
barIndex: number;
|
|
185
|
+
meta: {
|
|
186
|
+
title: string;
|
|
187
|
+
overlay: boolean;
|
|
188
|
+
precision?: number;
|
|
189
|
+
shorttitle?: string;
|
|
190
|
+
};
|
|
191
|
+
/** Named plot outputs, per key: index-aligned `{time, value}` points. */
|
|
192
|
+
plots: Record<string, ReadonlyArray<{
|
|
193
|
+
time: number;
|
|
194
|
+
value: unknown;
|
|
195
|
+
}>>;
|
|
196
|
+
/**
|
|
197
|
+
* The script's variables at the last computed bar, keyed by the names WRITTEN in the
|
|
198
|
+
* source. An engine that mangles names internally un-mangles them here: a transpiler's
|
|
199
|
+
* scoping scheme is its own business and must not reach host code. Values are the
|
|
200
|
+
* serializable subset (never live references, never per-bar series buffers).
|
|
201
|
+
*/
|
|
202
|
+
variables: Record<string, unknown>;
|
|
203
|
+
/**
|
|
204
|
+
* A STRATEGY's broker state at the last computed bar — absent for a plain indicator,
|
|
205
|
+
* and for an engine whose language has no strategy concept. Neutral by contract: the
|
|
206
|
+
* engine translates its own vocabulary into these fields.
|
|
207
|
+
*/
|
|
208
|
+
strategy?: StrategyState;
|
|
209
|
+
/** The strategy's round trips, closed then open. Absent when there are none. Select it
|
|
210
|
+
* explicitly — a deep backtest's ledger is large. */
|
|
211
|
+
trades?: StrategyTrade[];
|
|
212
|
+
warnings: EngineWarning[];
|
|
213
|
+
}
|
|
214
|
+
/** Keys a caller may restrict a context snapshot to (limits worker structured-clone cost). */
|
|
215
|
+
type ContextSelect = ReadonlyArray<keyof EngineContextSnapshot>;
|
|
216
|
+
interface ExecutionSession {
|
|
217
|
+
/**
|
|
218
|
+
* OPTIONAL capability — resolve a read-only context snapshot (null when the run
|
|
219
|
+
* hasn't produced one yet). Always a COPY: mutating it never touches the engine.
|
|
220
|
+
*/
|
|
221
|
+
getContext?(select?: ContextSelect): Promise<EngineContextSnapshot | null>;
|
|
222
|
+
/** Tear down (stops any streaming / incremental re-execution). */
|
|
223
|
+
stop(): void;
|
|
224
|
+
/** Re-run / re-stream with merged input overrides. */
|
|
225
|
+
update(inputs: Record<string, InputValue>): void;
|
|
226
|
+
/** Update the viewport window (re-runs viewport-dependent scripts; no-op otherwise). */
|
|
227
|
+
setVisibleRange(range: VisibleBarRange): void;
|
|
228
|
+
/** Signal that Vela's bars changed. No reason = live tick; see {@link BarsChangeReason}. */
|
|
229
|
+
notifyBars(reason?: BarsChangeReason): void;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* The scripting-engine abstraction. The orchestrator talks only to this, so every
|
|
233
|
+
* concrete engine is swappable and Vela itself SHIPS none — engines are separate
|
|
234
|
+
* packages (Pine Script: `@luxalgo/vela-pinets`) or host code written against this
|
|
235
|
+
* port (see docs/contributing/adding-an-engine.md). Engines are registered by `language` and selected per
|
|
236
|
+
* `addIndicator({ language })`; market data is owned by Vela's
|
|
237
|
+
* `MarketDataFeed` and passed into `execute`.
|
|
238
|
+
*/
|
|
239
|
+
interface ScriptingEngine {
|
|
240
|
+
/** Language id this engine handles, e.g. `'pine'`. The registry key. */
|
|
241
|
+
readonly language: string;
|
|
242
|
+
readonly capabilities: EngineCapabilities;
|
|
243
|
+
/** Parse a script: extract its inputs schema + declaration metadata. No market data. */
|
|
244
|
+
prepare(source: string, instanceId: string): Promise<PreparedScript>;
|
|
245
|
+
/** Execute (static or live). Returns a session control handle. */
|
|
246
|
+
execute(req: ExecutionRequest, handlers: ExecutionHandlers): ExecutionSession;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** Per-indicator events emitted on `handle.on(...)`. */
|
|
250
|
+
interface IndicatorEventMap extends Record<string, unknown> {
|
|
251
|
+
ready: undefined;
|
|
252
|
+
error: {
|
|
253
|
+
error: Error;
|
|
254
|
+
};
|
|
255
|
+
alert: {
|
|
256
|
+
id: string;
|
|
257
|
+
message: string;
|
|
258
|
+
title?: string;
|
|
259
|
+
time: number;
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* What `chart.addIndicator(...)` returns to the developer. The handle is usable
|
|
264
|
+
* synchronously; data renders when execution resolves (see `on('ready')`).
|
|
265
|
+
*/
|
|
266
|
+
interface IndicatorHandle {
|
|
267
|
+
readonly id: string;
|
|
268
|
+
readonly title: string;
|
|
269
|
+
/** The script source this indicator was added with. `undefined` for a NATIVE
|
|
270
|
+
* (core-computed) indicator — there is no script to show. What a host editor
|
|
271
|
+
* opens when a legend action asks for "the code behind this row". */
|
|
272
|
+
readonly source?: string;
|
|
273
|
+
/** Inputs parsed from the Pine source (populated once the script is prepared). */
|
|
274
|
+
readonly inputs: readonly InputSchema[];
|
|
275
|
+
/** Whether the indicator is currently shown (vs hidden). Hidden indicators stop computing. */
|
|
276
|
+
readonly visible: boolean;
|
|
277
|
+
setInput(key: string, value: InputValue): void;
|
|
278
|
+
setInputs(values: Record<string, InputValue>): void;
|
|
279
|
+
/**
|
|
280
|
+
* Hide or show the indicator. Hiding **suspends** it — its visuals are dropped (the legend
|
|
281
|
+
* row stays, marked hidden) and its computation stops (the engine session is torn down), so a
|
|
282
|
+
* hidden indicator consumes no resources. Showing re-runs it over the current bars.
|
|
283
|
+
*/
|
|
284
|
+
setVisible(visible: boolean): void;
|
|
285
|
+
/**
|
|
286
|
+
* Move (or merge) this indicator to another pane: the main price pane (`'price'`),
|
|
287
|
+
* an existing pane (`{ pane: id }`), or a fresh pane (`{ newPane: {...} }`, optionally
|
|
288
|
+
* placed relative to an existing pane). Merging into a pane it doesn't own gives it its
|
|
289
|
+
* own scale column. No-op (with a warning) on a renderer without pane management.
|
|
290
|
+
*/
|
|
291
|
+
moveTo(target: MoveTarget): void;
|
|
292
|
+
on<K extends keyof IndicatorEventMap>(event: K, handler: (payload: IndicatorEventMap[K]) => void): () => void;
|
|
293
|
+
/**
|
|
294
|
+
* Read-only snapshot of the engine's execution context (variables, plots, the
|
|
295
|
+
* script's return value…). Resolves null when the engine lacks the capability or
|
|
296
|
+
* nothing has run yet. Always a copy — never a live reference. `select` limits the
|
|
297
|
+
* extracted keys (keeps worker transfers small). Re-pull on `'context:changed'`.
|
|
298
|
+
*/
|
|
299
|
+
context(select?: ContextSelect): Promise<EngineContextSnapshot | null>;
|
|
300
|
+
remove(): void;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** A symbol resolved to a registered provider. */
|
|
304
|
+
interface Resolved {
|
|
305
|
+
/** Registered provider name (normalized — lower-case). */
|
|
306
|
+
provider: string;
|
|
307
|
+
/** Ticker the provider expects (any `provider:` prefix stripped, any `.ext` kept). */
|
|
308
|
+
ticker: string;
|
|
309
|
+
}
|
|
310
|
+
/** The parts of a raw symbol string. */
|
|
311
|
+
interface ParsedSymbol {
|
|
312
|
+
/** Lower-cased provider segment, or null when the symbol is bare. */
|
|
313
|
+
provider: string | null;
|
|
314
|
+
/** Everything after the `provider:` prefix (includes any `.ext`). */
|
|
315
|
+
ticker: string;
|
|
316
|
+
/** Best-effort trailing `.ext` token (provider-defined, never used for routing). */
|
|
317
|
+
ext?: string;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* The chart's data control surface (`chart.data`) — the sibling of `chart.renderer`.
|
|
322
|
+
* Registers market-data providers and queries the registry (resolve a symbol, list
|
|
323
|
+
* providers/symbols, fetch per-symbol metadata).
|
|
324
|
+
*
|
|
325
|
+
* It operates on the default {@link MultiProviderFeed}. If a fully custom feed was
|
|
326
|
+
* injected via `deps.dataFeed`, that feed manages its own data and the
|
|
327
|
+
* registration/query methods warn + no-op (mirroring `chart.renderer.set` on an
|
|
328
|
+
* unsupported feature).
|
|
329
|
+
*/
|
|
330
|
+
declare class DataControl {
|
|
331
|
+
private readonly registry;
|
|
332
|
+
constructor(feed: MarketDataFeed);
|
|
333
|
+
/**
|
|
334
|
+
* Register (or replace) a data provider under `name`. Any symbol prefixed `name:`
|
|
335
|
+
* (case-insensitive), or a bare symbol the provider's index contains, routes to it.
|
|
336
|
+
* Returns synchronously and is chainable: it kicks a background symbol-index build,
|
|
337
|
+
* and if the chart symbol resolves through this provider the parked initial load
|
|
338
|
+
* fires. Await `chart.ready()` for that load, or `chart.data.ready()` for the index.
|
|
339
|
+
*/
|
|
340
|
+
registerProvider(name: string, provider: DataProvider): this;
|
|
341
|
+
/** Remove a registered provider. */
|
|
342
|
+
unregisterProvider(name: string): this;
|
|
343
|
+
/** Metadata for every registered provider. */
|
|
344
|
+
providers(): ProviderInfo[];
|
|
345
|
+
/** Resolve a symbol string to `{ provider, ticker }`, or null if nothing serves it. */
|
|
346
|
+
resolve(symbol: string): Resolved | null;
|
|
347
|
+
/**
|
|
348
|
+
* The registered provider INSTANCE under `name` — the seam for EXTENDED provider
|
|
349
|
+
* surfaces: a provider may implement interfaces beyond the `DataProvider` port
|
|
350
|
+
* (extra data kinds, venue-specific APIs); consumers retrieve the instance and
|
|
351
|
+
* narrow it with their own type guard. Returns undefined if the name is unknown
|
|
352
|
+
* (or a custom `deps.dataFeed` bypasses the registry).
|
|
353
|
+
*/
|
|
354
|
+
providerInstance(name: string): DataProvider | undefined;
|
|
355
|
+
/** Indexed symbols for one provider (or all) — for autocomplete. */
|
|
356
|
+
symbols(provider?: string): SymbolDescriptor[];
|
|
357
|
+
/** Per-symbol metadata (Pine `syminfo.*`), resolved through the owning provider. */
|
|
358
|
+
symbolInfo(symbol: string): Promise<SymbolInfo | undefined>;
|
|
359
|
+
/**
|
|
360
|
+
* The full resolved capabilities for `symbol` — per-instrument when the provider refines
|
|
361
|
+
* them (`capabilitiesFor`), else its provider-wide declaration. Null while nothing
|
|
362
|
+
* resolves the symbol (a provider may still be registering), so callers that can act
|
|
363
|
+
* later should re-read rather than latch the first answer.
|
|
364
|
+
*/
|
|
365
|
+
capabilities(symbol: string): ProviderCapabilities | null;
|
|
366
|
+
/** Resolves when every registered provider's eager index has settled. */
|
|
367
|
+
ready(): Promise<void>;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* The renderer-neutral visual parts a native indicator emits each compute — a subset of
|
|
372
|
+
* {@link import('../model/indicator').IndicatorModel}. The orchestrator wraps this into a full
|
|
373
|
+
* model (stamping id / pane / native tag), so the native path reuses the entire mount → legend →
|
|
374
|
+
* settings → patch pipeline. (A native indicator with a *bespoke* renderer layer — e.g. the volume
|
|
375
|
+
* columns — instead pushes its payload through the dedicated renderer seam, `pushData`.)
|
|
376
|
+
*/
|
|
377
|
+
interface NativeIndicatorOutput {
|
|
378
|
+
series?: SeriesSpec[];
|
|
379
|
+
fills?: Fill[];
|
|
380
|
+
backgrounds?: Background[];
|
|
381
|
+
priceLines?: PriceLine[];
|
|
382
|
+
lines?: DrawingLine[];
|
|
383
|
+
boxes?: DrawingBox[];
|
|
384
|
+
labels?: DrawingLabel[];
|
|
385
|
+
polylines?: DrawingPolyline[];
|
|
386
|
+
linefills?: DrawingLinefill[];
|
|
387
|
+
tables?: DrawingTable[];
|
|
388
|
+
}
|
|
389
|
+
/** Services the host gives a running native indicator. */
|
|
390
|
+
interface NativeIndicatorContext {
|
|
391
|
+
readonly symbol: string;
|
|
392
|
+
readonly timeframe: string;
|
|
393
|
+
readonly live: boolean;
|
|
394
|
+
/** The canonical bar array (a live accessor — always current). */
|
|
395
|
+
bars(): readonly OHLCV[];
|
|
396
|
+
/** Market-data access (trades / capabilities) for data-driven natives. */
|
|
397
|
+
readonly data: DataControl;
|
|
398
|
+
/** Push a fresh render output; the chart mounts it (first call) or patches it (subsequent). */
|
|
399
|
+
emit(out: NativeIndicatorOutput): void;
|
|
400
|
+
/**
|
|
401
|
+
* Push a BESPOKE render payload to the renderer's native layer for this indicator's type (for a
|
|
402
|
+
* native whose visuals aren't ordinary series/fills — e.g. volume/VPVR push their layer config).
|
|
403
|
+
*/
|
|
404
|
+
pushData(data: unknown): void;
|
|
405
|
+
/** Set the indicator's legend status: `'loading'` (fetching), `'live'` (live-updating), `'idle'`. */
|
|
406
|
+
setStatus(status: IndicatorStatus): void;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* A core-computed (non-Pine) indicator instance — the compute + lifecycle behind one on-chart
|
|
410
|
+
* native indicator. The orchestrator owns one per instance and drives it through these hooks; the
|
|
411
|
+
* instance pushes its visuals via {@link NativeIndicatorContext.emit}. Implementations live in this
|
|
412
|
+
* folder (one file per type) and self-register a {@link NativeIndicatorDescriptor}.
|
|
413
|
+
*/
|
|
414
|
+
interface NativeIndicator {
|
|
415
|
+
/** Begin: compute + emit the first output. */
|
|
416
|
+
start(ctx: NativeIndicatorContext, inputs: Record<string, InputValue>): void;
|
|
417
|
+
/** A live tick arrived (bars changed) — recompute + emit. */
|
|
418
|
+
onBars(): void;
|
|
419
|
+
/** The viewport changed (scroll/zoom) — for range-aware natives (see `reactsToViewport`). */
|
|
420
|
+
onViewport(range: VisibleRange): void;
|
|
421
|
+
/** Settings changed — recompute + emit. */
|
|
422
|
+
setInputs(inputs: Record<string, InputValue>): void;
|
|
423
|
+
/** Hidden — stop timers/fetches (free resources); the instance + its state are kept for resume. */
|
|
424
|
+
suspend(): void;
|
|
425
|
+
/** Shown again — resume + re-emit. */
|
|
426
|
+
resume(): void;
|
|
427
|
+
/** Removed — full teardown (clear caches, stop timers). */
|
|
428
|
+
stop(): void;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Static description + factory for a native-indicator TYPE, registered once via
|
|
432
|
+
* {@link registerNativeIndicator}. The descriptor is the type (metadata + capability); `create()`
|
|
433
|
+
* mints a per-instance {@link NativeIndicator}.
|
|
434
|
+
*/
|
|
435
|
+
interface NativeIndicatorDescriptor {
|
|
436
|
+
readonly type: string;
|
|
437
|
+
readonly title: string;
|
|
438
|
+
readonly paneHint: 'price' | 'new';
|
|
439
|
+
readonly overlay: boolean;
|
|
440
|
+
/** Whether instances react to viewport changes (drives the orchestrator's viewport poke). */
|
|
441
|
+
readonly reactsToViewport?: boolean;
|
|
442
|
+
/** Marks the type as beta — surfaced in the catalog so a host "add indicator" UI can badge it. */
|
|
443
|
+
readonly beta?: boolean;
|
|
444
|
+
inputsSchema(): InputSchema[];
|
|
445
|
+
defaultInputs(): Record<string, InputValue>;
|
|
446
|
+
create(): NativeIndicator;
|
|
447
|
+
/**
|
|
448
|
+
* Whether this native indicator applies to `symbol` (a type may need a provider capability).
|
|
449
|
+
* Absent ⇒ always supported. Used to gate auto-add + an "add native indicator" menu.
|
|
450
|
+
*/
|
|
451
|
+
isSupported?(symbol: string, data: DataControl): boolean | Promise<boolean>;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* One entry in the "add native indicator" catalog: the type's static metadata plus its live state
|
|
455
|
+
* on a specific chart — whether it applies to the current symbol (`supported`) and whether an
|
|
456
|
+
* instance is already present (`present`, since natives are single-instance per type). Produced by
|
|
457
|
+
* `chart.availableNativeIndicators()`.
|
|
458
|
+
*/
|
|
459
|
+
interface NativeIndicatorInfo {
|
|
460
|
+
readonly type: string;
|
|
461
|
+
readonly title: string;
|
|
462
|
+
/** Applies to the current symbol (a type may need data the provider lacks). */
|
|
463
|
+
readonly supported: boolean;
|
|
464
|
+
/** An instance is already on the chart (a second add is a no-op). */
|
|
465
|
+
readonly present: boolean;
|
|
466
|
+
/** The type is flagged beta (for a badge in the picker). */
|
|
467
|
+
readonly beta?: boolean;
|
|
468
|
+
}
|
|
469
|
+
/** Register a native-indicator type so `chart.addNativeIndicator(type)` can create it. */
|
|
470
|
+
declare function registerNativeIndicator(descriptor: NativeIndicatorDescriptor): void;
|
|
471
|
+
/** Remove a registered native-indicator type (mainly for tests). */
|
|
472
|
+
declare function unregisterNativeIndicator(type: string): void;
|
|
473
|
+
/** Look up a registered native-indicator descriptor (undefined if the type isn't registered). */
|
|
474
|
+
declare function getNativeIndicator(type: string): NativeIndicatorDescriptor | undefined;
|
|
475
|
+
/** All registered native-indicator types (for a host "add native indicator" menu). */
|
|
476
|
+
declare function nativeIndicatorTypes(): string[];
|
|
477
|
+
/** All registered native-indicator descriptors (for building a catalog with metadata + capability). */
|
|
478
|
+
declare function nativeIndicatorDescriptors(): NativeIndicatorDescriptor[];
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Why a script computed. The distinction that matters most is `'tick'` vs `'bar'`: a tick
|
|
482
|
+
* refines the bar that is still open, so its values can still move, while `'bar'` means a
|
|
483
|
+
* new bar opened and everything before it is now settled. Anything that records, alerts,
|
|
484
|
+
* or exports should key off `'bar'`.
|
|
485
|
+
*/
|
|
486
|
+
type ScriptRunCause =
|
|
487
|
+
/** The first computation over the loaded history (also every re-computation an engine
|
|
488
|
+
* makes while a deep backfill is still landing — see {@link ScriptRun.complete}). */
|
|
489
|
+
'history'
|
|
490
|
+
/** The forming bar changed (a live tick). */
|
|
491
|
+
| 'tick'
|
|
492
|
+
/** A new bar opened — the previous one is final. */
|
|
493
|
+
| 'bar'
|
|
494
|
+
/** An input was edited. */
|
|
495
|
+
| 'inputs'
|
|
496
|
+
/** The visible range moved (viewport-aware scripts only). */
|
|
497
|
+
| 'viewport'
|
|
498
|
+
/** The chart's market changed and the script re-executed over the new bars. */
|
|
499
|
+
| 'market';
|
|
500
|
+
/**
|
|
501
|
+
* One computation of one script, as host code observes it — the payload of `script:run`
|
|
502
|
+
* and what `runScript()` resolves to.
|
|
503
|
+
*
|
|
504
|
+
* The split is deliberate: everything FLAT and at the current bar rides the run itself,
|
|
505
|
+
* while anything historical and unbounded (the trade ledger, a plot's full history) is a
|
|
506
|
+
* call you make only when you need it, so a per-tick listener never ships a 5 000-row
|
|
507
|
+
* ledger it will not read.
|
|
508
|
+
*/
|
|
509
|
+
interface ScriptRun {
|
|
510
|
+
/** The indicator id — the same one `chart.indicators()` and the lifecycle events carry. */
|
|
511
|
+
readonly id: string;
|
|
512
|
+
/** The title the script DECLARED (`strategy("SMA cross")`), not a placeholder. */
|
|
513
|
+
readonly title: string;
|
|
514
|
+
readonly kind: 'indicator' | 'strategy';
|
|
515
|
+
readonly cause: ScriptRunCause;
|
|
516
|
+
/** This script's first computed run. */
|
|
517
|
+
readonly first: boolean;
|
|
518
|
+
/** Index of the last computed bar. */
|
|
519
|
+
readonly bar: number;
|
|
520
|
+
/** Open time of that bar. */
|
|
521
|
+
readonly time: Millis;
|
|
522
|
+
/** That bar is still open, so these values are provisional. False on a static chart
|
|
523
|
+
* and on any run computed over settled history. */
|
|
524
|
+
readonly forming: boolean;
|
|
525
|
+
/** The run saw the FULL requested history. False only while an engine that computes
|
|
526
|
+
* progressively is still being fed a deep backfill — a deeper run will follow. */
|
|
527
|
+
readonly complete: boolean;
|
|
528
|
+
/** Each named plot's value at {@link bar}; `null` marks a gap. */
|
|
529
|
+
readonly plots: Readonly<Record<string, number | null>>;
|
|
530
|
+
/** The script's own variables at {@link bar}, keyed by the names WRITTEN in the source.
|
|
531
|
+
* Empty for an engine that exposes none. */
|
|
532
|
+
readonly vars: Readonly<Record<string, unknown>>;
|
|
533
|
+
/** Broker state at {@link bar} — present iff `kind === 'strategy'` and the engine
|
|
534
|
+
* reports it. */
|
|
535
|
+
readonly strategy?: StrategyState;
|
|
536
|
+
/** Warnings this script has raised so far. */
|
|
537
|
+
readonly warnings: readonly EngineWarning[];
|
|
538
|
+
/** The strategy's round trips, closed then open. Async because the ledger is unbounded:
|
|
539
|
+
* it never rides the run. Empty for an indicator. */
|
|
540
|
+
trades(): Promise<readonly StrategyTrade[]>;
|
|
541
|
+
/** One plot's full history. Async for the same reason. Empty for an unknown key. */
|
|
542
|
+
series(key: string): Promise<ReadonlyArray<{
|
|
543
|
+
time: Millis;
|
|
544
|
+
value: number | null;
|
|
545
|
+
}>>;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* What `chart.runScript()` resolves to: the script's first run, plus the controls for the
|
|
549
|
+
* indicator it put on the chart. Never rejects — a compile or runtime failure resolves
|
|
550
|
+
* with `ok: false` and the indicator is removed again (no dead legend row).
|
|
551
|
+
*/
|
|
552
|
+
interface ScriptRunResult {
|
|
553
|
+
ok: boolean;
|
|
554
|
+
/** The first computed run on success; null on failure. */
|
|
555
|
+
run: ScriptRun | null;
|
|
556
|
+
/** The failure, or null. */
|
|
557
|
+
error: Error | null;
|
|
558
|
+
/** Follow this script's later runs. Returns an unsubscriber. No-op after a failure. */
|
|
559
|
+
onUpdate(handler: (run: ScriptRun) => void): () => void;
|
|
560
|
+
/** Take the script off the chart. No-op after a failure. */
|
|
561
|
+
remove(): void;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/** Chart-level events emitted on `chart.on(...)`. */
|
|
565
|
+
interface VelaEventMap extends Record<string, unknown> {
|
|
566
|
+
ready: undefined;
|
|
567
|
+
/**
|
|
568
|
+
* The chart's market switched IN PLACE via `setMarket` — symbol, provider, timeframe,
|
|
569
|
+
* or offline data changed (a depth-only reload does not fire). Fires after the new
|
|
570
|
+
* market's history is painted and every consumer restarted. `prev` carries the
|
|
571
|
+
* previous identity so hosts can re-key per-symbol state (e.g. swap user-drawing
|
|
572
|
+
* documents between symbols).
|
|
573
|
+
*/
|
|
574
|
+
'market:changed': {
|
|
575
|
+
symbol: string;
|
|
576
|
+
timeframe: string;
|
|
577
|
+
prev: {
|
|
578
|
+
symbol: string;
|
|
579
|
+
timeframe: string;
|
|
580
|
+
};
|
|
581
|
+
};
|
|
582
|
+
/**
|
|
583
|
+
* A bar load began with nothing painted: the FIRST load (fires during construction —
|
|
584
|
+
* subscribers attached later see only its `load:end`), or an identity switch
|
|
585
|
+
* (symbol/provider/timeframe), which blanks the old series in the same breath. Fires
|
|
586
|
+
* before the first fetch — plugins, extensions and custom indicators hide or reset
|
|
587
|
+
* their own visuals here. Exactly one `load:end` follows. A depth-only reload
|
|
588
|
+
* (`bars`) keeps the chart painted and fires neither.
|
|
589
|
+
*/
|
|
590
|
+
'load:start': {
|
|
591
|
+
symbol: string;
|
|
592
|
+
timeframe: string;
|
|
593
|
+
firstLoad: boolean;
|
|
594
|
+
};
|
|
595
|
+
/**
|
|
596
|
+
* The load ended: its first bars painted (`bars` > 0 — on deep histories the quick
|
|
597
|
+
* preview, before the full depth), or it ended with none (`bars` = 0 — a failed
|
|
598
|
+
* fetch, an empty market, or a parked symbol nothing serves). Counterpart of
|
|
599
|
+
* `load:start`; plugins restore or rebuild their visuals here.
|
|
600
|
+
*/
|
|
601
|
+
'load:end': {
|
|
602
|
+
symbol: string;
|
|
603
|
+
timeframe: string;
|
|
604
|
+
bars: number;
|
|
605
|
+
};
|
|
606
|
+
'indicator:added': {
|
|
607
|
+
id: string;
|
|
608
|
+
};
|
|
609
|
+
'indicator:removed': {
|
|
610
|
+
id: string;
|
|
611
|
+
};
|
|
612
|
+
'indicator:error': {
|
|
613
|
+
id: string;
|
|
614
|
+
error: Error;
|
|
615
|
+
};
|
|
616
|
+
/** No registered provider can serve the chart symbol — the load is PARKED, not failed:
|
|
617
|
+
* it resumes by itself if a capable provider registers later. */
|
|
618
|
+
'data:unresolved': {
|
|
619
|
+
symbol: string;
|
|
620
|
+
providers: string[];
|
|
621
|
+
};
|
|
622
|
+
/** An indicator was moved/merged to another pane (`chart.panes` / legend / object tree). */
|
|
623
|
+
'indicator:moved': {
|
|
624
|
+
id: string;
|
|
625
|
+
paneId: string;
|
|
626
|
+
};
|
|
627
|
+
/** An indicator was shown/hidden (legend eye, `handle.setVisible`, or object tree). */
|
|
628
|
+
'indicator:visibility': {
|
|
629
|
+
id: string;
|
|
630
|
+
visible: boolean;
|
|
631
|
+
};
|
|
632
|
+
/** A pane's layout changed: order, collapse/maximize, creation or removal. */
|
|
633
|
+
'pane:changed': undefined;
|
|
634
|
+
/**
|
|
635
|
+
* The app theme changed — `chart.setTheme(...)` or the in-chart settings dialog's
|
|
636
|
+
* Canvas → Theme row. Payload is the RESOLVED theme; host chrome around the chart
|
|
637
|
+
* (toolbars, panels, page shells) re-skins from it. Not fired for plot-only
|
|
638
|
+
* cosmetic edits (`layout.background` through the config), which deliberately
|
|
639
|
+
* leave the app theme alone.
|
|
640
|
+
*/
|
|
641
|
+
'theme:changed': VelaTheme;
|
|
642
|
+
/** A study pane was reordered one slot (`dir`) — carries enough to invert for undo/redo. */
|
|
643
|
+
'pane:moved': {
|
|
644
|
+
paneId: string;
|
|
645
|
+
dir: 'up' | 'down';
|
|
646
|
+
};
|
|
647
|
+
/** A user drawing was created (interactively or via `chart.drawings.add`). */
|
|
648
|
+
'drawing:created': {
|
|
649
|
+
id: string;
|
|
650
|
+
};
|
|
651
|
+
/** A user drawing's anchors/style/text changed. */
|
|
652
|
+
'drawing:edited': {
|
|
653
|
+
id: string;
|
|
654
|
+
};
|
|
655
|
+
/** Selection changed (`id` is null when nothing is selected). */
|
|
656
|
+
'drawing:selected': {
|
|
657
|
+
id: string | null;
|
|
658
|
+
};
|
|
659
|
+
/** The favorite-tool set changed (star toggles or a bulk restore). */
|
|
660
|
+
'drawing:favorites': {
|
|
661
|
+
favorites: string[];
|
|
662
|
+
};
|
|
663
|
+
/** The armed drawing tool changed — toolbar click, one-shot tool finishing (back to
|
|
664
|
+
* the pointer, `null`), or a programmatic `drawings.setTool`. */
|
|
665
|
+
'drawing:tool': {
|
|
666
|
+
type: DrawingTypeKey | null;
|
|
667
|
+
};
|
|
668
|
+
/** The magnet snap mode changed (in-chart toolbar or `drawings.setSnapMode`). */
|
|
669
|
+
'drawing:snap': {
|
|
670
|
+
mode: SnapMode;
|
|
671
|
+
};
|
|
672
|
+
/** Stay-in-drawing-mode changed (in-chart toolbar or `drawings.setStayMode`) — when
|
|
673
|
+
* on, finishing a drawing leaves the tool armed. */
|
|
674
|
+
'drawing:stay': {
|
|
675
|
+
on: boolean;
|
|
676
|
+
};
|
|
677
|
+
/** The renderer-local mode changed: measure ruler, eraser, or none — including the
|
|
678
|
+
* mutual-exclusion exits (arming a tool leaves measure/eraser). */
|
|
679
|
+
'drawing:mode': {
|
|
680
|
+
mode: DrawingMode;
|
|
681
|
+
};
|
|
682
|
+
/** A user drawing was removed. */
|
|
683
|
+
'drawing:removed': {
|
|
684
|
+
id: string;
|
|
685
|
+
};
|
|
686
|
+
/** The user requested a drawing's settings popup. */
|
|
687
|
+
'drawing:settings': {
|
|
688
|
+
id: string;
|
|
689
|
+
};
|
|
690
|
+
/**
|
|
691
|
+
* A SCRIPT computed — the first run over the history, a live tick, a new bar, an input
|
|
692
|
+
* edit, a viewport move, a market switch. The payload carries the run itself (title,
|
|
693
|
+
* cause, the plots/variables/broker state at the computed bar), so a listener reads it
|
|
694
|
+
* directly instead of resolving a handle and pulling a snapshot. Throttled to ~1/s per
|
|
695
|
+
* indicator while streaming, and only emitted for engines that expose an execution
|
|
696
|
+
* context. Native (core-computed) indicators never fire it — they run no script.
|
|
697
|
+
*/
|
|
698
|
+
'script:run': ScriptRun;
|
|
699
|
+
/** An indicator's execution context advanced (run finished, or throttled during
|
|
700
|
+
* streaming) — re-pull `handle.context()` if you consume it. Prefer `script:run`,
|
|
701
|
+
* which delivers the data rather than a signal to go fetch it. */
|
|
702
|
+
'context:changed': {
|
|
703
|
+
id: string;
|
|
704
|
+
};
|
|
705
|
+
/** A live tick: the forming bar was updated or a new bar appended. */
|
|
706
|
+
bar: OHLCV;
|
|
707
|
+
/**
|
|
708
|
+
* The visible time range moved (pan/zoom/fit — fires per applied change, NOT
|
|
709
|
+
* debounced; the engine re-run debounce is separate). Payload = `{from, to}` in
|
|
710
|
+
* epoch-ms. The seam viewport-sync links between charts build on.
|
|
711
|
+
*/
|
|
712
|
+
'viewport:changed': {
|
|
713
|
+
from: number;
|
|
714
|
+
to: number;
|
|
715
|
+
};
|
|
716
|
+
/** A deep-history backfill chunk landed (`loaded` of `target` bars are on the chart). */
|
|
717
|
+
'history:progress': {
|
|
718
|
+
loaded: number;
|
|
719
|
+
target: number;
|
|
720
|
+
};
|
|
721
|
+
/**
|
|
722
|
+
* The history load finished: `'depth'` = the requested bar count is loaded, `'genesis'` =
|
|
723
|
+
* the source has nothing older (full available history), `'aborted'` = a fetch failed or
|
|
724
|
+
* the data was non-monotonic — the chart keeps what loaded. Fires exactly once, including
|
|
725
|
+
* for small/offline charts (immediately after their single load).
|
|
726
|
+
*/
|
|
727
|
+
'history:complete': {
|
|
728
|
+
reason: 'depth' | 'genesis' | 'aborted';
|
|
729
|
+
oldestTime: number;
|
|
730
|
+
barsLoaded: number;
|
|
731
|
+
};
|
|
732
|
+
alert: EngineAlert;
|
|
733
|
+
warning: EngineWarning;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* A renderer-agnostic count of the graphic elements one indicator generated — the
|
|
738
|
+
* deterministic oracle signal. It confirms the core *produced* the elements (engine +
|
|
739
|
+
* model mapping), independent of any renderer. Whether a renderer actually *drew* them
|
|
740
|
+
* is a separate (visual) check.
|
|
741
|
+
*/
|
|
742
|
+
interface IndicatorSummary {
|
|
743
|
+
id: string;
|
|
744
|
+
title: string;
|
|
745
|
+
overlay: boolean;
|
|
746
|
+
paneId?: string;
|
|
747
|
+
/** A native (core-computed) indicator, and its type — absent/false for a Pine indicator. */
|
|
748
|
+
native: boolean;
|
|
749
|
+
nativeType?: string;
|
|
750
|
+
/** Value-series counts keyed by kind (line/area/step/histogram/columns/circles/cross/candle/bar/markers). */
|
|
751
|
+
series: Record<string, number>;
|
|
752
|
+
fills: number;
|
|
753
|
+
backgrounds: number;
|
|
754
|
+
priceLines: number;
|
|
755
|
+
lines: number;
|
|
756
|
+
boxes: number;
|
|
757
|
+
labels: number;
|
|
758
|
+
polylines: number;
|
|
759
|
+
linefills: number;
|
|
760
|
+
tables: number;
|
|
761
|
+
barColors: number;
|
|
762
|
+
trades: number;
|
|
763
|
+
inputs: number;
|
|
764
|
+
}
|
|
765
|
+
/** A snapshot of everything the Vela core has generated for the mounted indicators. */
|
|
766
|
+
interface SceneInspection {
|
|
767
|
+
indicators: IndicatorSummary[];
|
|
768
|
+
/** Sums across all indicators, for convenient whole-scene assertions. */
|
|
769
|
+
totals: {
|
|
770
|
+
panes: number;
|
|
771
|
+
series: number;
|
|
772
|
+
fills: number;
|
|
773
|
+
backgrounds: number;
|
|
774
|
+
priceLines: number;
|
|
775
|
+
lines: number;
|
|
776
|
+
boxes: number;
|
|
777
|
+
labels: number;
|
|
778
|
+
polylines: number;
|
|
779
|
+
linefills: number;
|
|
780
|
+
tables: number;
|
|
781
|
+
barColors: number;
|
|
782
|
+
trades: number;
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* The public control surface for the active renderer — `chart.renderer`. A thin
|
|
788
|
+
* facade over the renderer port: get/set/inspect render features without exposing
|
|
789
|
+
* the internal orchestration methods (`setBars`, `mountIndicator`, …). A key the
|
|
790
|
+
* active renderer doesn't support warns in the console and is ignored — the chart
|
|
791
|
+
* is never touched.
|
|
792
|
+
*/
|
|
793
|
+
declare class RendererControl {
|
|
794
|
+
private readonly renderer;
|
|
795
|
+
constructor(renderer: IChartRenderer);
|
|
796
|
+
/** The active renderer's identity, e.g. `'native'` or `'lwc'`. */
|
|
797
|
+
get name(): string;
|
|
798
|
+
/** What the active renderer can draw (drives graceful degradation). */
|
|
799
|
+
get capabilities(): RendererCapabilities;
|
|
800
|
+
/** Whether the active renderer supports a feature — use to show/hide a UI control. */
|
|
801
|
+
supports(feature: string): boolean;
|
|
802
|
+
/** Read a feature's current value (`undefined` if unsupported). */
|
|
803
|
+
get(feature: string): unknown;
|
|
804
|
+
/**
|
|
805
|
+
* Set one feature (`set('glow', 0.6)`) or several at once
|
|
806
|
+
* (`set({ logScale: true, upColor: '#fff' })`). A key the active renderer does
|
|
807
|
+
* not support emits a console warning and is ignored, with no effect on the UI.
|
|
808
|
+
*/
|
|
809
|
+
set(feature: string | Record<string, unknown>, value?: unknown): this;
|
|
810
|
+
/**
|
|
811
|
+
* Wire the legend rows' HOST-CONTRIBUTED actions (the shells route the plugin
|
|
812
|
+
* registry through this; see `registerLegendAction`). Silent on a renderer without
|
|
813
|
+
* the seam — contributed legend actions simply never show there, same graceful
|
|
814
|
+
* degradation as the sync ghost crosshair.
|
|
815
|
+
*/
|
|
816
|
+
setLegendActions(provider: ((indicatorId: string) => LegendActionView[]) | null): void;
|
|
817
|
+
/**
|
|
818
|
+
* Export the current chart as a PNG data URL, or null if the active renderer
|
|
819
|
+
* doesn't support it (warns). DOM overlays (tables, legend) are not included.
|
|
820
|
+
*/
|
|
821
|
+
screenshot(): string | null;
|
|
822
|
+
/**
|
|
823
|
+
* The active renderer's full cosmetic config as a serializable, versioned JSON
|
|
824
|
+
* document — persist it (templates, saved settings) and feed it back to
|
|
825
|
+
* `applyConfig`. Returns null if the renderer has no rich config (warns).
|
|
826
|
+
*/
|
|
827
|
+
getConfig(): unknown;
|
|
828
|
+
/**
|
|
829
|
+
* Apply a (possibly partial) config document from `getConfig()` — load a template
|
|
830
|
+
* or restore saved settings. Malformed/unknown fields are ignored; no indicator
|
|
831
|
+
* re-run. No-ops with a warning if the renderer has no rich config.
|
|
832
|
+
*/
|
|
833
|
+
applyConfig(config: unknown): this;
|
|
834
|
+
/**
|
|
835
|
+
* Subscribe to cosmetic-config changes (`applyConfig` — the in-chart settings dialog
|
|
836
|
+
* commits through it). Host chrome that mirrors a config value (a bottom-bar timezone)
|
|
837
|
+
* re-pulls {@link get}/{@link getConfig} here. Silent no-op unsubscribe on a renderer
|
|
838
|
+
* without a rich config.
|
|
839
|
+
*/
|
|
840
|
+
onConfigChanged(cb: () => void): Unsubscribe;
|
|
841
|
+
/**
|
|
842
|
+
* Subscribe to crosshair movement — `time`/`price` under the cursor, per-series values,
|
|
843
|
+
* and the hovered bar's OHLC (null fields when the cursor leaves the chart). This is the
|
|
844
|
+
* public seam host chrome (status lines, data windows) builds on.
|
|
845
|
+
*/
|
|
846
|
+
onCrosshairMove(cb: (e: CrosshairEvent) => void): Unsubscribe;
|
|
847
|
+
/**
|
|
848
|
+
* The current data-window readout — the hovered bar's date/time and OHLCV plus every
|
|
849
|
+
* indicator's value there, each already formatted on its pane's scale (the latest bar when
|
|
850
|
+
* the cursor is off the plot). Pair it with {@link onCrosshairMove} to drive a data-window
|
|
851
|
+
* panel. Null on a renderer that doesn't provide the readout.
|
|
852
|
+
*/
|
|
853
|
+
dataWindowReadout(): DataWindowReadout | null;
|
|
854
|
+
/**
|
|
855
|
+
* Wire (or clear with `null`) the host's symbol picker for the settings dialog's `input.symbol`
|
|
856
|
+
* control — the host opens its own ticker-selection UI and reports the chosen symbol back.
|
|
857
|
+
* No-ops with a warning if the active renderer doesn't support it (only the native renderer does).
|
|
858
|
+
*/
|
|
859
|
+
setSymbolPicker(picker: SymbolPickerFn | null): this;
|
|
860
|
+
/**
|
|
861
|
+
* Move keyboard focus back onto the chart's interactive surface — call after a host
|
|
862
|
+
* control (a shared toolbar button) stole focus, so chart/drawing shortcuts keep
|
|
863
|
+
* working. Silent no-op on a renderer without a focusable surface.
|
|
864
|
+
*/
|
|
865
|
+
focus(): this;
|
|
866
|
+
/** Whether the active renderer can display an EXTERNAL (synced) crosshair. */
|
|
867
|
+
get supportsExternalCrosshair(): boolean;
|
|
868
|
+
/**
|
|
869
|
+
* Show (or clear, with `null`) a data-space ghost crosshair driven from OUTSIDE
|
|
870
|
+
* this chart — the multi-chart crosshair-sync seam. Silent no-op on a renderer
|
|
871
|
+
* without the capability (see {@link supportsExternalCrosshair}).
|
|
872
|
+
*/
|
|
873
|
+
setExternalCrosshair(time: number | null, price?: number | null): this;
|
|
874
|
+
/**
|
|
875
|
+
* Close any in-chart dialogs the active renderer owns (indicator settings, chart-settings
|
|
876
|
+
* gear) — for keeping host dialogs mutually exclusive with the renderer's. Silent no-op if
|
|
877
|
+
* the renderer has no such dialogs; safe to call speculatively.
|
|
878
|
+
*/
|
|
879
|
+
closeDialogs(): this;
|
|
880
|
+
/**
|
|
881
|
+
* Open (or toggle) the renderer's in-chart settings dialog — silent no-op without one.
|
|
882
|
+
* Pass a section title (e.g. `'Canvas'`) to land on that tab; an unknown one opens the
|
|
883
|
+
* dialog on its first tab, and with a section an open dialog switches tab instead of closing.
|
|
884
|
+
*/
|
|
885
|
+
openSettings(section?: string): this;
|
|
886
|
+
/** Contribute host settings tabs (callback rows) to the renderer's settings dialog —
|
|
887
|
+
* e.g. the widget's Status line toggles. Silent no-op without a dialog. */
|
|
888
|
+
setSettingsSections(sections: ReadonlyArray<{
|
|
889
|
+
title: string;
|
|
890
|
+
rows: readonly unknown[];
|
|
891
|
+
}>): this;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
/** Callback surface `PanesControl` uses to drive the orchestrator. */
|
|
895
|
+
interface PaneController {
|
|
896
|
+
/** Whether the active renderer supports pane management (move/merge/reorder/collapse). */
|
|
897
|
+
paneManagementSupported(): boolean;
|
|
898
|
+
listPanes(): PaneInfo[];
|
|
899
|
+
movePane(paneId: string, dir: 'up' | 'down'): void;
|
|
900
|
+
removePaneAndIndicators(paneId: string): void;
|
|
901
|
+
collapsePane(paneId: string, collapsed: boolean): void;
|
|
902
|
+
maximizePane(paneId: string | null): void;
|
|
903
|
+
moveIndicator(id: string, target: MoveTarget): void;
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* The public pane control surface — `chart.panes`. Lists panes with their indicators
|
|
907
|
+
* and moves/merges/reorders/collapses/maximizes them. On a renderer without pane
|
|
908
|
+
* management every mutation warns and no-ops (and `list()` still reports the panes).
|
|
909
|
+
*/
|
|
910
|
+
declare class PanesControl {
|
|
911
|
+
private readonly controller;
|
|
912
|
+
constructor(controller: PaneController);
|
|
913
|
+
/** Whether the active renderer supports pane management (use to show/hide host UI). */
|
|
914
|
+
get supported(): boolean;
|
|
915
|
+
/** The current panes (top-to-bottom by `order`) with the indicators each holds. */
|
|
916
|
+
list(): PaneInfo[];
|
|
917
|
+
/** Move a pane one slot up or down in the stack (the price pane stays pinned on top). */
|
|
918
|
+
move(paneId: string, dir: 'up' | 'down'): this;
|
|
919
|
+
/** Remove a pane and every indicator in it (the price pane can't be removed). */
|
|
920
|
+
remove(paneId: string): this;
|
|
921
|
+
/** Collapse a pane to a thin strip, or restore it. */
|
|
922
|
+
collapse(paneId: string, collapsed?: boolean): this;
|
|
923
|
+
/** Maximize one pane to fill the plot, or restore the split (`null`). */
|
|
924
|
+
maximize(paneId: string | null): this;
|
|
925
|
+
/** Move/merge an indicator to a pane — sugar for `handle.moveTo(...)` by id. */
|
|
926
|
+
moveIndicator(id: string, target: MoveTarget): this;
|
|
927
|
+
private guard;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
type EventHandler<T> = (payload: T) => void;
|
|
931
|
+
/** Minimal typed pub/sub. Handler errors are isolated (logged, never thrown). */
|
|
932
|
+
declare class TypedEventBus<Events extends Record<string, unknown>> {
|
|
933
|
+
private readonly handlers;
|
|
934
|
+
on<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): () => void;
|
|
935
|
+
off<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): void;
|
|
936
|
+
/** Whether anyone is listening — lets an emitter skip building an expensive payload. */
|
|
937
|
+
hasListeners<K extends keyof Events>(event: K): boolean;
|
|
938
|
+
emit<K extends keyof Events>(event: K, payload: Events[K]): void;
|
|
939
|
+
clear(): void;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/** Versioned persistence envelope for a chart's user drawings. */
|
|
943
|
+
interface DrawingsDocument {
|
|
944
|
+
version: 1;
|
|
945
|
+
drawings: SerializedDrawing[];
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/** Optional seed for a programmatic {@link DrawingController.add}. */
|
|
949
|
+
interface AddInit {
|
|
950
|
+
paneId?: string;
|
|
951
|
+
anchors?: SerializedDrawing['anchors'];
|
|
952
|
+
style?: Partial<SerializedDrawing['style']>;
|
|
953
|
+
text?: SerializedDrawing['text'];
|
|
954
|
+
/** Per-type extras (e.g. a glyph stamp's `glyph`, a fib tool's `levels`). */
|
|
955
|
+
props?: SerializedDrawing['props'];
|
|
956
|
+
/** Draw-order key. Defaults to just under the pane's price on a renderer with
|
|
957
|
+
* `drawingDepth` — the candles read on top of a fresh drawing; pass an explicit key
|
|
958
|
+
* for any other slot in the stack. */
|
|
959
|
+
zIndex?: number;
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Renderer-agnostic owner of the user-drawing model + tool/selection state. Holds
|
|
963
|
+
* the {@link DrawingStore} (source of truth), pushes snapshots to the renderer
|
|
964
|
+
* through {@link IDrawingsRendererPort}, and turns renderer intents into store
|
|
965
|
+
* mutations + `drawing:*` events. Inert (but persistence still works) when the
|
|
966
|
+
* active renderer lacks `userDrawings` — that's the LwC path.
|
|
967
|
+
*/
|
|
968
|
+
declare class DrawingController {
|
|
969
|
+
private readonly events;
|
|
970
|
+
private readonly store;
|
|
971
|
+
private readonly history;
|
|
972
|
+
private readonly port;
|
|
973
|
+
private readonly enabled;
|
|
974
|
+
private activeTool;
|
|
975
|
+
/** Mirror of the renderer's sticky magnet mode (the renderer default is 'off'). */
|
|
976
|
+
private snapMode;
|
|
977
|
+
/** When on, finishing a drawing leaves the tool armed (instead of one-shot disarm). */
|
|
978
|
+
private stayInDrawingMode;
|
|
979
|
+
/** Mirror of the renderer-local mode (measure/eraser/none). */
|
|
980
|
+
private mode;
|
|
981
|
+
/** FAVORITE tool types (insertion-ordered) — user prefs, not document data. */
|
|
982
|
+
private favs;
|
|
983
|
+
private selectedIds;
|
|
984
|
+
private clipboard;
|
|
985
|
+
private readonly lastStyle;
|
|
986
|
+
private readonly subs;
|
|
987
|
+
constructor(renderer: IChartRenderer, events: TypedEventBus<VelaEventMap>, option: DrawingsOption | undefined);
|
|
988
|
+
/** Whether the active renderer supports interactive drawings. */
|
|
989
|
+
get supported(): boolean;
|
|
990
|
+
setTool(type: DrawingTypeKey | null): void;
|
|
991
|
+
getTool(): DrawingTypeKey | null;
|
|
992
|
+
getSnapMode(): SnapMode;
|
|
993
|
+
setSnapMode(mode: SnapMode): void;
|
|
994
|
+
getStayMode(): boolean;
|
|
995
|
+
setStayMode(on: boolean): void;
|
|
996
|
+
getMode(): DrawingMode;
|
|
997
|
+
setMode(mode: DrawingMode): void;
|
|
998
|
+
showToolbar(visible: boolean): void;
|
|
999
|
+
/** The favorite tool types, in the order they were starred. */
|
|
1000
|
+
favorites(): DrawingTypeKey[];
|
|
1001
|
+
isFavorite(type: DrawingTypeKey): boolean;
|
|
1002
|
+
/** Star/unstar one tool. Unknown types are ignored; no-ops don't emit. */
|
|
1003
|
+
setFavorite(type: DrawingTypeKey, on: boolean): void;
|
|
1004
|
+
/** Replace the whole favorite set (bulk restore) — unknown types are dropped. */
|
|
1005
|
+
setFavorites(types: readonly DrawingTypeKey[]): void;
|
|
1006
|
+
private pushFavorites;
|
|
1007
|
+
setToolbar(option: DrawingsOption): void;
|
|
1008
|
+
/** Push per-tool shortcut hints (pre-formatted display strings) to the toolbar flyouts. */
|
|
1009
|
+
setToolShortcuts(map: Readonly<Partial<Record<DrawingTypeKey, string>>>): void;
|
|
1010
|
+
add(type: DrawingTypeKey, init?: AddInit): Drawing | null;
|
|
1011
|
+
remove(id: string): void;
|
|
1012
|
+
/** Apply a partial record to a drawing (headless write-back from a custom UI). */
|
|
1013
|
+
update(id: string, patch: Partial<SerializedDrawing>): void;
|
|
1014
|
+
/** Apply several partial records as ONE undo step (e.g. hiding/locking/reordering a group). */
|
|
1015
|
+
updateMany(patches: ReadonlyArray<{
|
|
1016
|
+
id: string;
|
|
1017
|
+
patch: Partial<SerializedDrawing>;
|
|
1018
|
+
}>): void;
|
|
1019
|
+
/** Delete several drawings as ONE undo step (the public face of {@link deleteMany}). */
|
|
1020
|
+
removeMany(ids: readonly string[]): void;
|
|
1021
|
+
setLocked(id: string, v: boolean): void;
|
|
1022
|
+
setVisible(id: string, v: boolean): void;
|
|
1023
|
+
bringToFront(id: string): void;
|
|
1024
|
+
sendToBack(id: string): void;
|
|
1025
|
+
/** The top of the pane's series stack — what a front drawing has to clear. 0 when the
|
|
1026
|
+
* renderer keeps drawings on their own layer (no shared z space). */
|
|
1027
|
+
private seriesTopZ;
|
|
1028
|
+
/** The bottom of the pane's series stack — what a backmost drawing has to undercut. */
|
|
1029
|
+
private seriesBottomZ;
|
|
1030
|
+
/** Where a NEW drawing starts: just under the pane's price so the candles read on top of it
|
|
1031
|
+
* (falling back to just under the pane's top series where there is no price — a study
|
|
1032
|
+
* pane). Half a key down never ties a series; drawings tying each other paint in insertion
|
|
1033
|
+
* order, so consecutive new drawings still stack newest-in-front. Undefined without a
|
|
1034
|
+
* shared z space — the store then places it over the other drawings, its own layer's top. */
|
|
1035
|
+
private startZ;
|
|
1036
|
+
/** Programmatically select drawings (host UI → chart): shows the on-chart handles + toolbar.
|
|
1037
|
+
* `additive` toggles membership (matching shift-click) instead of replacing. */
|
|
1038
|
+
select(ids: readonly string[], additive?: boolean): void;
|
|
1039
|
+
/** Open a drawing's on-chart settings popup (and select it) — a click on it, driven from a host UI. */
|
|
1040
|
+
openSettings(id: string): void;
|
|
1041
|
+
undo(): void;
|
|
1042
|
+
redo(): void;
|
|
1043
|
+
canUndo(): boolean;
|
|
1044
|
+
canRedo(): boolean;
|
|
1045
|
+
/** Duplicate drawings in place (clones land on the source, auto-selected → "duplicate then drag"). */
|
|
1046
|
+
duplicate(ids: readonly string[]): Drawing[];
|
|
1047
|
+
clone(id: string): Drawing | null;
|
|
1048
|
+
/** Copy drawings into the in-memory clipboard (no model change, no event). */
|
|
1049
|
+
copy(ids: readonly string[]): void;
|
|
1050
|
+
paste(): Drawing[];
|
|
1051
|
+
all(): SerializedDrawing[];
|
|
1052
|
+
toJSON(): DrawingsDocument;
|
|
1053
|
+
fromJSON(doc: unknown): void;
|
|
1054
|
+
destroy(): void;
|
|
1055
|
+
/** Set/extend the selection. `additive` toggles membership (shift-click) vs replacing it. */
|
|
1056
|
+
private setSelection;
|
|
1057
|
+
/** Restore a history snapshot, reconciling selection against what survived. */
|
|
1058
|
+
private restoreSnapshot;
|
|
1059
|
+
/** Delete drawings as one undo step; prune them from the selection. */
|
|
1060
|
+
private deleteMany;
|
|
1061
|
+
/** Add clones (fresh ids, fresh mount-order z) as one undo step + select them. */
|
|
1062
|
+
private insertClones;
|
|
1063
|
+
private resolve;
|
|
1064
|
+
/** Remember a drawing's style as the "last used" for its type (seeds the next one). */
|
|
1065
|
+
private captureStyle;
|
|
1066
|
+
private sync;
|
|
1067
|
+
/** Renderer gesture → authoritative store mutation + event. */
|
|
1068
|
+
private onIntent;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* The chart's drawing control surface (`chart.drawings`) — sibling of
|
|
1073
|
+
* `chart.data` / `chart.renderer`. Activate tools, create/mutate drawings
|
|
1074
|
+
* programmatically, and persist them. Always present; on a renderer without the
|
|
1075
|
+
* `userDrawings` capability the interactive methods warn + no-op (the
|
|
1076
|
+
* {@link DataControl} pattern), while `toJSON`/`fromJSON`/`all` still round-trip
|
|
1077
|
+
* because the model is core-owned.
|
|
1078
|
+
*/
|
|
1079
|
+
declare class DrawingsControl {
|
|
1080
|
+
private readonly ctrl;
|
|
1081
|
+
constructor(ctrl: DrawingController);
|
|
1082
|
+
/** Whether the active renderer supports interactive drawings. */
|
|
1083
|
+
get supported(): boolean;
|
|
1084
|
+
/** Arm a tool — the next click(s) place it. `null` returns to select/idle. */
|
|
1085
|
+
setTool(type: DrawingTypeKey | null): this;
|
|
1086
|
+
/** The currently armed tool (`null` = select/idle). Mirrors in-chart toolbar clicks
|
|
1087
|
+
* and one-shot tools disarming — listen on `drawing:tool` to follow changes. */
|
|
1088
|
+
getTool(): DrawingTypeKey | null;
|
|
1089
|
+
/** Set the sticky magnet snap mode (`'off' | 'weak' | 'strong'`). */
|
|
1090
|
+
setSnapMode(mode: SnapMode): this;
|
|
1091
|
+
/** The current magnet snap mode — follow changes on `drawing:snap`. */
|
|
1092
|
+
getSnapMode(): SnapMode;
|
|
1093
|
+
/** Keep the armed tool after each placement (`true`) or one-shot disarm (`false`). */
|
|
1094
|
+
setStayMode(on: boolean): this;
|
|
1095
|
+
/** Whether tools stay armed after placement — follow changes on `drawing:stay`. */
|
|
1096
|
+
getStayMode(): boolean;
|
|
1097
|
+
/** Enter/exit a renderer-local mode: `'measure'` (transient ruler), `'eraser'`, or
|
|
1098
|
+
* `null` (none). Mutually exclusive with each other and with any armed tool — the
|
|
1099
|
+
* renderer enforces the exclusion and the outcome lands on `drawing:mode`. */
|
|
1100
|
+
setMode(mode: DrawingMode): this;
|
|
1101
|
+
/** The current renderer-local mode — follow changes on `drawing:mode`. */
|
|
1102
|
+
getMode(): DrawingMode;
|
|
1103
|
+
/** Show or hide the on-chart drawing toolbar. */
|
|
1104
|
+
showToolbar(visible?: boolean): this;
|
|
1105
|
+
/** Reconfigure the toolbar groups/tools live. */
|
|
1106
|
+
setToolbar(option: DrawingsOption): this;
|
|
1107
|
+
/** Show per-tool shortcut hints in the toolbar flyouts. Values are PRE-FORMATTED
|
|
1108
|
+
* display strings (e.g. `'Alt+T'`, `'⌥T'`) — the host owns the keymap and the
|
|
1109
|
+
* platform formatting, so hints always match the host's actual bindings. */
|
|
1110
|
+
setToolShortcuts(map: Readonly<Partial<Record<DrawingTypeKey, string>>>): this;
|
|
1111
|
+
/** Create a drawing programmatically (no clicking). Returns it, or null if unsupported. */
|
|
1112
|
+
add(type: DrawingTypeKey, init?: AddInit): Drawing | null;
|
|
1113
|
+
remove(id: string): this;
|
|
1114
|
+
/** Apply a partial record to a drawing — for a custom (headless) settings UI. */
|
|
1115
|
+
update(id: string, patch: Partial<SerializedDrawing>): this;
|
|
1116
|
+
/** Apply several partial records as one undo step (group hide/lock/reorder from a host UI). */
|
|
1117
|
+
updateMany(patches: ReadonlyArray<{
|
|
1118
|
+
id: string;
|
|
1119
|
+
patch: Partial<SerializedDrawing>;
|
|
1120
|
+
}>): this;
|
|
1121
|
+
/** Remove several drawings as one undo step. */
|
|
1122
|
+
removeMany(ids: readonly string[]): this;
|
|
1123
|
+
lock(id: string, v?: boolean): this;
|
|
1124
|
+
show(id: string, v?: boolean): this;
|
|
1125
|
+
/** Select drawings on the chart (highlight + open their toolbar) — for a host-side tree/list.
|
|
1126
|
+
* Pass `null` or `[]` to clear the selection. */
|
|
1127
|
+
select(ids: string | readonly string[] | null): this;
|
|
1128
|
+
/** Open a drawing's settings popup on the chart (selecting it) — the twin of clicking it. */
|
|
1129
|
+
openSettings(id: string): this;
|
|
1130
|
+
bringToFront(id: string): this;
|
|
1131
|
+
sendToBack(id: string): this;
|
|
1132
|
+
/** Revert the last edit. No-op when there is nothing to undo. */
|
|
1133
|
+
undo(): this;
|
|
1134
|
+
/** Re-apply the last undone edit. No-op when there is nothing to redo. */
|
|
1135
|
+
redo(): this;
|
|
1136
|
+
canUndo(): boolean;
|
|
1137
|
+
canRedo(): boolean;
|
|
1138
|
+
/** Duplicate a drawing in place; the clone is selected. Returns this (chainable). */
|
|
1139
|
+
clone(id: string): this;
|
|
1140
|
+
/** Duplicate several drawings in place; the clones become the selection. */
|
|
1141
|
+
duplicate(ids: string[]): this;
|
|
1142
|
+
/** Copy drawings into the in-memory clipboard for a later {@link paste}. */
|
|
1143
|
+
copyToClipboard(ids: string[]): this;
|
|
1144
|
+
/** Paste the clipboard as new drawings (fresh ids), selecting them. */
|
|
1145
|
+
paste(): this;
|
|
1146
|
+
/** Every drawing as plain JSON, in paint order. */
|
|
1147
|
+
all(): SerializedDrawing[];
|
|
1148
|
+
/** Snapshot all drawings as a versioned document (persistence). */
|
|
1149
|
+
toJSON(): DrawingsDocument;
|
|
1150
|
+
/** Restore drawings from a document produced by {@link toJSON} (untrusted-safe). */
|
|
1151
|
+
fromJSON(doc: unknown): this;
|
|
1152
|
+
/** The favorite tool types (starred in the toolbar flyouts), insertion-ordered. */
|
|
1153
|
+
favorites(): DrawingTypeKey[];
|
|
1154
|
+
isFavorite(type: DrawingTypeKey): boolean;
|
|
1155
|
+
/** Star/unstar one tool type. */
|
|
1156
|
+
setFavorite(type: DrawingTypeKey, on: boolean): this;
|
|
1157
|
+
/** Replace the whole favorite set (e.g. restoring persisted prefs). */
|
|
1158
|
+
setFavorites(types: readonly DrawingTypeKey[]): this;
|
|
1159
|
+
/** Aliases mirroring `renderer.getConfig()/applyConfig()` for symmetry. */
|
|
1160
|
+
getConfig(): DrawingsDocument;
|
|
1161
|
+
applyConfig(doc: unknown): this;
|
|
1162
|
+
private ok;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/** Outcome of {@link Vela.runIndicator}: success carries the live handle, failure the error. */
|
|
1166
|
+
interface RunIndicatorResult {
|
|
1167
|
+
ok: boolean;
|
|
1168
|
+
/** The mounted indicator on success; null on failure (it was removed again). */
|
|
1169
|
+
handle: IndicatorHandle | null;
|
|
1170
|
+
/** The compile/runtime error on failure; null on success. */
|
|
1171
|
+
error: Error | null;
|
|
1172
|
+
/** Post-mortem context snapshot on failure, when the engine had produced one (else null). */
|
|
1173
|
+
context: EngineContextSnapshot | null;
|
|
1174
|
+
}
|
|
1175
|
+
/** Optional dependency overrides — inject a different renderer, engines, or data feed (tests, swaps). */
|
|
1176
|
+
interface VelaDeps {
|
|
1177
|
+
renderer?: IChartRenderer;
|
|
1178
|
+
/** Scripting engines to register at construction (bulk form of `registerEngine`); default none. */
|
|
1179
|
+
engines?: ScriptingEngine[];
|
|
1180
|
+
/** Market-data source; default `new MultiProviderFeed()` (a provider registry; offline `data` needs no provider).
|
|
1181
|
+
* A custom feed injected here is used bare — `chart.data` registration is then a no-op. */
|
|
1182
|
+
dataFeed?: MarketDataFeed;
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* The public, imperative chart. Composition root: wires the built-in native
|
|
1186
|
+
* renderer (the default) + provider data feed and delegates orchestration.
|
|
1187
|
+
* Optional renderers (e.g. lightweight-charts) are passed in as a class via
|
|
1188
|
+
* `options.renderer` and instantiated here, so this module imports only the
|
|
1189
|
+
* built-in native renderer. Scripting engines are opt-in — register one with
|
|
1190
|
+
* `registerEngine` (no engine ⇒ candles only).
|
|
1191
|
+
*/
|
|
1192
|
+
declare class Vela {
|
|
1193
|
+
private readonly orchestrator;
|
|
1194
|
+
private readonly rendererControl;
|
|
1195
|
+
private readonly panesControl;
|
|
1196
|
+
private readonly dataControl;
|
|
1197
|
+
private readonly drawingsControl;
|
|
1198
|
+
constructor(container: HTMLElement | string, options?: VelaOptions, deps?: VelaDeps);
|
|
1199
|
+
/**
|
|
1200
|
+
* Register a scripting engine so `addIndicator({ language })` can run that
|
|
1201
|
+
* language. Vela ships NO engine — install the one you need (Pine Script:
|
|
1202
|
+
* `@luxalgo/vela-pinets`) and register it, e.g.
|
|
1203
|
+
* `chart.registerEngine('pine', new PineEngine())`; without one the chart
|
|
1204
|
+
* displays candles, drawings and native indicators only. Re-registering a
|
|
1205
|
+
* language replaces it.
|
|
1206
|
+
*/
|
|
1207
|
+
registerEngine(language: string, engine: ScriptingEngine): this;
|
|
1208
|
+
/** Run an indicator script on the chart's market data and render it. */
|
|
1209
|
+
addIndicator(source: string, options?: AddIndicatorOptions): IndicatorHandle;
|
|
1210
|
+
/**
|
|
1211
|
+
* Add a built-in NATIVE indicator (core-computed, no scripting engine) by registered `type` —
|
|
1212
|
+
* e.g. `'vpvr'`. It becomes a first-class indicator (legend row, settings, hide, remove,
|
|
1213
|
+
* events) and is single-instance per type (a second call returns the existing handle). Returns
|
|
1214
|
+
* a fail-soft handle for an unregistered type. Native renderer only.
|
|
1215
|
+
*/
|
|
1216
|
+
addNativeIndicator(type: string, options?: {
|
|
1217
|
+
inputs?: Record<string, InputValue>;
|
|
1218
|
+
}): IndicatorHandle;
|
|
1219
|
+
/**
|
|
1220
|
+
* The catalog of built-in native indicators with their live state on this chart — each entry's
|
|
1221
|
+
* `type`, `title`, whether it `supported`s the current symbol, and whether it's already `present`
|
|
1222
|
+
* (native indicators are single-instance per type, so a second `addNativeIndicator` is a no-op).
|
|
1223
|
+
* Lets a host "add indicator" UI list them, gate unsupported ones, and avoid duplicates. Async
|
|
1224
|
+
* because support may probe the provider (a type may need data the symbol lacks).
|
|
1225
|
+
*/
|
|
1226
|
+
availableNativeIndicators(): Promise<NativeIndicatorInfo[]>;
|
|
1227
|
+
/**
|
|
1228
|
+
* The native-indicator types PRESENT on the chart right now — the synchronous slice of
|
|
1229
|
+
* {@link availableNativeIndicators} (only support probing is async; presence never is).
|
|
1230
|
+
* Persistence snapshots read this: an unload-time flush must see an add/remove that
|
|
1231
|
+
* happened microseconds ago, which an async catalog mirror cannot guarantee.
|
|
1232
|
+
*/
|
|
1233
|
+
presentNativeIndicators(): string[];
|
|
1234
|
+
/** Live handles of every indicator currently on the chart (script + native) — drive
|
|
1235
|
+
* host panels (object trees, indicator lists) with per-id visibility/removal. */
|
|
1236
|
+
indicators(): IndicatorHandle[];
|
|
1237
|
+
/**
|
|
1238
|
+
* Execute an indicator script and INJECT it only if the run succeeds — the seam for
|
|
1239
|
+
* host editors and consoles. Resolves `{ ok: true, handle }` after the first
|
|
1240
|
+
* successful evaluation, or `{ ok: false, error }` after a compile/runtime failure —
|
|
1241
|
+
* in which case the failed indicator is removed again (no dead legend row).
|
|
1242
|
+
* Never rejects.
|
|
1243
|
+
*/
|
|
1244
|
+
/**
|
|
1245
|
+
* Execute a script and resolve its FIRST computed run — the data-out door for host
|
|
1246
|
+
* editors, consoles and dashboards. The script is injected only if it runs (a failure
|
|
1247
|
+
* removes it again, leaving no dead legend row), and the result carries the run itself
|
|
1248
|
+
* plus the controls for what it put on the chart: `onUpdate` to follow later runs,
|
|
1249
|
+
* `remove` to take it off. Never rejects.
|
|
1250
|
+
*
|
|
1251
|
+
* `runScript` is `runIndicator` with the run as its payload rather than a handle to go
|
|
1252
|
+
* fetch from — the same relationship `script:run` has to `context:changed`.
|
|
1253
|
+
*/
|
|
1254
|
+
runScript(source: string, options?: AddIndicatorOptions): Promise<ScriptRunResult>;
|
|
1255
|
+
runIndicator(source: string, options?: AddIndicatorOptions): Promise<RunIndicatorResult>;
|
|
1256
|
+
/**
|
|
1257
|
+
* Switch the chart's market IN PLACE — symbol, provider, timeframe, depth, or offline
|
|
1258
|
+
* data — WITHOUT destroying the chart: indicators re-execute over the new bars, native
|
|
1259
|
+
* indicators restart, and panes, user drawings, renderer config and event
|
|
1260
|
+
* subscriptions all survive. Resolves once the new market's history is painted (a
|
|
1261
|
+
* deep backfill continues behind it — await {@link historyComplete}); a call
|
|
1262
|
+
* superseded by a newer `setMarket` resolves silently. Emits `market:changed`
|
|
1263
|
+
* (with the previous identity) when the market identity changed.
|
|
1264
|
+
*/
|
|
1265
|
+
setMarket(next: MarketSwitch): Promise<void>;
|
|
1266
|
+
/** The current market identity — the read counterpart of {@link setMarket}. A snapshot
|
|
1267
|
+
* of the REQUESTED market: it reflects an in-flight switch immediately (before the
|
|
1268
|
+
* new bars land). Listen to `market:changed` for committed identity changes. */
|
|
1269
|
+
get market(): MarketSnapshot;
|
|
1270
|
+
/** Resolves once the chart is painted and interactive. For a symbol-backed chart this
|
|
1271
|
+
* awaits a provider being registered that resolves the symbol (the parked load). On a
|
|
1272
|
+
* ranged feed the first paint is a small recent head (~200 bars) and the rest of the
|
|
1273
|
+
* history keeps backfilling BEHIND this — await {@link historyComplete} for the full
|
|
1274
|
+
* depth. Distinct from `chart.data.ready()`, which awaits only the provider symbol
|
|
1275
|
+
* indexes. */
|
|
1276
|
+
ready(): Promise<void>;
|
|
1277
|
+
/** Resolves once the FULL requested history has loaded (immediately for small/offline
|
|
1278
|
+
* charts; after the backward backfill for deep ones — see the `history:progress` /
|
|
1279
|
+
* `history:complete` events). Never rejects: on destroy or a failed backfill it
|
|
1280
|
+
* resolves with whatever depth loaded. */
|
|
1281
|
+
historyComplete(): Promise<void>;
|
|
1282
|
+
/**
|
|
1283
|
+
* A renderer-agnostic snapshot of the graphic elements the core has generated
|
|
1284
|
+
* (series, fills, drawings, tables, …) — a deterministic check that a feature was
|
|
1285
|
+
* produced, independent of which renderer drew it.
|
|
1286
|
+
*/
|
|
1287
|
+
inspect(): SceneInspection;
|
|
1288
|
+
/**
|
|
1289
|
+
* The active renderer's control surface. Set/read render features at runtime —
|
|
1290
|
+
* common ones (candle colors, `logScale`, `currentPriceLine`) and renderer-specific
|
|
1291
|
+
* ones (native `glow`) — with **no indicator re-run**. Unsupported keys warn and no-op:
|
|
1292
|
+
* `chart.renderer.set('glow', 0.6)`, `chart.renderer.set({ logScale: true })`.
|
|
1293
|
+
*/
|
|
1294
|
+
get renderer(): RendererControl;
|
|
1295
|
+
/**
|
|
1296
|
+
* The chart's pane control surface. List panes with the indicators each holds and
|
|
1297
|
+
* move/merge/reorder/collapse/maximize them: `chart.panes.list()`,
|
|
1298
|
+
* `chart.panes.moveIndicator(id, { newPane: true })`, `chart.panes.collapse(id)`.
|
|
1299
|
+
* On a renderer without pane management the mutators warn and no-op.
|
|
1300
|
+
*/
|
|
1301
|
+
get panes(): PanesControl;
|
|
1302
|
+
/**
|
|
1303
|
+
* The chart's data control surface. Register market-data providers and query the
|
|
1304
|
+
* registry: `chart.data.registerProvider('binance', new BinanceProvider())`,
|
|
1305
|
+
* `chart.data.resolve('BTCUSDT')`, `chart.data.symbols('binance')`, and
|
|
1306
|
+
* `chart.data.ready()` (provider indexes settled). No provider is bundled —
|
|
1307
|
+
* registering the one that resolves the chart symbol fires the parked initial load
|
|
1308
|
+
* (await it with `chart.ready()`).
|
|
1309
|
+
*/
|
|
1310
|
+
get data(): DataControl;
|
|
1311
|
+
/**
|
|
1312
|
+
* The chart's user-drawings control surface. Activate tools, create/mutate
|
|
1313
|
+
* drawings programmatically, and persist them:
|
|
1314
|
+
* `chart.drawings.setTool('trendline')`, `chart.drawings.add('hline', { … })`,
|
|
1315
|
+
* `chart.drawings.toJSON()/fromJSON(doc)`. Always present; on a renderer without
|
|
1316
|
+
* the `userDrawings` capability the interactive methods warn + no-op while
|
|
1317
|
+
* persistence still round-trips. Enable the on-chart toolbar with
|
|
1318
|
+
* `new Vela(el, { drawings: true })` or `chart.drawings.showToolbar()`.
|
|
1319
|
+
*/
|
|
1320
|
+
get drawings(): DrawingsControl;
|
|
1321
|
+
on<K extends keyof VelaEventMap>(event: K, handler: (payload: VelaEventMap[K]) => void): () => void;
|
|
1322
|
+
/** The current visible time range (`from`/`to` in epoch-ms), or null before data loads. */
|
|
1323
|
+
getVisibleRange(): VisibleRange | null;
|
|
1324
|
+
/** Set the visible time range explicitly (epoch-ms). Use for a custom date range. */
|
|
1325
|
+
setVisibleRange(range: VisibleRange): this;
|
|
1326
|
+
/**
|
|
1327
|
+
* Pan the view by a fraction of the visible width — positive ⇒ toward the latest
|
|
1328
|
+
* bars, negative ⇒ into history. Behaves exactly like dragging the chart: constant
|
|
1329
|
+
* zoom, the same pan limits (forward stops at the newest candle plus the bounded
|
|
1330
|
+
* empty space), and eased on renderers that animate pans. Repeated calls stack into
|
|
1331
|
+
* one continuous scroll.
|
|
1332
|
+
*/
|
|
1333
|
+
panBy(fraction: number): this;
|
|
1334
|
+
/**
|
|
1335
|
+
* Frame a named date-range preset over the loaded bars: `'1D'`, `'1W'`, `'1M'`,
|
|
1336
|
+
* `'3M'`, `'6M'`, `'1Y'`, `'YTD'`, or `'ALL'`. A preset deeper than the loaded
|
|
1337
|
+
* history simply frames everything (it doesn't fetch more bars).
|
|
1338
|
+
*/
|
|
1339
|
+
setVisibleRangePreset(preset: VisibleRangePreset): this;
|
|
1340
|
+
resize(): void;
|
|
1341
|
+
/**
|
|
1342
|
+
* Swap the app theme at runtime — `'dark'`, `'light'`, or a full custom
|
|
1343
|
+
* {@link VelaTheme}. Re-skins the chart surface, axes, legends and in-chart chrome
|
|
1344
|
+
* live (no indicator re-run, no rebuild) and emits `theme:changed` with the resolved
|
|
1345
|
+
* theme so host chrome around the chart can follow. Explicitly customized plot
|
|
1346
|
+
* cosmetics (a config-set background or series color) are re-based only when they
|
|
1347
|
+
* were inherited from the previous theme.
|
|
1348
|
+
*/
|
|
1349
|
+
setTheme(theme: ThemeName | VelaTheme): this;
|
|
1350
|
+
destroy(): void;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
/** The runtime surface an action's `when`/`run` receives. */
|
|
1354
|
+
interface WidgetContext {
|
|
1355
|
+
/** The CURRENT inner chart. Read it through this getter rather than capturing it:
|
|
1356
|
+
* a shell may replace its chart instance, and a captured one would be destroyed.
|
|
1357
|
+
* (Symbol and timeframe switches are applied IN PLACE — the instance survives them.) */
|
|
1358
|
+
chart: Vela;
|
|
1359
|
+
symbol: string;
|
|
1360
|
+
timeframe: string;
|
|
1361
|
+
priceStyle: string;
|
|
1362
|
+
setSymbol(symbol: string): void;
|
|
1363
|
+
setTimeframe(tf: string): void;
|
|
1364
|
+
setPriceStyle(style: string): void;
|
|
1365
|
+
openSymbolSearch(query?: string): void;
|
|
1366
|
+
/** Open/close a docked side panel by id (built-in or contributed) — a bare call flips
|
|
1367
|
+
* it. The dock stays exclusive: opening one closes whichever was showing. Unknown ids
|
|
1368
|
+
* are ignored. The seam a plugin uses to open ITS OWN panel programmatically. */
|
|
1369
|
+
togglePanel(id: string, open?: boolean): void;
|
|
1370
|
+
/** The widget's root element — pass it as `host` when mounting kit components
|
|
1371
|
+
* (Dialog/Menu/Tooltip) from an action; without an explicit host they portal to
|
|
1372
|
+
* the body, OUTSIDE the theme variables. A multi-chart shell hands its own root. */
|
|
1373
|
+
host: HTMLElement;
|
|
1374
|
+
/** The widget's feedback pill (bottom-center, auto-hides). */
|
|
1375
|
+
toast(message: string, kind?: 'info' | 'success' | 'error'): void;
|
|
1376
|
+
}
|
|
1377
|
+
/** Where an action is projected. */
|
|
1378
|
+
type WidgetActionTarget = 'topbar' | 'context:body' | 'context:price-axis' | 'context:time-axis';
|
|
1379
|
+
interface WidgetActionDescriptor {
|
|
1380
|
+
/** Stable id — re-registering an id replaces it. */
|
|
1381
|
+
id: string;
|
|
1382
|
+
target: WidgetActionTarget;
|
|
1383
|
+
label: string;
|
|
1384
|
+
/** Icon id from the `vela/ui` icon registry (register yours with `registerIcon`). */
|
|
1385
|
+
icon?: string;
|
|
1386
|
+
/** Sort key within the contributed group (ascending; default 0). */
|
|
1387
|
+
order?: number;
|
|
1388
|
+
/** Runtime gate — omitted ⇒ always shown. */
|
|
1389
|
+
when?: (ctx: WidgetContext) => boolean;
|
|
1390
|
+
run: (ctx: WidgetContext) => void;
|
|
1391
|
+
}
|
|
1392
|
+
/**
|
|
1393
|
+
* A widget ATTACHMENT — a contributed unit of per-widget behavior/UI beyond a single
|
|
1394
|
+
* button: overlays, gesture handlers, custom key handling. `mount` runs once per
|
|
1395
|
+
* widget (at construction, or on `refreshActions()` for late registrations) with the
|
|
1396
|
+
* widget's {@link WidgetContext}; the returned disposer runs at widget destroy.
|
|
1397
|
+
* Everything the attachment touches must come from `ctx` (never module globals).
|
|
1398
|
+
*/
|
|
1399
|
+
interface WidgetAttachment {
|
|
1400
|
+
/** Stable id — re-registering an id replaces it (mounted widgets keep the old one until destroy). */
|
|
1401
|
+
id: string;
|
|
1402
|
+
mount(ctx: WidgetContext): () => void;
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* A contributed side panel's runtime handle — what `mount` hands back. Every member is
|
|
1406
|
+
* optional: a panel that only paints its body once needs none of them.
|
|
1407
|
+
*/
|
|
1408
|
+
interface SidePanelHandle {
|
|
1409
|
+
/** (Re)bind to a chart instance: on mount, after every widget rebuild, and — in a
|
|
1410
|
+
* workspace — whenever the active cell changes. */
|
|
1411
|
+
onChart?(chart: Vela): void;
|
|
1412
|
+
/** The panel just became visible. Panels that render lazily do it here. */
|
|
1413
|
+
onOpen?(): void;
|
|
1414
|
+
/** Released when the panel is dropped (widget destroy, or a re-registration). */
|
|
1415
|
+
destroy?(): void;
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* The header surface a contributed panel may use: a SLOT between the title and the close
|
|
1419
|
+
* button for compact controls (a document name, action icons), and the title text itself.
|
|
1420
|
+
* Everything else in the header (the close button, the row) stays the shell's.
|
|
1421
|
+
*/
|
|
1422
|
+
interface SidePanelHeader {
|
|
1423
|
+
/** Lay out inline controls here; the close button stays pinned right of it. */
|
|
1424
|
+
slot: HTMLElement;
|
|
1425
|
+
/** Replace the header title (an empty string hides it). The topbar toggle keeps the
|
|
1426
|
+
* DECLARED `title` as its tooltip. */
|
|
1427
|
+
setTitle(title: string): void;
|
|
1428
|
+
}
|
|
1429
|
+
/**
|
|
1430
|
+
* A contributed SIDE PANEL — a docked column in the shell's panel dock, alongside the object
|
|
1431
|
+
* tree and the data window, with a toggle button in the topbar's panel group.
|
|
1432
|
+
*
|
|
1433
|
+
* The shell owns the chrome (header, close button, dock exclusivity, the button and its pressed
|
|
1434
|
+
* state) and hands `mount` the panel's BODY element to fill — plus a {@link SidePanelHeader}
|
|
1435
|
+
* for panels that dock controls in their header; the contribution never reaches into
|
|
1436
|
+
* the shell's DOM. Register at import time, before widgets are constructed (`refreshActions()`
|
|
1437
|
+
* picks up later registrations on an already-built widget).
|
|
1438
|
+
*/
|
|
1439
|
+
interface SidePanelDescriptor {
|
|
1440
|
+
/** Stable id — re-registering an id replaces it. Also the key its width persists under. */
|
|
1441
|
+
id: string;
|
|
1442
|
+
/** Header title, and the tooltip of its topbar button. */
|
|
1443
|
+
title: string;
|
|
1444
|
+
/** Icon id from the `vela/ui` icon registry (register yours with `registerIcon`). */
|
|
1445
|
+
icon: string;
|
|
1446
|
+
/** Sort key among the panel buttons (ascending; default 100 — after the built-ins). */
|
|
1447
|
+
order?: number;
|
|
1448
|
+
/** Declared width in px (default 280). */
|
|
1449
|
+
width?: number;
|
|
1450
|
+
/** Let the user drag the panel's inner edge (default false — a fixed column). */
|
|
1451
|
+
resizable?: boolean;
|
|
1452
|
+
minWidth?: number;
|
|
1453
|
+
maxWidth?: number;
|
|
1454
|
+
mount(ctx: WidgetContext, body: HTMLElement, header: SidePanelHeader): SidePanelHandle | void;
|
|
1455
|
+
}
|
|
1456
|
+
/** One panel toggle, as the shell's chrome consumes it (data, never DOM). */
|
|
1457
|
+
interface SidePanelButton {
|
|
1458
|
+
id: string;
|
|
1459
|
+
title: string;
|
|
1460
|
+
icon: string;
|
|
1461
|
+
}
|
|
1462
|
+
/** Register (or replace) a widget attachment. Returns an unregister disposer. */
|
|
1463
|
+
declare function registerWidgetAttachment(att: WidgetAttachment): () => void;
|
|
1464
|
+
declare function unregisterWidgetAttachment(id: string): void;
|
|
1465
|
+
/** Every registered attachment (registration order). */
|
|
1466
|
+
declare function widgetAttachments(): WidgetAttachment[];
|
|
1467
|
+
/** Sort key of a panel that declares none — after the shell's own panels. */
|
|
1468
|
+
declare const DEFAULT_PANEL_ORDER = 100;
|
|
1469
|
+
/** Register (or replace) a side panel. Returns an unregister disposer. */
|
|
1470
|
+
declare function registerSidePanel(desc: SidePanelDescriptor): () => void;
|
|
1471
|
+
declare function unregisterSidePanel(id: string): void;
|
|
1472
|
+
/** Every registered side panel, `order`-sorted (registration order breaks ties). */
|
|
1473
|
+
declare function sidePanels(): SidePanelDescriptor[];
|
|
1474
|
+
/** Register (or replace) a widget action. Widgets read the registry live. */
|
|
1475
|
+
declare function registerWidgetAction(desc: WidgetActionDescriptor): () => void;
|
|
1476
|
+
declare function unregisterWidgetAction(id: string): void;
|
|
1477
|
+
/** Actions for one target, `order`-sorted, `when`-filtered when a context is given. */
|
|
1478
|
+
declare function widgetActions(target: WidgetActionTarget, ctx?: WidgetContext): WidgetActionDescriptor[];
|
|
1479
|
+
/** What a legend action sees about the indicator whose row it sits on. */
|
|
1480
|
+
interface LegendIndicatorInfo {
|
|
1481
|
+
id: string;
|
|
1482
|
+
title: string;
|
|
1483
|
+
/** The script source the indicator was added with; undefined for a NATIVE
|
|
1484
|
+
* (core-computed) indicator. The usual `when` gate for source-centric actions. */
|
|
1485
|
+
source?: string;
|
|
1486
|
+
}
|
|
1487
|
+
/**
|
|
1488
|
+
* A contributed LEGEND-ROW action: an icon button on every indicator's legend row,
|
|
1489
|
+
* revealed with the built-in controls (hover/selection), between them and the ✕.
|
|
1490
|
+
* `when` gates per indicator (e.g. `(ind) => ind.source !== undefined` for actions
|
|
1491
|
+
* that need the script). `run` receives the shell's {@link WidgetContext} and the row's
|
|
1492
|
+
* {@link LegendIndicatorInfo}.
|
|
1493
|
+
*/
|
|
1494
|
+
interface LegendActionDescriptor {
|
|
1495
|
+
/** Stable id — re-registering an id replaces it. */
|
|
1496
|
+
id: string;
|
|
1497
|
+
/** Icon id from the `vela/ui` icon registry (register yours with `registerIcon`). */
|
|
1498
|
+
icon: string;
|
|
1499
|
+
tooltip: string;
|
|
1500
|
+
/** Sort key within the contributed group (ascending; default 0). */
|
|
1501
|
+
order?: number;
|
|
1502
|
+
/** Per-indicator gate — omitted ⇒ shown on every row. */
|
|
1503
|
+
when?: (indicator: LegendIndicatorInfo) => boolean;
|
|
1504
|
+
run(ctx: WidgetContext, indicator: LegendIndicatorInfo): void;
|
|
1505
|
+
}
|
|
1506
|
+
/** Register (or replace) a legend action. Returns an unregister disposer. */
|
|
1507
|
+
declare function registerLegendAction(desc: LegendActionDescriptor): () => void;
|
|
1508
|
+
declare function unregisterLegendAction(id: string): void;
|
|
1509
|
+
/** Every registered legend action, `order`-sorted (registration order breaks ties). */
|
|
1510
|
+
declare function legendActions(): LegendActionDescriptor[];
|
|
1511
|
+
/** Makes ONE engine instance for ONE chart — engines hold per-chart sessions (and
|
|
1512
|
+
* possibly a worker), so the shell calls the factory per chart build, never shares. */
|
|
1513
|
+
type EngineFactory = () => ScriptingEngine;
|
|
1514
|
+
/**
|
|
1515
|
+
* Register (or replace) a DEFAULT scripting engine for a language: every widget and
|
|
1516
|
+
* workspace cell built afterwards registers `make()` on its chart automatically — the
|
|
1517
|
+
* app-level wiring for hosts that pair Vela with an engine package, same shape as the
|
|
1518
|
+
* other contribution registries. A per-instance `engines` option still wins for the
|
|
1519
|
+
* same language, and the bare `Vela` chart is untouched: with nothing registered here,
|
|
1520
|
+
* nothing changes anywhere (there is still no bundled default engine).
|
|
1521
|
+
*/
|
|
1522
|
+
declare function registerDefaultEngine(language: string, make: EngineFactory): () => void;
|
|
1523
|
+
declare function unregisterDefaultEngine(language: string): void;
|
|
1524
|
+
/** The registered defaults merged UNDER `overrides` — per-instance factories win per
|
|
1525
|
+
* language. The shell layers (widget, workspace cell) register exactly this result. */
|
|
1526
|
+
declare function resolveEngines(overrides?: Record<string, EngineFactory>): Record<string, EngineFactory>;
|
|
1527
|
+
|
|
1528
|
+
export { nativeIndicatorDescriptors as $, type SidePanelHandle as A, type BarsChangeReason as B, type ContextSelect as C, type DrawingsDocument as D, type EngineAlert as E, type FetchSeries as F, type SidePanelHeader as G, type StrategyFill as H, type IndicatorHandle as I, type StrategyState as J, type StrategyTrade as K, type LegendActionDescriptor as L, type VelaDeps as M, type NativeIndicator as N, type VelaEventMap as O, type ParsedSymbol as P, type VisibleBarRange as Q, type Resolved as R, type ScriptingEngine as S, TypedEventBus as T, type WidgetActionDescriptor as U, Vela as V, type WidgetContext as W, type WidgetActionTarget as X, type WidgetAttachment as Y, getNativeIndicator as Z, legendActions as _, type ScriptRun as a, nativeIndicatorTypes as a0, registerDefaultEngine as a1, registerLegendAction as a2, registerNativeIndicator as a3, registerSidePanel as a4, registerWidgetAction as a5, registerWidgetAttachment as a6, resolveEngines as a7, sidePanels as a8, unregisterDefaultEngine as a9, unregisterLegendAction as aa, unregisterNativeIndicator as ab, unregisterSidePanel as ac, unregisterWidgetAction as ad, unregisterWidgetAttachment as ae, widgetActions as af, widgetAttachments as ag, DEFAULT_PANEL_ORDER as ah, DataControl as b, DrawingsControl as c, type EngineCapabilities as d, type EngineContextSnapshot as e, type EngineFactory as f, type EngineWarning as g, type ExecutionHandlers as h, type ExecutionMarket as i, type ExecutionRequest as j, type ExecutionSession as k, type IndicatorEventMap as l, type IndicatorSummary as m, type LegendIndicatorInfo as n, type NativeIndicatorContext as o, type NativeIndicatorDescriptor as p, type NativeIndicatorInfo as q, type NativeIndicatorOutput as r, type PreparedScript as s, RendererControl as t, type RunIndicatorResult as u, type SceneInspection as v, type ScriptRunCause as w, type ScriptRunResult as x, type SidePanelButton as y, type SidePanelDescriptor as z };
|