@christtrade/depth 0.12.21

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 (171) hide show
  1. package/LICENSE.md +201 -0
  2. package/NOTICE +15 -0
  3. package/README.md +159 -0
  4. package/depth.cjs +1136 -0
  5. package/depth.css +2 -0
  6. package/depth.mjs +1136 -0
  7. package/depth.nopreflight.css +2 -0
  8. package/index.d.ts +1 -0
  9. package/package.json +32 -0
  10. package/types/ChartInner.d.ts +114 -0
  11. package/types/ChartOuter.d.ts +31 -0
  12. package/types/components/account/AccountSummary.d.ts +8 -0
  13. package/types/components/chart/chart-context-menu.d.ts +30 -0
  14. package/types/components/chart/chart-settings-dialog.d.ts +15 -0
  15. package/types/components/chart/chart-status-overlay.d.ts +24 -0
  16. package/types/components/chart/data-status.d.ts +10 -0
  17. package/types/components/chart/pane-legend.d.ts +37 -0
  18. package/types/components/chart/session-status-badge.d.ts +14 -0
  19. package/types/components/chart/status-bar.d.ts +9 -0
  20. package/types/components/chart/symbol-icon.d.ts +9 -0
  21. package/types/components/chart/tz.d.ts +10 -0
  22. package/types/components/drawings/drawing-icons.d.ts +2 -0
  23. package/types/components/drawings/drawing-settings-bar.d.ts +15 -0
  24. package/types/components/drawings/drawing-settings-dialog.d.ts +268 -0
  25. package/types/components/drawings/drawing-toolbar.d.ts +14 -0
  26. package/types/components/drawings/drawing-tools.d.ts +23 -0
  27. package/types/components/indicators/indicators-dialog.d.ts +20 -0
  28. package/types/components/indicators/indicators-settings-dialog.d.ts +164 -0
  29. package/types/components/multi-chart/GridDividers.d.ts +12 -0
  30. package/types/components/multi-chart/LayoutPicker.d.ts +19 -0
  31. package/types/components/plugin-panels/BottomBarPluginHost.d.ts +7 -0
  32. package/types/components/plugin-panels/PluginFixedPanelHost.d.ts +18 -0
  33. package/types/components/plugin-panels/PluginToolbarHost.d.ts +7 -0
  34. package/types/components/plugin-panels/PluginWindowsDropdown.d.ts +7 -0
  35. package/types/components/plugins/plugin-manager-dialog.d.ts +14 -0
  36. package/types/components/toolbar/SymbolSwitcher.d.ts +8 -0
  37. package/types/components/toolbar/chart-icons.d.ts +16 -0
  38. package/types/components/toolbar/chart-type-selector.d.ts +11 -0
  39. package/types/components/toolbar/timeframe-selector.d.ts +15 -0
  40. package/types/components/trading/OrderPanel.d.ts +36 -0
  41. package/types/components/trading/QuickTradingButtons.d.ts +7 -0
  42. package/types/components/trading/order-math.d.ts +94 -0
  43. package/types/components/ui/button.d.ts +11 -0
  44. package/types/components/ui/checkbox.d.ts +4 -0
  45. package/types/components/ui/color-picker.d.ts +12 -0
  46. package/types/components/ui/dialog.d.ts +19 -0
  47. package/types/components/ui/dropdown-menu.d.ts +27 -0
  48. package/types/components/ui/hover-card.d.ts +6 -0
  49. package/types/components/ui/input.d.ts +4 -0
  50. package/types/components/ui/popover.d.ts +7 -0
  51. package/types/components/ui/resizable.d.ts +23 -0
  52. package/types/components/ui/separator.d.ts +4 -0
  53. package/types/components/ui/slider.d.ts +4 -0
  54. package/types/components/ui/switch.d.ts +4 -0
  55. package/types/components/ui/tooltip.d.ts +7 -0
  56. package/types/core/AccountManager.d.ts +142 -0
  57. package/types/core/ChartModel.d.ts +84 -0
  58. package/types/core/ChartState.d.ts +51 -0
  59. package/types/core/ChartTypeRegistry.d.ts +27 -0
  60. package/types/core/DataEngine.d.ts +143 -0
  61. package/types/core/DataSourceRegistry.d.ts +106 -0
  62. package/types/core/DepthChart.d.ts +458 -0
  63. package/types/core/DrawingRegistry.d.ts +133 -0
  64. package/types/core/DrawingStore.d.ts +26 -0
  65. package/types/core/ExecutionEngine.d.ts +95 -0
  66. package/types/core/GlobalChartBus.d.ts +32 -0
  67. package/types/core/Playback.d.ts +48 -0
  68. package/types/core/PlaybackStateRegistry.d.ts +25 -0
  69. package/types/core/PluginRegistry.d.ts +67 -0
  70. package/types/core/PluginSchedule.d.ts +15 -0
  71. package/types/core/RenderEngine.d.ts +143 -0
  72. package/types/core/ScriptedPlugin.d.ts +153 -0
  73. package/types/core/SessionMapper.d.ts +54 -0
  74. package/types/core/SessionUtils.d.ts +53 -0
  75. package/types/core/TypedEventBus.d.ts +691 -0
  76. package/types/core/WasmPluginHost.d.ts +39 -0
  77. package/types/core/index.d.ts +70 -0
  78. package/types/core/plugin-startup.d.ts +33 -0
  79. package/types/core/processing/data-chunk.d.ts +37 -0
  80. package/types/core/processing/data-level.d.ts +13 -0
  81. package/types/core/processing/l2-processor.d.ts +10 -0
  82. package/types/core/processing/l3-processor.d.ts +26 -0
  83. package/types/core/processing/ohlcv-processor.d.ts +14 -0
  84. package/types/core/processing/tick-processor.d.ts +14 -0
  85. package/types/core/script-dsl.d.ts +20 -0
  86. package/types/core/script-scope.d.ts +4 -0
  87. package/types/core/script.worker.d.ts +1 -0
  88. package/types/hooks/useCellBridges.d.ts +36 -0
  89. package/types/hooks/useChartData.d.ts +153 -0
  90. package/types/hooks/useChartHandlers.d.ts +94 -0
  91. package/types/hooks/useChartInteraction.d.ts +160 -0
  92. package/types/hooks/useChartLayout.d.ts +21 -0
  93. package/types/hooks/useChartPlugin.d.ts +34 -0
  94. package/types/hooks/useChartSettings.d.ts +44 -0
  95. package/types/hooks/useChartSubscriptions.d.ts +64 -0
  96. package/types/hooks/useChartView.d.ts +47 -0
  97. package/types/hooks/usePlaybackEngine.d.ts +85 -0
  98. package/types/hooks/useRenderEngine.d.ts +64 -0
  99. package/types/hooks/useTradeLines.d.ts +80 -0
  100. package/types/hooks/useTradingState.d.ts +135 -0
  101. package/types/interfaces/IAccountAdapter.d.ts +38 -0
  102. package/types/interfaces/ICoordinateTransformer.d.ts +105 -0
  103. package/types/interfaces/IDataAdapter.d.ts +402 -0
  104. package/types/interfaces/IExecutionAdapter.d.ts +71 -0
  105. package/types/interfaces/plugins/IChartPlugin.d.ts +254 -0
  106. package/types/interfaces/plugins/IChartTypePlugin.d.ts +126 -0
  107. package/types/interfaces/plugins/IDataSourcePlugin.d.ts +20 -0
  108. package/types/interfaces/plugins/IDrawingPlugin.d.ts +62 -0
  109. package/types/interfaces/plugins/IIndicatorPlugin.d.ts +97 -0
  110. package/types/interfaces/plugins/index.d.ts +5 -0
  111. package/types/lib/bar-grid.d.ts +6 -0
  112. package/types/lib/book.d.ts +5 -0
  113. package/types/lib/clock.d.ts +7 -0
  114. package/types/lib/compact-buffer.d.ts +66 -0
  115. package/types/lib/constants.d.ts +5 -0
  116. package/types/lib/createSimulatedAdapter.d.ts +42 -0
  117. package/types/lib/dpr.d.ts +27 -0
  118. package/types/lib/heatmap.worker.d.ts +1 -0
  119. package/types/lib/indicator-stdlib.d.ts +426 -0
  120. package/types/lib/indicator-worker.d.ts +65 -0
  121. package/types/lib/matchingEngine.d.ts +144 -0
  122. package/types/lib/notifications/tradeToast.d.ts +31 -0
  123. package/types/lib/pointer-lock.d.ts +5 -0
  124. package/types/lib/priceFormat.d.ts +17 -0
  125. package/types/lib/priceTransition.d.ts +22 -0
  126. package/types/lib/renderers/drawFootprintChart.d.ts +5 -0
  127. package/types/lib/renderers/drawTradeLines.d.ts +112 -0
  128. package/types/lib/renderers/drawings-renderer.d.ts +57 -0
  129. package/types/lib/renderers/renderer.d.ts +113 -0
  130. package/types/lib/sampler.d.ts +7 -0
  131. package/types/lib/series/japaneseCharts.d.ts +88 -0
  132. package/types/lib/slice-worker-client.d.ts +138 -0
  133. package/types/lib/slice.worker.d.ts +139 -0
  134. package/types/lib/storage.d.ts +108 -0
  135. package/types/lib/symbol-info.d.ts +12 -0
  136. package/types/lib/symbol-search.d.ts +29 -0
  137. package/types/lib/timeframes.d.ts +46 -0
  138. package/types/lib/tradingview-import.d.ts +32 -0
  139. package/types/lib/types/chart-settings.d.ts +90 -0
  140. package/types/lib/types/drawing-types.d.ts +393 -0
  141. package/types/lib/types/footprint.d.ts +119 -0
  142. package/types/lib/types/heatmap-types.d.ts +30 -0
  143. package/types/lib/types/index.d.ts +147 -0
  144. package/types/lib/types/indicator-types.d.ts +123 -0
  145. package/types/lib/types/layout-sync.d.ts +43 -0
  146. package/types/lib/types/trading-types.d.ts +323 -0
  147. package/types/lib/use-forwarded-ref.d.ts +1 -0
  148. package/types/lib/utils.d.ts +2 -0
  149. package/types/plugins/alligator.d.ts +1 -0
  150. package/types/plugins/atr.d.ts +1 -0
  151. package/types/plugins/awesome-oscillator.d.ts +1 -0
  152. package/types/plugins/bollinger-bands.d.ts +1 -0
  153. package/types/plugins/cci.d.ts +1 -0
  154. package/types/plugins/cvd.d.ts +1 -0
  155. package/types/plugins/donchian.d.ts +1 -0
  156. package/types/plugins/ichimoku.d.ts +1 -0
  157. package/types/plugins/index.d.ts +25 -0
  158. package/types/plugins/keltner.d.ts +1 -0
  159. package/types/plugins/macd.d.ts +1 -0
  160. package/types/plugins/mfi.d.ts +1 -0
  161. package/types/plugins/moving-average.d.ts +1 -0
  162. package/types/plugins/obv.d.ts +1 -0
  163. package/types/plugins/psar.d.ts +1 -0
  164. package/types/plugins/rsi.d.ts +1 -0
  165. package/types/plugins/sessions.d.ts +1 -0
  166. package/types/plugins/stochastic.d.ts +1 -0
  167. package/types/plugins/supertrend.d.ts +1 -0
  168. package/types/plugins/volume.d.ts +1 -0
  169. package/types/plugins/vwap.d.ts +1 -0
  170. package/types/plugins/williams-r.d.ts +1 -0
  171. package/types/react/useDepthChart.d.ts +6 -0
