@coderyo/renderer-lite 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { Bar } from '@coderyo/data';
2
- import { IndicatorConfig } from '@coderyo/indicators';
3
1
  import { IChartApi, LineData, UTCTimestamp } from 'lightweight-charts';
2
+ import { Interval, Bar } from '@coderyo/data';
3
+ import { IndicatorConfig } from '@coderyo/indicators';
4
4
 
5
5
  interface ChartVisibleRange {
6
6
  fromMs: number;
@@ -21,6 +21,7 @@ declare class TimeScaleBus {
21
21
  visibleFromMs: number;
22
22
  visibleToMs: number;
23
23
  register(chart: IChartApi): void;
24
+ unregister(chart: IChartApi): void;
24
25
  subscribeTransform(listener: TransformListener): () => void;
25
26
  setBarsTimeRange(fromMs: number, toMs: number): void;
26
27
  getVisibleRange(): ChartVisibleRange | null;
@@ -32,6 +33,36 @@ declare class TimeScaleBus {
32
33
  private emit;
33
34
  }
34
35
 
36
+ /** Trim; empty / whitespace → independent pane (no cross-pane sync). */
37
+ declare function normalizeSyncGroupId(id?: string | null): string | null;
38
+ type PaneSyncKey = 'main' | 'volume' | 'indicator';
39
+ declare function independentBusKey(pane: PaneSyncKey): string;
40
+ declare function resolveBusMapKey(groupId: string | null | undefined, pane: PaneSyncKey): string;
41
+ interface PaneSyncGroupPatch {
42
+ main?: string | null;
43
+ volume?: string | null;
44
+ indicator?: string | null;
45
+ }
46
+ /**
47
+ * One {@link TimeScaleBus} per sync group id; empty group id → per-pane independent bus.
48
+ */
49
+ declare class TimeScaleBusRegistry {
50
+ private readonly buses;
51
+ private readonly paneKeys;
52
+ private activeKey;
53
+ constructor();
54
+ getOrCreateBus(key: string): TimeScaleBus;
55
+ getBusKeyForPane(pane: PaneSyncKey): string;
56
+ getBusForPane(pane: PaneSyncKey): TimeScaleBus;
57
+ /** Active bus for IChart viewport APIs (follows last-focused chart pane). */
58
+ get activeBus(): TimeScaleBus;
59
+ getActiveBusKey(): string;
60
+ setActivePane(pane: PaneSyncKey): void;
61
+ setPaneSyncGroup(pane: PaneSyncKey, groupId: string | null | undefined): string;
62
+ forEachBus(fn: (key: string, bus: TimeScaleBus) => void): void;
63
+ moveChart(chart: IChartApi, fromKey: string, toKey: string, copyRange?: boolean): void;
64
+ }
65
+
35
66
  type ScaleMode = 'linear' | 'log';
36
67
  interface CrosshairPayload {
37
68
  time: number;
@@ -49,8 +80,18 @@ interface PinePlotLine {
49
80
  color?: string;
50
81
  values: (number | null)[];
51
82
  }
83
+ type ChartPaneId = 'main' | 'volume' | 'indicator';
84
+ declare function isLayeredPaneMount(opts: Pick<PaneOrchestratorOptions, 'volumeMount'>): boolean;
85
+ declare function shouldResizeChartPane(focus: Set<ChartPaneId> | null, pane: ChartPaneId): boolean;
52
86
  interface PaneOrchestratorOptions {
87
+ /** Main candlestick mount (required). */
53
88
  container: HTMLElement;
89
+ /**
90
+ * P2: separate volume layer host; when set, no flex column in container.
91
+ * Mount order: create empty `chartMain` + `chartVolume` nodes first, pass to compositor widgets,
92
+ * then `createChart(chartMain, { volumeMount: chartVolume })` so LWC mounts after layer frames apply.
93
+ */
94
+ volumeMount?: HTMLElement;
54
95
  indicatorRoot?: HTMLElement;
55
96
  theme?: 'dark' | 'light';
56
97
  scaleMode?: ScaleMode;
@@ -64,9 +105,26 @@ interface PaneOrchestratorOptions {
64
105
  /** Animate last candle + price line toward new OHLC (~150ms). */
65
106
  smoothPriceUpdate?: boolean;
66
107
  smoothPriceDurationMs?: number;
108
+ onIndicatorConfigChange?: (config: IndicatorConfig) => void;
109
+ /** When true (default), set bar spacing on interval reload — does not change visible bar count. */
110
+ autoBarSpacingOnInterval?: boolean;
111
+ barSpacingByInterval?: Partial<Record<Interval, number>>;
112
+ /**
113
+ * When false, do not listen for `tradview:pane-resize` (ChartController owns that path).
114
+ * @default true for standalone orchestrator use; ChartController passes false.
115
+ */
116
+ listenPaneResizeEvents?: boolean;
67
117
  }
68
118
  declare class PaneOrchestrator {
69
- readonly bus: TimeScaleBus;
119
+ readonly busRegistry: TimeScaleBusRegistry;
120
+ /** Active sync group bus (last-focused pane); used by ChartController viewport APIs. */
121
+ get bus(): TimeScaleBus;
122
+ private readonly layeredPanes;
123
+ private readonly mainEl;
124
+ private readonly volWrap;
125
+ private detachMainVolResizer;
126
+ private resizeFocusPanes;
127
+ private readonly listenPaneResizeEvents;
70
128
  private readonly mainChart;
71
129
  private readonly volumeChart;
72
130
  private readonly mainSeries;
@@ -89,11 +147,19 @@ declare class PaneOrchestrator {
89
147
  private barTimesOrdered;
90
148
  private didInitialFit;
91
149
  private skipNextInitialFit;
150
+ /** setBars ran before the pane had layout size; refit on first real resize. */
151
+ private pendingViewportFit;
152
+ private pendingViewportBars;
92
153
  private indicatorConfig;
154
+ private onIndicatorConfigChange?;
155
+ private currentInterval;
156
+ private autoBarSpacingOnInterval;
157
+ private barSpacingByInterval?;
93
158
  private priceLine;
94
159
  private barAnimator;
95
160
  private smoothPriceDurationMs;
96
161
  constructor(opts: PaneOrchestratorOptions);
162
+ private readonly onPaneResize;
97
163
  setSmoothPriceUpdate(enabled: boolean, durationMs?: number): void;
98
164
  /** Update the last candle (and price line); optional smooth interpolation. */
99
165
  updateLastBar(target: Bar, opts?: {
@@ -102,16 +168,41 @@ declare class PaneOrchestrator {
102
168
  }): void;
103
169
  private applyLastBarToSeries;
104
170
  private ensurePriceLine;
171
+ setIntervalContext(interval: Interval): void;
105
172
  setTheme(theme: 'dark' | 'light'): void;
106
173
  setIndicatorConfig(config: IndicatorConfig | null): void;
174
+ private isVolumeVisible;
175
+ private closeVolumePane;
176
+ private applyVolumeVisibility;
177
+ /** Assign per-pane sync group ids (`''` / omit = independent). Re-registers LWC charts on group change. */
178
+ setPaneSyncGroups(patch: PaneSyncGroupPatch): void;
179
+ setActiveSyncPane(pane: ChartPaneId): void;
180
+ /** P2: when set, only these panes get LWC resize (panes in the same sync group still share TimeScaleBus). */
181
+ setResizeFocusPanes(panes: ChartPaneId[] | null): void;
182
+ /** Current resize focus (null = all panes). @internal — not part of public package API. */
183
+ getResizeFocusPanes(): ChartPaneId[] | null;
184
+ private shouldResizePane;
185
+ private rebuildMainVolumeResizer;
107
186
  setPinePlots(plots: PinePlotLine[] | null): void;
187
+ private teardownIndicatorStack;
108
188
  private applyMainOverlays;
109
189
  private syncPinePlotSeries;
110
190
  setShowGrid(show: boolean): void;
111
191
  setBars(bars: Bar[], gaps?: number[]): void;
192
+ private mainPaneHasSize;
193
+ private tryInitialViewportFit;
194
+ private flushPendingViewportFit;
112
195
  subscribeCrosshair(listener: (payload: CrosshairPayload | null) => void): () => void;
113
196
  private findNearestBar;
114
197
  private createIndicatorStack;
198
+ /** After symbol/interval reload: bar spacing for interval + show integrator-loaded span. */
199
+ applyIntervalBarSpacing(interval?: Interval): void;
200
+ setBarSpacingPolicy(opts: {
201
+ autoBarSpacingOnInterval?: boolean;
202
+ barSpacingByInterval?: Partial<Record<Interval, number>>;
203
+ }): void;
204
+ /** Sync time scale to loaded bars (integrator history); adjust bar spacing only, not bar count. */
205
+ private applyViewAfterDataReload;
115
206
  resetViewState(): void;
116
207
  /** Skip the next automatic fitContent after setBars (used by reloadHistory). */
117
208
  preserveViewportOnNextSetBars(): void;
@@ -126,6 +217,11 @@ declare class PaneOrchestrator {
126
217
  scrollToRealtime(): void;
127
218
  setLogScale(enabled: boolean): void;
128
219
  resize(): void;
220
+ /**
221
+ * Resize every LWC pane once for viewport fit; does **not** change {@link resizeFocusPanes}.
222
+ * @internal Used by ChartController data refresh paths.
223
+ */
224
+ resizeAllPanes(): void;
129
225
  getOverlayCanvas(): HTMLCanvasElement | null;
130
226
  timeToX(tMs: number): number | null;
131
227
  priceToY(price: number): number | null;
@@ -140,11 +236,21 @@ declare class PaneOrchestrator {
140
236
  private layoutForTheme;
141
237
  }
142
238
 
239
+ declare function attachPaneResizer(topPane: HTMLElement, bottomPane: HTMLElement, opts?: {
240
+ minTopPx?: number;
241
+ minBottomPx?: number;
242
+ storageKey?: string;
243
+ }): () => void;
244
+
245
+ type IndicatorPaneId = 'macd' | 'rsi' | 'kdj';
143
246
  interface IndicatorPaneStackOptions {
144
247
  theme?: 'dark' | 'light';
145
248
  showGrid?: boolean;
146
249
  config?: IndicatorConfig;
250
+ onConfigChange?: (config: IndicatorConfig) => void;
147
251
  }
252
+ /** PR-21: detect in-place tail updates vs full recompute. */
253
+ declare function detectIndicatorBarMutation(prevTimes: number[], bars: Bar[]): 'full' | 'tail-append' | 'tail-update';
148
254
  declare class IndicatorPaneStack {
149
255
  private readonly root;
150
256
  private readonly macdChart;
@@ -163,10 +269,20 @@ declare class IndicatorPaneStack {
163
269
  private readonly macdWrap;
164
270
  private readonly rsiWrap;
165
271
  private readonly kdjWrap;
272
+ private readonly detachResizers;
273
+ private lastBarTimes;
274
+ private onConfigChange?;
166
275
  constructor(root: HTMLElement, bus: TimeScaleBus, opts?: IndicatorPaneStackOptions | 'dark' | 'light');
167
276
  setConfig(config: IndicatorConfig): void;
277
+ private closePane;
168
278
  private applyPaneVisibility;
279
+ /** Rebuild flex children and drag handles only between visible panes. */
280
+ private rebuildPaneLayout;
169
281
  clearBars(): void;
282
+ private warmupLookback;
283
+ private detectBarMutation;
284
+ private pushSeriesUpdates;
285
+ private pushHistUpdates;
170
286
  setBars(bars: Bar[]): void;
171
287
  setTheme(theme: 'dark' | 'light'): void;
172
288
  setShowGrid(show: boolean): void;
@@ -176,6 +292,8 @@ declare class IndicatorPaneStack {
176
292
  destroy(): void;
177
293
  private createPaneWrap;
178
294
  private layoutForTheme;
295
+ /** LWC instances for sync-group reassignment. */
296
+ getCharts(): IChartApi[];
179
297
  }
180
298
  declare function maOverlayLine(bars: Bar[], period?: number, source?: IndicatorConfig['source']): LineData<UTCTimestamp>[];
181
299
  declare function volMaOverlayLine(bars: Bar[], period?: number): LineData<UTCTimestamp>[];
@@ -186,4 +304,11 @@ declare function bollOverlayLines(bars: Bar[], period: number, mult: number, sou
186
304
  lower: LineData<UTCTimestamp>[];
187
305
  };
188
306
 
189
- export { type ChartVisibleRange, type CrosshairPayload, IndicatorPaneStack, type IndicatorPaneStackOptions, PaneOrchestrator, type PaneOrchestratorOptions, type PinePlotLine, type ScaleMode, TimeScaleBus, type TransformState, bollOverlayLines, emaOverlayLine, maOverlayLine, volMaOverlayLine };
307
+ /**
308
+ * Default horizontal bar spacing (px) per interval so candle width feels consistent
309
+ * when the integrator controls how many bars are loaded / visible.
310
+ */
311
+ declare function defaultBarSpacingForInterval(interval: Interval): number;
312
+ declare function resolveBarSpacingForInterval(interval: Interval, overrides?: Partial<Record<Interval, number>>): number;
313
+
314
+ export { type ChartPaneId, type ChartVisibleRange, type CrosshairPayload, type IndicatorPaneId, IndicatorPaneStack, type IndicatorPaneStackOptions, PaneOrchestrator, type PaneOrchestratorOptions, type PaneSyncGroupPatch, type PaneSyncKey, type PinePlotLine, type ScaleMode, TimeScaleBus, TimeScaleBusRegistry, type TransformState, attachPaneResizer, bollOverlayLines, defaultBarSpacingForInterval, detectIndicatorBarMutation, emaOverlayLine, independentBusKey, isLayeredPaneMount, maOverlayLine, normalizeSyncGroupId, resolveBarSpacingForInterval, resolveBusMapKey, shouldResizeChartPane, volMaOverlayLine };