@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.
Files changed (61) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +28 -0
  3. package/README.md +135 -0
  4. package/dist/DataProvider-DKNDHpNv.d.cts +134 -0
  5. package/dist/DataProvider-Dzd-Erlk.d.ts +134 -0
  6. package/dist/chunk-7UFX5ZIG.js +5976 -0
  7. package/dist/chunk-GYD2THPV.js +252 -0
  8. package/dist/chunk-KCCZNKH7.js +19137 -0
  9. package/dist/chunk-KM6LHB3Y.js +76 -0
  10. package/dist/chunk-OVQKKXLZ.js +3978 -0
  11. package/dist/chunk-Q3XQHLIH.js +7 -0
  12. package/dist/chunk-RHIDOUFL.js +698 -0
  13. package/dist/contributions-hX3EUyjG.d.ts +1528 -0
  14. package/dist/contributions-o1GRKPI_.d.cts +1528 -0
  15. package/dist/history-Dzxz-MQj.d.ts +298 -0
  16. package/dist/history-LJkz4-sS.d.cts +298 -0
  17. package/dist/icons-BZYbJXSV.d.cts +10 -0
  18. package/dist/icons-BZYbJXSV.d.ts +10 -0
  19. package/dist/index.cjs +25294 -0
  20. package/dist/index.d.cts +1189 -0
  21. package/dist/index.d.ts +1189 -0
  22. package/dist/index.js +5 -0
  23. package/dist/keymap-CGOz5F5f.d.cts +64 -0
  24. package/dist/keymap-CGOz5F5f.d.ts +64 -0
  25. package/dist/options-Q-576hIi.d.cts +1545 -0
  26. package/dist/options-Q-576hIi.d.ts +1545 -0
  27. package/dist/plugin-D94muTV-.d.cts +405 -0
  28. package/dist/plugin-aGUD1epn.d.ts +405 -0
  29. package/dist/plugin.cjs +5967 -0
  30. package/dist/plugin.d.cts +7 -0
  31. package/dist/plugin.d.ts +7 -0
  32. package/dist/plugin.js +3 -0
  33. package/dist/providers/binance.cjs +390 -0
  34. package/dist/providers/binance.d.cts +62 -0
  35. package/dist/providers/binance.d.ts +62 -0
  36. package/dist/providers/binance.js +388 -0
  37. package/dist/providers/coinbase.cjs +462 -0
  38. package/dist/providers/coinbase.d.cts +59 -0
  39. package/dist/providers/coinbase.d.ts +59 -0
  40. package/dist/providers/coinbase.js +460 -0
  41. package/dist/providers/hyperliquid.cjs +361 -0
  42. package/dist/providers/hyperliquid.d.cts +54 -0
  43. package/dist/providers/hyperliquid.d.ts +54 -0
  44. package/dist/providers/hyperliquid.js +359 -0
  45. package/dist/side-panel-CT9ZwIGz.d.cts +63 -0
  46. package/dist/side-panel-CT9ZwIGz.d.ts +63 -0
  47. package/dist/ui.cjs +1030 -0
  48. package/dist/ui.d.cts +188 -0
  49. package/dist/ui.d.ts +188 -0
  50. package/dist/ui.js +3 -0
  51. package/dist/vela.global.js +26509 -0
  52. package/dist/vela.global.min.js +230 -0
  53. package/dist/widget.cjs +31178 -0
  54. package/dist/widget.d.cts +799 -0
  55. package/dist/widget.d.ts +799 -0
  56. package/dist/widget.js +1060 -0
  57. package/dist/workspace.cjs +31692 -0
  58. package/dist/workspace.d.cts +579 -0
  59. package/dist/workspace.d.ts +579 -0
  60. package/dist/workspace.js +1694 -0
  61. 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 };