@@ -0,0 +1,458 @@
1
+ import type { IDataAdapter, OhlcvBar, SymbolInfo } from '../interfaces/IDataAdapter';
2
+ import type { IExecutionAdapter } from '../interfaces/IExecutionAdapter';
3
+ import type { IAccountAdapter } from '../interfaces/IAccountAdapter';
4
+ import type { ActiveDrawingTool, Drawing } from '../lib/types/drawing-types';
5
+ import type { ChartSettings } from '../lib/types/chart-settings';
6
+ import type { FootprintOptions } from '../lib/types/footprint';
7
+ import { type DepthProps } from '../ChartOuter';
8
+ import { ExecutionEngine } from './ExecutionEngine';
9
+ import type { FillSearchOptions } from '../lib/matchingEngine';
10
+ import { LiveTransformer } from '../interfaces/ICoordinateTransformer';
11
+ import { BottomBarItem, ChartPlugin, InstalledPlugin, PluginType, ToolbarItem } from './PluginRegistry';
12
+ import { RenderEngine } from './RenderEngine';
13
+ import { ChartEvents, TypedEventBus } from './TypedEventBus';
14
+ import { ChartState } from './ChartState';
15
+ import type { SyncInLayout } from '../lib/types/layout-sync';
16
+ import { ChartModel, type ChartPaneState } from './ChartModel';
17
+ import { DrawingStore } from './DrawingStore';
18
+ import { ChartPane, Indicator } from '../lib/types/indicator-types';
19
+ import { AccountManager, LedgerAdjustment, LedgerFill, LedgerOrder, LedgerPosition, type AccountSaveState } from './AccountManager';
20
+ import { PlaybackMode, type PrefetchOptions } from '../hooks/usePlaybackEngine';
21
+ import { type ChartPreferences } from '../lib/storage';
22
+ import { type PluginCatalogEntry, type PluginStartupEntry, type PluginStartupRecord } from './plugin-startup';
23
+ export interface FeaturesOptions {
24
+ contextMenu?: boolean;
25
+ plugins?: boolean | {
26
+ enabled?: boolean;
27
+ indicators?: boolean;
28
+ charts?: boolean;
29
+ extensions?: boolean;
30
+ drawings?: boolean;
31
+ };
32
+ timeframe?: {
33
+ timeframes?: string[] | 'any';
34
+ allowCustom?: boolean;
35
+ };
36
+ }
37
+ export type TimePrecision = 's' | 'ms' | 'us' | 'ns';
38
+ export type PlaybackOptions = {
39
+ /**
40
+ * Tunes forward prefetch during continuous playback. Optional - the engine
41
+ * measures real load latency and sizes the lead on its own.
42
+ */
43
+ prefetch?: PrefetchOptions;
44
+ };
45
+ export type AccountOptions = {
46
+ initialBalance?: number;
47
+ /** Settlement currency for the balance. Display only. Default: 'USD' */
48
+ currency?: string;
49
+ adapter?: IAccountAdapter;
50
+ adjustments?: LedgerAdjustment[];
51
+ fills?: LedgerFill[];
52
+ positions?: LedgerPosition[];
53
+ orders?: LedgerOrder[];
54
+ /**
55
+ * Tunes how skipped spans (from far jumps) are settled for fills. Accuracy
56
+ * by default. Also adjustable at runtime via `chart.account.setFillSearch`.
57
+ */
58
+ fillSearch?: Partial<FillSearchOptions>;
59
+ };
60
+ export interface ChartOptions {
61
+ dataAdapter: IDataAdapter;
62
+ initialLoad: {
63
+ start: string | number;
64
+ end: string | number;
65
+ };
66
+ playback?: PlaybackOptions;
67
+ horizon: string | number;
68
+ symbol: string;
69
+ timePrecision?: TimePrecision;
70
+ barNs?: bigint;
71
+ fpOptions?: FootprintOptions;
72
+ initialWindowNs?: bigint;
73
+ prefetchWindowNs?: bigint;
74
+ executionAdapter?: IExecutionAdapter;
75
+ hideToolbar?: boolean;
76
+ hideBottomToolbar?: boolean;
77
+ hideDrawingToolbar?: boolean;
78
+ hidePriceScale?: boolean;
79
+ hideTimeScale?: boolean;
80
+ hideStatusBar?: boolean;
81
+ hideLegend?: boolean;
82
+ timeframe?: string;
83
+ debug?: {
84
+ showDataStatusInBottomRightCorner?: boolean;
85
+ };
86
+ features?: FeaturesOptions;
87
+ /**
88
+ * Seed a first-run session from the user's TradingView preferences, if their
89
+ * charting library left any in localStorage on this origin. Defaults to true.
90
+ *
91
+ * Only fills in settings that are currently unset, runs at most once per
92
+ * device, and is skipped entirely when `restore` is supplied.
93
+ */
94
+ importTradingViewSettings?: boolean;
95
+ account?: AccountOptions;
96
+ /**
97
+ * Saved state to restore on construction.
98
+ * Obtain via chart.serialize(), pass back here on next mount.
99
+ */
100
+ restore?: ChartSaveState;
101
+ toolbar?: (chart: DepthChart) => React.ReactNode[];
102
+ }
103
+ /** Bump when the save document shape changes incompatibly; handled in migrate(). */
104
+ export declare const SAVE_VERSION = 1;
105
+ export interface LayoutDescriptor {
106
+ id: string;
107
+ label: string;
108
+ count: number;
109
+ cols: number;
110
+ rows: number;
111
+ areas: string;
112
+ }
113
+ export interface ChartSaveState {
114
+ /** Schema version. Absent = legacy/pre-versioning. */
115
+ version?: number;
116
+ /** Grid layout descriptor (which preset, how many cells). */
117
+ layout?: LayoutDescriptor;
118
+ /** Which properties the layout's cells share (crosshair, symbol, ...). */
119
+ syncInLayout?: SyncInLayout;
120
+ /** Column/row divider sizes (fr) and the focused pane index. */
121
+ gridColSizes?: number[];
122
+ gridRowSizes?: number[];
123
+ focusedPane?: number;
124
+ /** Trading account. Controller-level - one account across every pane. */
125
+ account?: AccountSaveState;
126
+ /** Shared plugin pool: each plugin's id + code, stored once. Restored under
127
+ * the same id so a host re-installing it manually dedups. Pane plugin refs
128
+ * point at these ids. */
129
+ plugins?: InstalledPlugin[];
130
+ /** Drawings keyed by symbol - drawings follow the symbol, not the pane. */
131
+ drawings?: Record<string, Drawing[]>;
132
+ /** Per-pane state: independent symbol / timeframe / settings / plugin refs. */
133
+ charts?: ChartPaneState[];
134
+ /**
135
+ * Device-level preferences that aren't per-pane: custom and favorite
136
+ * timeframes, favorite drawings, drawing style templates, color swatches, and
137
+ * each plugin's settings and KV store. Keyed by storage key.
138
+ */
139
+ preferences?: ChartPreferences;
140
+ }
141
+ /** Serialize a save document to a JSON string, encoding BigInts losslessly. */
142
+ export declare function stringifyChartSave(state: ChartSaveState): string;
143
+ /** Parse a JSON string produced by stringifyChartSave back into a save document. */
144
+ export declare function parseChartSave(json: string): ChartSaveState;
145
+ type PlaybackAPI<T> = {
146
+ play: () => T;
147
+ pause: () => T;
148
+ playing: boolean;
149
+ stepSize: string;
150
+ speed: number;
151
+ mode: PlaybackMode;
152
+ stepSnap: boolean;
153
+ setStepSize: (step: string) => T;
154
+ setSpeed: (speed: number) => T;
155
+ stepBack: () => T;
156
+ stepForward: () => T;
157
+ setMode: (mode: PlaybackMode) => T;
158
+ setStepSnap: (snap: boolean) => T;
159
+ /** Current playhead position, epoch ns. */
160
+ time: bigint;
161
+ /** Jump the playhead. Accepts ns (bigint), epoch ms, a Date, or an ISO string. */
162
+ goTo: (t: bigint | number | Date | string) => T;
163
+ /**
164
+ * Refuse every move that would put the playhead behind where it has already
165
+ * been. Refused moves emit `playback:blocked` rather than failing silently.
166
+ */
167
+ lockForward: (on?: boolean) => T;
168
+ /** Earliest time the playhead may move to, or null when it may move freely. */
169
+ floor: bigint | null;
170
+ allows: (tNs: bigint) => boolean;
171
+ };
172
+ export declare class DepthChart {
173
+ private readonly options;
174
+ readonly id: string;
175
+ readonly eventBus: TypedEventBus;
176
+ readonly executionEngine: ExecutionEngine;
177
+ private readonly dataEngine;
178
+ readonly transformer: LiveTransformer;
179
+ private features;
180
+ private readonly pluginRegistry;
181
+ private _renderEngine;
182
+ private _panelRegistry;
183
+ private _toolbarRegistry;
184
+ private _bottomBarRegistry;
185
+ private _openBarProviders;
186
+ private _horizon;
187
+ private readonly dataSources;
188
+ private readonly drawingRegistry;
189
+ private destroyed;
190
+ private registeredPlugins;
191
+ private _pluginStateListeners;
192
+ private _pluginCatalog;
193
+ private playbackController;
194
+ private readonly playbackStateRegistry;
195
+ private readonly pluginSchedules;
196
+ readonly state: ChartState;
197
+ private readonly _panes;
198
+ readonly drawingStore: DrawingStore;
199
+ readonly account: AccountManager | null;
200
+ playback: PlaybackAPI<DepthChart>;
201
+ private timePrecision;
202
+ constructor(options: ChartOptions);
203
+ setDataAdapter(adapter: IDataAdapter): this;
204
+ load(symbol: string): Promise<void>;
205
+ /**
206
+ * Re-fetch the charted symbol's window without moving the playhead. For when
207
+ * the data source's answer changes rather than the question - the host grants
208
+ * access to a resolution that was refused before, a feed gets backfilled.
209
+ *
210
+ * Switching timeframe is not a substitute: that refines bars from what is
211
+ * already loaded, so anything the first fetch didn't return never arrives.
212
+ */
213
+ reloadData(): Promise<void>;
214
+ getSymbolInfo(symbol: string): SymbolInfo | null;
215
+ /**
216
+ * The bar still being built at the playback horizon, on the focused pane, or
217
+ * `null` before any data has arrived.
218
+ *
219
+ * Unlike the tail of `getData().ohlcvBars` - which is the last bar that was
220
+ * *loaded*, at the fetch resolution and possibly past the horizon - this is
221
+ * the candle the chart is actually drawing on the right edge.
222
+ */
223
+ openBar(): OhlcvBar | null;
224
+ getMaxLookbackBars(): number;
225
+ horizon(): number;
226
+ fitToData(): this;
227
+ setActiveTool(tool: ActiveDrawingTool): this;
228
+ /**
229
+ * Set the active timeframe by label, e.g. "1m", "5m", "1h", "4h", "1d".
230
+ * Custom labels like "213m" or "2h" are accepted too.
231
+ */
232
+ setTimeframe(label: string): this;
233
+ /**
234
+ * The per-pane model for a layout cell index, created on first access. New
235
+ * panes inherit the chart's current symbol / timeframe / footprint options.
236
+ */
237
+ getChart(index: number): ChartModel;
238
+ /** All instantiated pane models, ordered by cell index. */
239
+ get charts(): ChartModel[];
240
+ get focusedChart(): ChartModel;
241
+ /**
242
+ * Is this timeframe allowed by the current feature set? The one source of
243
+ * truth for the gate - every timeframe switch is enforced against it.
244
+ */
245
+ isTimeframeAllowed(label: string): boolean;
246
+ /**
247
+ * Widen what's allowed at runtime, e.g. after the host grants a trial of a
248
+ * paid timeframe. Mutates the same `features` object the UI holds so
249
+ * call-time checks see it immediately, then emits `features:change` so the
250
+ * rendered locks catch up.
251
+ *
252
+ * Presentation only. Anything worth money has to be enforced by whatever
253
+ * serves the data, since a client can always be patched.
254
+ */
255
+ allowTimeframes(labels: string[] | 'any'): this;
256
+ /** Returns the label of the currently active timeframe, e.g. "1m". */
257
+ getTimeframe(): string;
258
+ /**
259
+ * The currently charted symbol. Reads the focused pane, which is the real
260
+ * truth - pane models update on every switch, whereas `state.symbol` is only
261
+ * a mirror (see _wireSymbolMirror) and as good as the events it has seen.
262
+ */
263
+ getSymbol(): string;
264
+ /**
265
+ * The tool armed for drawing - `{ name: 'cursor' }` when the chart is idle.
266
+ * What the toolbar highlights, not what is selected on the canvas. For that
267
+ * see `getSelectedDrawing`.
268
+ */
269
+ getActiveTool(): ActiveDrawingTool;
270
+ /**
271
+ * The drawing the user has selected, in the same `{ name, id, state }` shape
272
+ * as an armed tool, or null when nothing is.
273
+ *
274
+ * `state` is read live out of the drawing store, so it reflects a box that is
275
+ * still being dragged.
276
+ */
277
+ getSelectedDrawing(): ActiveDrawingTool | null;
278
+ /**
279
+ * Any drawing on the active symbol by id, same shape as
280
+ * `getSelectedDrawing`. Null once it has been deleted.
281
+ *
282
+ * The counterpart to selection: a host latched onto a drawing needs to keep
283
+ * reading it after the user selects something else, and needs the null to
284
+ * know when it is gone.
285
+ */
286
+ getDrawing(id: string): ActiveDrawingTool | null;
287
+ /**
288
+ * Fires whenever the active symbol's drawings change - added, edited,
289
+ * dragged or deleted. Returns an unsubscribe.
290
+ *
291
+ * Bound to whichever symbol is active when you call it, since drawings are
292
+ * stored per symbol. Re-subscribe on `chart:set-symbol` to follow the chart
293
+ * across instruments.
294
+ */
295
+ onDrawingsChanged(fn: () => void): () => void;
296
+ /**
297
+ * Patch chart visual settings (scale mode, grid, crosshair, etc.).
298
+ * Equivalent to using the settings dialog in the UI.
299
+ */
300
+ setChartSettings(patch: Partial<ChartSettings>): this;
301
+ /**
302
+ * Switch the active symbol on this chart instance only. Emits
303
+ * `chart:set-symbol`; the data engine, panes and trading bridge all react
304
+ * through their own subscriptions.
305
+ */
306
+ setSymbol(symbol: string): this;
307
+ addIndicator(id: string): this;
308
+ removeIndicator(id: string): this;
309
+ /**
310
+ * Swap the account adapter at runtime. Pass null to revert to the built-in
311
+ * eventBus-driven mode.
312
+ */
313
+ setAccountAdapter(adapter: IAccountAdapter | null): this;
314
+ /**
315
+ * Collect serializable state from every module. Store the result and pass it
316
+ * as `restore` on the next chart construction.
317
+ */
318
+ serialize(): ChartSaveState;
319
+ private _activePaneCount;
320
+ /**
321
+ * Distribute a saved document to every owner. Called from the constructor
322
+ * when `restore` is passed, and callable later for a "load session" action.
323
+ *
324
+ * Order matters: preferences first so a plugin's `getSettings()` sees its
325
+ * restored values during install, then the plugin pool so per-pane refs
326
+ * resolve against it, then account, layout, drawings, and the pane models.
327
+ *
328
+ * Preferences are merged, not replaced - a save document adds its timeframes
329
+ * and templates to whatever the device already has instead of wiping them.
330
+ */
331
+ restore(state: ChartSaveState): this;
332
+ getProps(): DepthProps;
333
+ on<K extends keyof ChartEvents>(event: K, handler: (data: ChartEvents[K]) => void): () => void;
334
+ off<K extends keyof ChartEvents>(event: K, handler: (data: ChartEvents[K]) => void): void;
335
+ use(plugin: ChartPlugin): this;
336
+ /**
337
+ * Apply an installed plugin to the panes. Safe to call before the plugin's
338
+ * worker has registered its capabilities - the activation is queued and runs
339
+ * as soon as the def lands.
340
+ */
341
+ add(pluginOrId: string | ChartPlugin): this;
342
+ /**
343
+ * Take a plugin's live instances off the panes without uninstalling it. It
344
+ * stays loaded, so hot reload keeps working and `add()` re-applies it
345
+ * instantly. To tear it down entirely use `unuse()`.
346
+ */
347
+ remove(pluginOrId: string | ChartPlugin): this;
348
+ /** Uninstall a plugin: kills its worker and removes everything it registered. */
349
+ unuse(id: string): this;
350
+ /** Is this plugin id currently loaded (installed or queued for install)? */
351
+ isPluginInstalled(id: string): boolean;
352
+ /**
353
+ * Pool plugin ids a restored session still expects but nothing has installed.
354
+ * A host that keeps plugin code in its own store rather than the save
355
+ * document (so `serialize().plugins` is stripped) installs these on mount,
356
+ * and the panes then rebuild their indicators with the saved settings.
357
+ */
358
+ getPendingPluginIds(): string[];
359
+ /**
360
+ * Tell the chart where the host keeps its plugin code. The provider is called
361
+ * on demand, so a host whose list changes (a script editor, a store) just
362
+ * returns the current one rather than re-registering.
363
+ *
364
+ * Setting it applies startup plugins straight away - the plugins a restored
365
+ * session references, plus anything the user left switched on - so a host that
366
+ * strips `plugins` out of its save document doesn't have to reinstall them by
367
+ * hand.
368
+ */
369
+ setPluginCatalog(provider: () => PluginCatalogEntry[]): this;
370
+ /** Every plugin the host has code for, loaded or not. */
371
+ getPluginCatalog(): PluginCatalogEntry[];
372
+ /**
373
+ * Install a plugin from the catalog, optionally putting it on the chart.
374
+ * Returns false when the catalog has no code for that id.
375
+ */
376
+ loadPlugin(id: string, opts?: {
377
+ activate?: boolean;
378
+ }): boolean;
379
+ /**
380
+ * Uninstall a plugin and stop loading it at startup. The counterpart to
381
+ * `loadPlugin` - `unuse()` on its own leaves the startup record alone, which
382
+ * is what a restart wants.
383
+ */
384
+ unloadPlugin(id: string): this;
385
+ /** What every plugin the user has an opinion about should do at startup. */
386
+ getPluginStartup(): PluginStartupRecord;
387
+ /**
388
+ * Record what a plugin should do when the chart opens. Merges into any
389
+ * existing entry; `null` forgets the plugin, which lets a restored save
390
+ * document decide again.
391
+ */
392
+ setPluginStartup(id: string, entry: Partial<PluginStartupEntry> | null): this;
393
+ /**
394
+ * Install what this session should open with: every plugin a restored pane
395
+ * references, plus every plugin marked autostart. Idempotent - already-loaded
396
+ * ids are skipped, so it is safe to call again after the catalog changes.
397
+ */
398
+ applyStartupPlugins(): this;
399
+ /** Name and type of every loaded plugin. */
400
+ getInstalledPlugins(): Array<{
401
+ id: string;
402
+ name: string;
403
+ type: PluginType;
404
+ }>;
405
+ /**
406
+ * Show or hide a plugin's panel.
407
+ *
408
+ * Goes through the registry rather than straight to the event, so a consumer
409
+ * that mounts later - the windows dropdown, a second panel host - reads the
410
+ * state the user left rather than what the plugin registered with.
411
+ */
412
+ setPanelVisible(id: string, visible: boolean): this;
413
+ /** Does this plugin have at least one live instance on a pane? */
414
+ isPluginActive(id: string): boolean;
415
+ /**
416
+ * Which plugins are loaded, and which have live instances on a pane. Two
417
+ * different states - a plugin can be installed (worker running, capabilities
418
+ * registered) without being applied to any pane.
419
+ */
420
+ getPluginState(): {
421
+ installed: Set<string>;
422
+ active: Set<string>;
423
+ };
424
+ /**
425
+ * Observe install/uninstall and pane activation/removal. Only fires when the
426
+ * set of ids actually changes - pane models notify on unrelated churn (axis
427
+ * drags rewrite settings every frame) that callers shouldn't re-render on.
428
+ */
429
+ onPluginStateChange(cb: (state: {
430
+ installed: Set<string>;
431
+ active: Set<string>;
432
+ }) => void): () => void;
433
+ private _notifyPluginState;
434
+ getRegisteredPlugins(): Map<string, {
435
+ indicator: Indicator;
436
+ activeByDefault: boolean;
437
+ pane: ChartPane;
438
+ }>;
439
+ getPanelRegistry(): ReadonlyMap<string, {
440
+ element: React.ReactNode;
441
+ title: string;
442
+ visible: boolean;
443
+ }>;
444
+ getToolbarRegistry(): ReadonlyMap<string, ToolbarItem>;
445
+ getBottomBarRegistry(): ReadonlyMap<string, BottomBarItem>;
446
+ attachRenderEngine(engine: RenderEngine): void;
447
+ /**
448
+ * Snapshot of the chart with every layer composited (base, drawings, UI).
449
+ * Returns null until the render engine has attached.
450
+ */
451
+ screenshot(): HTMLCanvasElement | null;
452
+ private _focusedCellId;
453
+ private _wireSymbolMirror;
454
+ private _wireDataRouting;
455
+ private _buildPluginContext;
456
+ destroy(): void;
457
+ }
458
+ export {};
@@ -0,0 +1,133 @@
1
+ import type { Anchor, DrawingAnchorId, PluginDraftDrawing, PluginDrawing } from '../lib/types/drawing-types';
2
+ import type { LiveTransformer } from '../interfaces/ICoordinateTransformer';
3
+ import type { StyleField } from '../components/drawings/drawing-settings-dialog';
4
+ export interface PluginDrawingRenderContext {
5
+ ctx: CanvasRenderingContext2D;
6
+ anchors: Anchor[];
7
+ w: number;
8
+ h: number;
9
+ oy: number;
10
+ transformer: LiveTransformer;
11
+ selected: boolean;
12
+ hovered: boolean;
13
+ hotAnchor: DrawingAnchorId | null;
14
+ data: unknown;
15
+ }
16
+ export interface PluginDrawingHitContext {
17
+ mx: number;
18
+ my: number;
19
+ anchors: Anchor[];
20
+ w: number;
21
+ h: number;
22
+ oy: number;
23
+ transformer: LiveTransformer;
24
+ data: unknown;
25
+ }
26
+ export interface PluginDrawingToolDef {
27
+ /** Must be globally unique. Use reverse-domain: 'com.myname.anchored-vwap' */
28
+ id: string;
29
+ name: string;
30
+ icon?: string;
31
+ cursor?: string;
32
+ /**
33
+ * Number of anchor clicks to commit the drawing.
34
+ * 'dynamic' = user keeps clicking, presses Escape to finish.
35
+ */
36
+ anchorCount: number | 'dynamic';
37
+ /**
38
+ * Render the committed drawing, on every canvas frame. Use ctx.anchors plus
39
+ * the transformer to get from data space to pixels. You must call
40
+ * ctx.save()/restore() if you change global canvas state.
41
+ */
42
+ render(ctx: PluginDrawingRenderContext): void;
43
+ /**
44
+ * Is the mouse over this drawing? Called with each anchor's pixel position
45
+ * already resolved, though you can do your own geometry. Return the anchor
46
+ * id that was hit, null for a body hit, or false for no hit.
47
+ */
48
+ hitTest(ctx: PluginDrawingHitContext): DrawingAnchorId | 'body' | false;
49
+ /**
50
+ * Called while the user is still placing anchors. Return draw commands for
51
+ * the preview, same signature as render. Without it, a dot is drawn at the
52
+ * last placed anchor.
53
+ */
54
+ preview?(ctx: PluginDrawingRenderContext & {
55
+ cursorAnchor: Anchor;
56
+ }): void;
57
+ /**
58
+ * Default style/data merged into the drawing on creation.
59
+ * Returned from getSettings() / stored in drawing.data.
60
+ */
61
+ defaultData?: unknown;
62
+ /**
63
+ * Fields for the Style tab of the drawing settings dialog. Each field's
64
+ * `key` names a key in the drawing's own `data`, so every drawing made with
65
+ * this tool is styled independently. Build them with the `StyleField`
66
+ * helpers exported alongside the dialog.
67
+ */
68
+ settingsSchema?: StyleField[];
69
+ /**
70
+ * Raw pointer and keyboard events while this tool is active. The plugin gets
71
+ * every event and can call ctx methods to commit drawings, update the draft,
72
+ * request redraws. Return true to stop the event reaching the chart's own
73
+ * handlers.
74
+ */
75
+ onPointerDown?(event: PluginToolEvent): boolean | void;
76
+ onPointerMove?(event: PluginToolEvent): boolean | void;
77
+ onPointerUp?(event: PluginToolEvent): boolean | void;
78
+ onKeyDown?(event: PluginKeyEvent): boolean | void;
79
+ onMove?(ctx: PluginDrawingMoveContext): unknown;
80
+ onActivate?(ctx: PluginToolActiveContext): void;
81
+ onDeactivate?(): void;
82
+ }
83
+ export interface PluginToolEvent {
84
+ ts: bigint;
85
+ price: number;
86
+ x: number;
87
+ y: number;
88
+ shiftKey: boolean;
89
+ ctrlKey: boolean;
90
+ altKey: boolean;
91
+ buttons: number;
92
+ tool: PluginToolActiveContext;
93
+ plugin: PluginDrawingToolDef;
94
+ }
95
+ export interface PluginKeyEvent {
96
+ key: string;
97
+ code: string;
98
+ shiftKey: boolean;
99
+ ctrlKey: boolean;
100
+ tool: PluginToolActiveContext;
101
+ }
102
+ export interface PluginDrawingMoveContext {
103
+ data: unknown;
104
+ anchors: Anchor[];
105
+ anchor: DrawingAnchorId;
106
+ dts: bigint;
107
+ dprice: number;
108
+ curTs: bigint;
109
+ curPrice: number;
110
+ }
111
+ export interface PluginToolActiveContext {
112
+ /** Commit a drawing to the drawings array */
113
+ /** keepActive leaves the tool armed, for tools you place several of in a row. */
114
+ commitDrawing(drawing: Omit<PluginDrawing, 'id'> & {
115
+ keepActive?: boolean;
116
+ }): void;
117
+ /** Update the current draft (triggers redraw) */
118
+ setDraft(draft: PluginDraftDrawing | null): void;
119
+ /** Request a canvas redraw without changing draft */
120
+ requestRedraw(): void;
121
+ /** Deactivate this tool and return to cursor */
122
+ deactivate(): void;
123
+ /** The overlay canvas - for tools that want to paint directly every frame */
124
+ getOverlayCanvas(): HTMLCanvasElement;
125
+ }
126
+ export declare class DrawingRegistry {
127
+ private tools;
128
+ register(def: PluginDrawingToolDef): () => void;
129
+ get(id: string): PluginDrawingToolDef | undefined;
130
+ getAll(): PluginDrawingToolDef[];
131
+ has(id: string): boolean;
132
+ }
133
+ export declare const drawingRegistry: DrawingRegistry;
@@ -0,0 +1,26 @@
1
+ import type { Drawing } from '../lib/types/drawing-types';
2
+ type Listener = () => void;
3
+ export declare class DrawingStore {
4
+ private bySymbol;
5
+ private listeners;
6
+ /** Drawings for a symbol. Returns a stable empty array when none exist. */
7
+ forSymbol(symbol: string): readonly Drawing[];
8
+ /** Find a single drawing within a symbol's bucket. */
9
+ find(symbol: string, id: string): Drawing | undefined;
10
+ /** Symbols that currently have at least one drawing. */
11
+ symbols(): string[];
12
+ add(symbol: string, drawing: Drawing): void;
13
+ update(symbol: string, id: string, patch: Partial<Drawing>): void;
14
+ remove(symbol: string, id: string): void;
15
+ /** Replace a symbol's whole bucket - reorder, bulk edit, restore. */
16
+ setForSymbol(symbol: string, drawings: Drawing[]): void;
17
+ clearSymbol(symbol: string): void;
18
+ /** Snapshot of every non-empty bucket, in the save document's shape. */
19
+ serialize(): Record<string, Drawing[]>;
20
+ /** Replace the whole store from a snapshot, notifying every symbol it touches. */
21
+ restore(map: Record<string, Drawing[]>): void;
22
+ /** Subscribe to one symbol's bucket. Returns an unsubscribe. */
23
+ subscribe(symbol: string, fn: Listener): () => void;
24
+ private _changed;
25
+ }
26
+ export {};