@coderyo/core 1.0.0-rc.4 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +40 -3
- package/dist/index.js +297 -24
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as _coderyo_drawings from '@coderyo/drawings';
|
|
2
2
|
import { DrawingRecord, DrawingStyleMeta } from '@coderyo/drawings';
|
|
3
3
|
import * as _coderyo_data from '@coderyo/data';
|
|
4
|
-
import { RealtimeStreamMode, Interval, DataProvider, SymbolResolver } from '@coderyo/data';
|
|
4
|
+
import { RealtimeStreamMode, Interval, DataProvider, SymbolResolver, Bar } from '@coderyo/data';
|
|
5
5
|
import { IndicatorConfig } from '@coderyo/indicators';
|
|
6
6
|
import { FetchPolicy } from '@coderyo/virtual-window';
|
|
7
|
+
import { ChartVisibleRange } from '@coderyo/renderer-lite';
|
|
8
|
+
export { ChartVisibleRange } from '@coderyo/renderer-lite';
|
|
7
9
|
import { BridgeAdapter, BridgeOutboundType } from '@coderyo/bridge';
|
|
8
10
|
export { PINE_EDITOR_DEFAULT, PINE_SAMPLE_SCRIPT, PineCompileResult, PineIrProgram, PinePlotSeries, compilePineLite, runPineLite } from '@coderyo/pine-lite';
|
|
9
11
|
|
|
@@ -36,6 +38,8 @@ interface ChartFeatures {
|
|
|
36
38
|
protobuf?: boolean;
|
|
37
39
|
telemetry?: boolean;
|
|
38
40
|
tickStream?: boolean;
|
|
41
|
+
/** Run Pine-lite VM in a Web Worker when available (default true). */
|
|
42
|
+
pineWorker?: boolean;
|
|
39
43
|
}
|
|
40
44
|
interface ResolvedChartFeatures {
|
|
41
45
|
fetchPolicy: FetchPolicy;
|
|
@@ -51,6 +55,7 @@ interface ResolvedChartFeatures {
|
|
|
51
55
|
protobuf: boolean;
|
|
52
56
|
telemetry: boolean;
|
|
53
57
|
tickStream: boolean;
|
|
58
|
+
pineWorker: boolean;
|
|
54
59
|
}
|
|
55
60
|
declare const DEFAULT_CHART_FEATURES: ResolvedChartFeatures;
|
|
56
61
|
declare function resolveChartFeatures(partial?: ChartFeatures): ResolvedChartFeatures;
|
|
@@ -82,7 +87,7 @@ interface ChartOptions {
|
|
|
82
87
|
/** @deprecated Use features.indicators */
|
|
83
88
|
indicatorConfig?: IndicatorConfig;
|
|
84
89
|
}
|
|
85
|
-
type ChartEvent = 'connectionChange' | 'barUpdate' | 'error' | 'visibleRangeChange' | 'symbolChange' | 'intervalChange' | 'crosshairChange' | 'destroyed' | 'drawingSelectionChange' | 'drawingContextMenu' | 'requestCursorTool' | 'featuresChange';
|
|
90
|
+
type ChartEvent = 'connectionChange' | 'barUpdate' | 'error' | 'visibleRangeChange' | 'symbolChange' | 'intervalChange' | 'crosshairChange' | 'destroyed' | 'drawingSelectionChange' | 'drawingContextMenu' | 'requestCursorTool' | 'featuresChange' | 'telemetry';
|
|
86
91
|
type EventHandler = (payload?: unknown) => void;
|
|
87
92
|
declare class ChartController {
|
|
88
93
|
private readonly container;
|
|
@@ -102,6 +107,10 @@ declare class ChartController {
|
|
|
102
107
|
private offCrosshair;
|
|
103
108
|
private features;
|
|
104
109
|
private pineIr;
|
|
110
|
+
private tickAggregator;
|
|
111
|
+
private catchUpInFlight;
|
|
112
|
+
private lastCatchUpAt;
|
|
113
|
+
private offPageResume;
|
|
105
114
|
constructor(container: HTMLElement, options: ChartOptions);
|
|
106
115
|
getFeatures(): ResolvedChartFeatures;
|
|
107
116
|
setFeatures(patch: ChartFeatures): this;
|
|
@@ -109,6 +118,9 @@ declare class ChartController {
|
|
|
109
118
|
private applyFeatures;
|
|
110
119
|
private recompilePine;
|
|
111
120
|
private applyPinePlots;
|
|
121
|
+
private trackTelemetry;
|
|
122
|
+
setLocale(locale: string): this;
|
|
123
|
+
subscribeBars(handler: (bar: Bar) => void): () => void;
|
|
112
124
|
/** Integrator push: update last candle close (and H/L) without WS. */
|
|
113
125
|
updateLastPrice(price: number, timeMs?: number): this;
|
|
114
126
|
private buildBarFromPrice;
|
|
@@ -140,6 +152,12 @@ declare class ChartController {
|
|
|
140
152
|
setShowGrid(show: boolean): this;
|
|
141
153
|
fitContent(): this;
|
|
142
154
|
scrollToRealtime(): this;
|
|
155
|
+
getVisibleRange(): ChartVisibleRange | null;
|
|
156
|
+
getBarSpace(): number;
|
|
157
|
+
setBarSpace(px: number): this;
|
|
158
|
+
setVisibleRange(range: ChartVisibleRange): this;
|
|
159
|
+
scrollToTimestamp(tsMs: number, animationMs?: number): this;
|
|
160
|
+
reloadHistory(): Promise<this>;
|
|
143
161
|
setLogScale(enabled: boolean): this;
|
|
144
162
|
setFullscreen(_enabled: boolean): this;
|
|
145
163
|
exportImage(opts?: {
|
|
@@ -150,6 +168,11 @@ declare class ChartController {
|
|
|
150
168
|
private isLoadGenerationCurrent;
|
|
151
169
|
private bootstrap;
|
|
152
170
|
private teardownSubscription;
|
|
171
|
+
private bindPageResumeCatchUp;
|
|
172
|
+
/**
|
|
173
|
+
* Backfill bars missed while the tab/window was backgrounded or WS delivery paused.
|
|
174
|
+
*/
|
|
175
|
+
private catchUpMissedBars;
|
|
153
176
|
private maybeLoadMore;
|
|
154
177
|
private refreshRender;
|
|
155
178
|
private emit;
|
|
@@ -168,7 +191,7 @@ interface WireChartBridgeOptions {
|
|
|
168
191
|
declare function wireChartBridge(opts: WireChartBridgeOptions): () => void;
|
|
169
192
|
|
|
170
193
|
/** Synced by scripts/sync-versions.mjs from repo VERSION file */
|
|
171
|
-
declare const TRADVIEW_VERSION: "1.0.
|
|
194
|
+
declare const TRADVIEW_VERSION: "1.0.1";
|
|
172
195
|
|
|
173
196
|
/** Playground / docs: opt-in full TV-like chart features. */
|
|
174
197
|
declare function createDemoChartFeatures(opts: {
|
|
@@ -200,6 +223,17 @@ interface IChart {
|
|
|
200
223
|
setLogScale(enabled: boolean): IChart;
|
|
201
224
|
fitContent(): IChart;
|
|
202
225
|
scrollToRealtime(): IChart;
|
|
226
|
+
/** Visible time range in ms (`fromMs` / `toMs`), or `null` if unknown. */
|
|
227
|
+
getVisibleRange(): ChartVisibleRange | null;
|
|
228
|
+
/** Bar spacing in px (zoom). Alias for LWC `barSpacing`. */
|
|
229
|
+
getBarSpace(): number;
|
|
230
|
+
setBarSpace(px: number): IChart;
|
|
231
|
+
/** Restore viewport time range after re-bootstrap. */
|
|
232
|
+
setVisibleRange(range: ChartVisibleRange): IChart;
|
|
233
|
+
/** Scroll so `tsMs` aligns to the right edge of the viewport. */
|
|
234
|
+
scrollToTimestamp(tsMs: number, animationMs?: number): IChart;
|
|
235
|
+
/** Re-fetch recent history without clearing scroll/zoom. */
|
|
236
|
+
reloadHistory(): Promise<IChart>;
|
|
203
237
|
resize(size?: {
|
|
204
238
|
width?: number;
|
|
205
239
|
height?: number;
|
|
@@ -224,6 +258,9 @@ interface IChart {
|
|
|
224
258
|
/** Integrator push: smooth-update last candle toward `price` (no WS required). */
|
|
225
259
|
updateLastPrice(price: number, timeMs?: number): IChart;
|
|
226
260
|
hasActiveSymbol(): boolean;
|
|
261
|
+
setLocale(locale: string): IChart;
|
|
262
|
+
/** Subscribe to realtime bar updates; returns unsubscribe. */
|
|
263
|
+
subscribeBars(handler: (bar: _coderyo_data.Bar) => void): () => void;
|
|
227
264
|
destroy(): void;
|
|
228
265
|
}
|
|
229
266
|
declare function createChart(target: HTMLElement | string, options: CreateChartOptions): IChart;
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "@coderyo/bridge";
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
|
-
var TRADVIEW_VERSION = "1.0.
|
|
8
|
+
var TRADVIEW_VERSION = "1.0.1";
|
|
9
9
|
|
|
10
10
|
// src/bridge-wire.ts
|
|
11
11
|
var TRADVIEW_API_VERSION = 1;
|
|
@@ -16,7 +16,8 @@ var CHART_EVENT_TO_BRIDGE = {
|
|
|
16
16
|
symbolChange: "chart.symbol",
|
|
17
17
|
intervalChange: "chart.interval",
|
|
18
18
|
crosshairChange: "chart.crosshair",
|
|
19
|
-
destroyed: "chart.destroyed"
|
|
19
|
+
destroyed: "chart.destroyed",
|
|
20
|
+
barUpdate: "chart.barUpdate"
|
|
20
21
|
};
|
|
21
22
|
function wireChartBridge(opts) {
|
|
22
23
|
const chartId = opts.chartId ?? `chart-${Date.now()}`;
|
|
@@ -104,6 +105,10 @@ function wireChartBridge(opts) {
|
|
|
104
105
|
handlers.set("destroyed", () => {
|
|
105
106
|
post("chart.destroyed", { chartId });
|
|
106
107
|
});
|
|
108
|
+
handlers.set("barUpdate", (bar) => {
|
|
109
|
+
const b = bar;
|
|
110
|
+
post("chart.barUpdate", { chartId, t: b?.t, c: b?.c });
|
|
111
|
+
});
|
|
107
112
|
for (const [ev, fn] of handlers) {
|
|
108
113
|
const bridgeType = CHART_EVENT_TO_BRIDGE[ev];
|
|
109
114
|
if (!bridgeType || shouldPost(bridgeType)) {
|
|
@@ -139,6 +144,36 @@ function wireChartBridge(opts) {
|
|
|
139
144
|
});
|
|
140
145
|
postResize();
|
|
141
146
|
break;
|
|
147
|
+
case "host.setLogScale":
|
|
148
|
+
if (typeof p.enabled === "boolean") chart.setLogScale(p.enabled);
|
|
149
|
+
break;
|
|
150
|
+
case "host.setBarSpace":
|
|
151
|
+
if (typeof p.px === "number") chart.setBarSpace(p.px);
|
|
152
|
+
break;
|
|
153
|
+
case "host.setVisibleRange":
|
|
154
|
+
if (typeof p.fromMs === "number" && typeof p.toMs === "number") {
|
|
155
|
+
chart.setVisibleRange({ fromMs: p.fromMs, toMs: p.toMs });
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
case "host.scrollToTimestamp":
|
|
159
|
+
if (typeof p.tsMs === "number") {
|
|
160
|
+
chart.scrollToTimestamp(
|
|
161
|
+
p.tsMs,
|
|
162
|
+
typeof p.animationMs === "number" ? p.animationMs : void 0
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
case "host.reloadHistory":
|
|
167
|
+
void chart.reloadHistory();
|
|
168
|
+
break;
|
|
169
|
+
case "host.setLocale":
|
|
170
|
+
if (typeof p.locale === "string") chart.setLocale(p.locale);
|
|
171
|
+
break;
|
|
172
|
+
case "host.setFeatures":
|
|
173
|
+
if (p.features && typeof p.features === "object") {
|
|
174
|
+
chart.setFeatures(p.features);
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
142
177
|
case "host.destroy":
|
|
143
178
|
chart.destroy();
|
|
144
179
|
break;
|
|
@@ -154,12 +189,51 @@ function wireChartBridge(opts) {
|
|
|
154
189
|
}
|
|
155
190
|
|
|
156
191
|
// src/chart-controller.ts
|
|
157
|
-
import { floorBarOpenTime } from "@coderyo/data";
|
|
192
|
+
import { floorBarOpenTime, intervalMs as intervalMs2 } from "@coderyo/data";
|
|
158
193
|
import { parseInterval } from "@coderyo/data";
|
|
159
|
-
import { BarStore } from "@coderyo/series";
|
|
194
|
+
import { BarStore, computeGapStartTimes, TickAggregator } from "@coderyo/series";
|
|
195
|
+
import { setLocale as setI18nLocale } from "@coderyo/i18n";
|
|
196
|
+
|
|
197
|
+
// src/fetch-chart-history.ts
|
|
198
|
+
import { intervalMs } from "@coderyo/data";
|
|
199
|
+
async function fetchChartHistory(provider, query) {
|
|
200
|
+
const caps = await provider.getCapabilities?.();
|
|
201
|
+
if (caps?.wsHistory && provider.requestWsHistory) {
|
|
202
|
+
try {
|
|
203
|
+
if (query.mode === "range") {
|
|
204
|
+
const bars = await provider.requestWsHistory({
|
|
205
|
+
symbol: query.symbol,
|
|
206
|
+
interval: query.interval,
|
|
207
|
+
from: query.from,
|
|
208
|
+
to: query.to
|
|
209
|
+
});
|
|
210
|
+
return { bars, hasMore: false };
|
|
211
|
+
}
|
|
212
|
+
if (query.mode === "loadMore") {
|
|
213
|
+
const ms = intervalMs(query.interval);
|
|
214
|
+
const from = query.endTime - ms * query.limit;
|
|
215
|
+
const bars = await provider.requestWsHistory({
|
|
216
|
+
symbol: query.symbol,
|
|
217
|
+
interval: query.interval,
|
|
218
|
+
from,
|
|
219
|
+
to: query.endTime
|
|
220
|
+
});
|
|
221
|
+
return { bars, hasMore: false };
|
|
222
|
+
}
|
|
223
|
+
} catch {
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return provider.getHistory(query);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// src/chart-controller.ts
|
|
160
230
|
import { VirtualWindow } from "@coderyo/virtual-window";
|
|
161
231
|
import { DrawingManager } from "@coderyo/drawings";
|
|
162
|
-
import {
|
|
232
|
+
import {
|
|
233
|
+
compilePineLite,
|
|
234
|
+
runPineLiteAsync,
|
|
235
|
+
terminatePineWorker
|
|
236
|
+
} from "@coderyo/pine-lite";
|
|
163
237
|
import { PaneOrchestrator } from "@coderyo/renderer-lite";
|
|
164
238
|
|
|
165
239
|
// src/chart-features.ts
|
|
@@ -176,7 +250,8 @@ var DEFAULT_CHART_FEATURES = {
|
|
|
176
250
|
pineEnabled: false,
|
|
177
251
|
protobuf: false,
|
|
178
252
|
telemetry: false,
|
|
179
|
-
tickStream: false
|
|
253
|
+
tickStream: false,
|
|
254
|
+
pineWorker: true
|
|
180
255
|
};
|
|
181
256
|
function resolveChartFeatures(partial) {
|
|
182
257
|
const d = DEFAULT_CHART_FEATURES;
|
|
@@ -199,7 +274,8 @@ function resolveChartFeatures(partial) {
|
|
|
199
274
|
pineEnabled: partial?.pineEnabled ?? d.pineEnabled,
|
|
200
275
|
protobuf: partial?.protobuf ?? d.protobuf,
|
|
201
276
|
telemetry: partial?.telemetry ?? d.telemetry,
|
|
202
|
-
tickStream: partial?.tickStream ?? d.tickStream
|
|
277
|
+
tickStream: partial?.tickStream ?? d.tickStream,
|
|
278
|
+
pineWorker: partial?.pineWorker ?? d.pineWorker
|
|
203
279
|
};
|
|
204
280
|
}
|
|
205
281
|
function mergeChartFeatures(current, patch) {
|
|
@@ -216,7 +292,8 @@ function mergeChartFeatures(current, patch) {
|
|
|
216
292
|
pineEnabled: patch.pineEnabled ?? current.pineEnabled,
|
|
217
293
|
protobuf: patch.protobuf ?? current.protobuf,
|
|
218
294
|
telemetry: patch.telemetry ?? current.telemetry,
|
|
219
|
-
tickStream: patch.tickStream ?? current.tickStream
|
|
295
|
+
tickStream: patch.tickStream ?? current.tickStream,
|
|
296
|
+
pineWorker: patch.pineWorker ?? current.pineWorker
|
|
220
297
|
});
|
|
221
298
|
}
|
|
222
299
|
var PENDING_SYMBOL = "";
|
|
@@ -288,6 +365,7 @@ var ChartController = class {
|
|
|
288
365
|
this.offCrosshair = this.orchestrator.subscribeCrosshair((payload) => {
|
|
289
366
|
this.emit("crosshairChange", payload);
|
|
290
367
|
});
|
|
368
|
+
this.bindPageResumeCatchUp();
|
|
291
369
|
if (this.hasActiveSymbol()) {
|
|
292
370
|
void this.bootstrap(this.loadGeneration);
|
|
293
371
|
} else {
|
|
@@ -311,6 +389,10 @@ var ChartController = class {
|
|
|
311
389
|
offCrosshair = null;
|
|
312
390
|
features;
|
|
313
391
|
pineIr = null;
|
|
392
|
+
tickAggregator = null;
|
|
393
|
+
catchUpInFlight = false;
|
|
394
|
+
lastCatchUpAt = 0;
|
|
395
|
+
offPageResume = null;
|
|
314
396
|
getFeatures() {
|
|
315
397
|
return { ...this.features };
|
|
316
398
|
}
|
|
@@ -350,20 +432,42 @@ var ChartController = class {
|
|
|
350
432
|
return;
|
|
351
433
|
}
|
|
352
434
|
this.pineIr = compiled.ir;
|
|
435
|
+
if (this.hasActiveSymbol()) {
|
|
436
|
+
const bars = this.virtualWindow.getBarsForRender();
|
|
437
|
+
if (bars.length > 0) this.applyPinePlots(bars);
|
|
438
|
+
}
|
|
353
439
|
}
|
|
354
440
|
applyPinePlots(bars) {
|
|
355
441
|
if (!this.features.pineEnabled || !this.pineIr) {
|
|
356
442
|
this.orchestrator.setPinePlots(null);
|
|
357
443
|
return;
|
|
358
444
|
}
|
|
359
|
-
const
|
|
360
|
-
this.
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
445
|
+
const ir = this.pineIr;
|
|
446
|
+
const useWorker = this.features.pineWorker;
|
|
447
|
+
void runPineLiteAsync(ir, bars, { useWorker }).then((result) => {
|
|
448
|
+
if (this.destroyed || this.pineIr !== ir) return;
|
|
449
|
+
this.orchestrator.setPinePlots(
|
|
450
|
+
result.plots.map((p) => ({
|
|
451
|
+
title: p.title,
|
|
452
|
+
values: p.values,
|
|
453
|
+
color: void 0
|
|
454
|
+
}))
|
|
455
|
+
);
|
|
456
|
+
}).catch((err) => this.emit("error", err));
|
|
457
|
+
}
|
|
458
|
+
trackTelemetry(event, data) {
|
|
459
|
+
if (!this.features.telemetry) return;
|
|
460
|
+
this.emit("telemetry", { event, ...data });
|
|
461
|
+
}
|
|
462
|
+
setLocale(locale) {
|
|
463
|
+
setI18nLocale(locale);
|
|
464
|
+
this.trackTelemetry("locale", { locale });
|
|
465
|
+
return this;
|
|
466
|
+
}
|
|
467
|
+
subscribeBars(handler) {
|
|
468
|
+
const wrapper = (payload) => handler(payload);
|
|
469
|
+
this.on("barUpdate", wrapper);
|
|
470
|
+
return () => this.off("barUpdate", wrapper);
|
|
367
471
|
}
|
|
368
472
|
/** Integrator push: update last candle close (and H/L) without WS. */
|
|
369
473
|
updateLastPrice(price, timeMs = Date.now()) {
|
|
@@ -411,6 +515,7 @@ var ChartController = class {
|
|
|
411
515
|
this.refreshRender(loadGen);
|
|
412
516
|
}
|
|
413
517
|
this.emit("barUpdate", bar);
|
|
518
|
+
this.trackTelemetry("barUpdate", { t: bar.t, partial });
|
|
414
519
|
}
|
|
415
520
|
applyDrawingLayer() {
|
|
416
521
|
if (!this.drawingManager) return;
|
|
@@ -529,6 +634,58 @@ var ChartController = class {
|
|
|
529
634
|
this.orchestrator.scrollToRealtime();
|
|
530
635
|
return this;
|
|
531
636
|
}
|
|
637
|
+
getVisibleRange() {
|
|
638
|
+
return this.orchestrator.getVisibleRange();
|
|
639
|
+
}
|
|
640
|
+
getBarSpace() {
|
|
641
|
+
return this.orchestrator.getBarSpace();
|
|
642
|
+
}
|
|
643
|
+
setBarSpace(px) {
|
|
644
|
+
this.orchestrator.setBarSpace(px);
|
|
645
|
+
return this;
|
|
646
|
+
}
|
|
647
|
+
setVisibleRange(range) {
|
|
648
|
+
this.orchestrator.setVisibleRange(range);
|
|
649
|
+
const { fromMs, toMs } = range;
|
|
650
|
+
if (toMs > fromMs) {
|
|
651
|
+
this.virtualWindow.setVisibleRange({ fromMs, toMs });
|
|
652
|
+
this.visibleRangeInitialized = true;
|
|
653
|
+
}
|
|
654
|
+
return this;
|
|
655
|
+
}
|
|
656
|
+
scrollToTimestamp(tsMs, animationMs) {
|
|
657
|
+
this.orchestrator.scrollToTimestamp(tsMs, animationMs);
|
|
658
|
+
return this;
|
|
659
|
+
}
|
|
660
|
+
async reloadHistory() {
|
|
661
|
+
if (!this.hasActiveSymbol()) return this;
|
|
662
|
+
const savedRange = this.getVisibleRange();
|
|
663
|
+
const savedBarSpace = this.getBarSpace();
|
|
664
|
+
const loadGen = this.loadGeneration;
|
|
665
|
+
const symbol = this.store.symbol;
|
|
666
|
+
const interval = this.store.interval;
|
|
667
|
+
try {
|
|
668
|
+
const history = await fetchChartHistory(this.options.dataProvider, {
|
|
669
|
+
mode: "loadMore",
|
|
670
|
+
symbol,
|
|
671
|
+
interval,
|
|
672
|
+
endTime: Date.now(),
|
|
673
|
+
limit: 500
|
|
674
|
+
});
|
|
675
|
+
if (!this.isLoadGenerationCurrent(loadGen)) return this;
|
|
676
|
+
if (this.store.symbol !== symbol || this.store.interval !== interval) return this;
|
|
677
|
+
if (history.bars.length === 0) return this;
|
|
678
|
+
await this.store.mergeBars(history.bars.map((bar) => ({ bar, source: "rest" })));
|
|
679
|
+
if (!this.isLoadGenerationCurrent(loadGen)) return this;
|
|
680
|
+
this.orchestrator.preserveViewportOnNextSetBars();
|
|
681
|
+
this.refreshRender(loadGen);
|
|
682
|
+
if (savedBarSpace > 0) this.setBarSpace(savedBarSpace);
|
|
683
|
+
if (savedRange) this.setVisibleRange(savedRange);
|
|
684
|
+
} catch (err) {
|
|
685
|
+
this.emit("error", err);
|
|
686
|
+
}
|
|
687
|
+
return this;
|
|
688
|
+
}
|
|
532
689
|
setLogScale(enabled) {
|
|
533
690
|
this.orchestrator.setLogScale(enabled);
|
|
534
691
|
return this;
|
|
@@ -558,12 +715,15 @@ var ChartController = class {
|
|
|
558
715
|
destroy() {
|
|
559
716
|
if (this.destroyed) return;
|
|
560
717
|
this.destroyed = true;
|
|
718
|
+
this.offPageResume?.();
|
|
719
|
+
this.offPageResume = null;
|
|
561
720
|
this.offCrosshair?.();
|
|
562
721
|
this.offCrosshair = null;
|
|
563
722
|
this.resizeObserver.disconnect();
|
|
564
723
|
this.drawingManager?.destroy();
|
|
565
724
|
void this.teardownSubscription();
|
|
566
725
|
this.orchestrator.destroy();
|
|
726
|
+
terminatePineWorker();
|
|
567
727
|
this.emit("destroyed", { chartId: this.options.chartId ?? "default" });
|
|
568
728
|
this.emit("connectionChange", "disconnected");
|
|
569
729
|
}
|
|
@@ -583,7 +743,13 @@ var ChartController = class {
|
|
|
583
743
|
const symbol = this.store.symbol;
|
|
584
744
|
const interval = this.store.interval;
|
|
585
745
|
const endTime = Date.now();
|
|
586
|
-
|
|
746
|
+
if (this.features.protobuf) {
|
|
747
|
+
this.emit("error", {
|
|
748
|
+
code: "PROTOBUF_UNAVAILABLE",
|
|
749
|
+
message: "Protobuf encoding requires protocol v1.1 (not in 1.0.0)"
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
const history = await fetchChartHistory(this.options.dataProvider, {
|
|
587
753
|
mode: "loadMore",
|
|
588
754
|
symbol,
|
|
589
755
|
interval,
|
|
@@ -601,16 +767,22 @@ var ChartController = class {
|
|
|
601
767
|
});
|
|
602
768
|
this.emit("intervalChange", interval);
|
|
603
769
|
const streamMode = this.features.tickStream ? "bar+tick" : this.features.streamMode;
|
|
770
|
+
const tickOnly = streamMode === "tick";
|
|
604
771
|
const params = {
|
|
605
772
|
symbol,
|
|
606
773
|
interval,
|
|
607
|
-
channels: this.features.tickStream ? ["bar", "tick"] : ["bar"],
|
|
774
|
+
channels: tickOnly ? ["tick"] : this.features.tickStream ? ["bar", "tick"] : ["bar"],
|
|
608
775
|
streamMode
|
|
609
776
|
};
|
|
777
|
+
this.tickAggregator = tickOnly ? new TickAggregator(interval, (bar, partial) => {
|
|
778
|
+
if (!this.isLoadGenerationCurrent(loadGen)) return;
|
|
779
|
+
if (this.store.symbol !== symbol || this.store.interval !== interval) return;
|
|
780
|
+
void this.applyRealtimeBar(bar, partial, loadGen);
|
|
781
|
+
}) : null;
|
|
610
782
|
await this.options.dataProvider.connect?.();
|
|
611
783
|
if (!this.isLoadGenerationCurrent(loadGen)) return;
|
|
612
784
|
const sub = await this.options.dataProvider.subscribe(params, {
|
|
613
|
-
onBar: (bar, meta) => {
|
|
785
|
+
onBar: tickOnly ? void 0 : (bar, meta) => {
|
|
614
786
|
if (!this.isLoadGenerationCurrent(loadGen)) return;
|
|
615
787
|
if (this.store.symbol !== symbol || this.store.interval !== interval) return;
|
|
616
788
|
void this.applyRealtimeBar(bar, meta.partial, loadGen);
|
|
@@ -618,10 +790,19 @@ var ChartController = class {
|
|
|
618
790
|
onTick: (tick) => {
|
|
619
791
|
if (!this.isLoadGenerationCurrent(loadGen)) return;
|
|
620
792
|
if (this.store.symbol !== symbol || this.store.interval !== interval) return;
|
|
793
|
+
if (this.tickAggregator) {
|
|
794
|
+
this.tickAggregator.ingest(tick);
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
621
797
|
const bar = this.buildBarFromPrice(tick.price, tick.t);
|
|
622
798
|
void this.applyRealtimeBar(bar, true, loadGen);
|
|
623
799
|
},
|
|
624
|
-
onConnectionChange: (state) =>
|
|
800
|
+
onConnectionChange: (state) => {
|
|
801
|
+
this.emit("connectionChange", state);
|
|
802
|
+
if (state === "connected" && this.subscriptionId != null) {
|
|
803
|
+
void this.catchUpMissedBars();
|
|
804
|
+
}
|
|
805
|
+
},
|
|
625
806
|
onError: (err) => this.emit("error", err)
|
|
626
807
|
});
|
|
627
808
|
if (!this.isLoadGenerationCurrent(loadGen)) {
|
|
@@ -631,11 +812,73 @@ var ChartController = class {
|
|
|
631
812
|
this.subscriptionId = sub.id;
|
|
632
813
|
}
|
|
633
814
|
async teardownSubscription() {
|
|
815
|
+
this.tickAggregator?.flush();
|
|
816
|
+
this.tickAggregator = null;
|
|
634
817
|
if (this.subscriptionId) {
|
|
635
818
|
await this.options.dataProvider.unsubscribe(this.subscriptionId);
|
|
636
819
|
this.subscriptionId = null;
|
|
637
820
|
}
|
|
638
821
|
}
|
|
822
|
+
bindPageResumeCatchUp() {
|
|
823
|
+
if (typeof document === "undefined") return;
|
|
824
|
+
const onResume = () => {
|
|
825
|
+
if (document.visibilityState !== "visible") return;
|
|
826
|
+
void this.catchUpMissedBars();
|
|
827
|
+
};
|
|
828
|
+
document.addEventListener("visibilitychange", onResume);
|
|
829
|
+
const cleanups = [
|
|
830
|
+
() => document.removeEventListener("visibilitychange", onResume)
|
|
831
|
+
];
|
|
832
|
+
if (typeof window !== "undefined") {
|
|
833
|
+
const onFocus = () => void this.catchUpMissedBars();
|
|
834
|
+
window.addEventListener("focus", onFocus);
|
|
835
|
+
cleanups.push(() => window.removeEventListener("focus", onFocus));
|
|
836
|
+
}
|
|
837
|
+
this.offPageResume = () => {
|
|
838
|
+
for (const fn of cleanups) fn();
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Backfill bars missed while the tab/window was backgrounded or WS delivery paused.
|
|
843
|
+
*/
|
|
844
|
+
async catchUpMissedBars() {
|
|
845
|
+
if (this.destroyed || !this.hasActiveSymbol()) return;
|
|
846
|
+
const now = Date.now();
|
|
847
|
+
if (now - this.lastCatchUpAt < 400) return;
|
|
848
|
+
if (this.catchUpInFlight) return;
|
|
849
|
+
const times = this.store.sortedTimes;
|
|
850
|
+
if (times.length === 0) return;
|
|
851
|
+
const lastT = times[times.length - 1];
|
|
852
|
+
const interval = this.store.interval;
|
|
853
|
+
const to = now + intervalMs2(interval);
|
|
854
|
+
if (to <= lastT) return;
|
|
855
|
+
this.catchUpInFlight = true;
|
|
856
|
+
this.lastCatchUpAt = now;
|
|
857
|
+
const loadGen = this.loadGeneration;
|
|
858
|
+
const symbol = this.store.symbol;
|
|
859
|
+
try {
|
|
860
|
+
const history = await fetchChartHistory(this.options.dataProvider, {
|
|
861
|
+
mode: "range",
|
|
862
|
+
symbol,
|
|
863
|
+
interval,
|
|
864
|
+
from: lastT,
|
|
865
|
+
to
|
|
866
|
+
});
|
|
867
|
+
if (!this.isLoadGenerationCurrent(loadGen)) return;
|
|
868
|
+
if (this.store.symbol !== symbol || this.store.interval !== interval) return;
|
|
869
|
+
if (history.bars.length === 0) return;
|
|
870
|
+
await this.store.mergeBars(
|
|
871
|
+
history.bars.map((bar) => ({ bar, source: "rest" }))
|
|
872
|
+
);
|
|
873
|
+
if (!this.isLoadGenerationCurrent(loadGen)) return;
|
|
874
|
+
this.orchestrator.preserveViewportOnNextSetBars();
|
|
875
|
+
this.refreshRender(loadGen);
|
|
876
|
+
} catch (err) {
|
|
877
|
+
this.emit("error", err);
|
|
878
|
+
} finally {
|
|
879
|
+
this.catchUpInFlight = false;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
639
882
|
async maybeLoadMore() {
|
|
640
883
|
if (this.destroyed || this.loadingMore) return;
|
|
641
884
|
const loadGen = this.loadGeneration;
|
|
@@ -645,7 +888,10 @@ var ChartController = class {
|
|
|
645
888
|
try {
|
|
646
889
|
for (const req of reqs) {
|
|
647
890
|
if (!this.isLoadGenerationCurrent(loadGen)) return;
|
|
648
|
-
const history = await
|
|
891
|
+
const history = await fetchChartHistory(
|
|
892
|
+
this.options.dataProvider,
|
|
893
|
+
toHistoryQuery(req)
|
|
894
|
+
);
|
|
649
895
|
if (!this.isLoadGenerationCurrent(loadGen)) return;
|
|
650
896
|
if (history.bars.length === 0) continue;
|
|
651
897
|
await this.store.mergeBars(
|
|
@@ -674,7 +920,11 @@ var ChartController = class {
|
|
|
674
920
|
}
|
|
675
921
|
const bars = this.virtualWindow.getBarsForRender();
|
|
676
922
|
if (bars.length === 0) return;
|
|
677
|
-
this.
|
|
923
|
+
const gaps = this.features.gaps.whitespace ? computeGapStartTimes(
|
|
924
|
+
bars.map((b) => b.t),
|
|
925
|
+
this.store.interval
|
|
926
|
+
) : void 0;
|
|
927
|
+
this.orchestrator.setBars(bars, gaps);
|
|
678
928
|
this.applyPinePlots(bars);
|
|
679
929
|
this.drawingManager?.redraw();
|
|
680
930
|
this.emit("visibleRangeChange", {
|
|
@@ -767,6 +1017,24 @@ function wrap(controller, beforeDestroy) {
|
|
|
767
1017
|
controller.scrollToRealtime();
|
|
768
1018
|
return wrap(controller, beforeDestroy);
|
|
769
1019
|
},
|
|
1020
|
+
getVisibleRange: () => controller.getVisibleRange(),
|
|
1021
|
+
getBarSpace: () => controller.getBarSpace(),
|
|
1022
|
+
setBarSpace: (px) => {
|
|
1023
|
+
controller.setBarSpace(px);
|
|
1024
|
+
return wrap(controller, beforeDestroy);
|
|
1025
|
+
},
|
|
1026
|
+
setVisibleRange: (range) => {
|
|
1027
|
+
controller.setVisibleRange(range);
|
|
1028
|
+
return wrap(controller, beforeDestroy);
|
|
1029
|
+
},
|
|
1030
|
+
scrollToTimestamp: (tsMs, animationMs) => {
|
|
1031
|
+
controller.scrollToTimestamp(tsMs, animationMs);
|
|
1032
|
+
return wrap(controller, beforeDestroy);
|
|
1033
|
+
},
|
|
1034
|
+
reloadHistory: async () => {
|
|
1035
|
+
await controller.reloadHistory();
|
|
1036
|
+
return wrap(controller, beforeDestroy);
|
|
1037
|
+
},
|
|
770
1038
|
resize: (s) => {
|
|
771
1039
|
controller.resize(s);
|
|
772
1040
|
return wrap(controller, beforeDestroy);
|
|
@@ -818,6 +1086,11 @@ function wrap(controller, beforeDestroy) {
|
|
|
818
1086
|
return wrap(controller, beforeDestroy);
|
|
819
1087
|
},
|
|
820
1088
|
hasActiveSymbol: () => controller.hasActiveSymbol(),
|
|
1089
|
+
setLocale: (locale) => {
|
|
1090
|
+
controller.setLocale(locale);
|
|
1091
|
+
return wrap(controller, beforeDestroy);
|
|
1092
|
+
},
|
|
1093
|
+
subscribeBars: (handler) => controller.subscribeBars(handler),
|
|
821
1094
|
destroy: () => {
|
|
822
1095
|
controller.destroy();
|
|
823
1096
|
beforeDestroy?.();
|
|
@@ -846,7 +1119,7 @@ function createChart(target, options) {
|
|
|
846
1119
|
// src/index.ts
|
|
847
1120
|
import {
|
|
848
1121
|
compilePineLite as compilePineLite2,
|
|
849
|
-
runPineLite
|
|
1122
|
+
runPineLite,
|
|
850
1123
|
PINE_SAMPLE_SCRIPT as PINE_SAMPLE_SCRIPT2,
|
|
851
1124
|
PINE_EDITOR_DEFAULT
|
|
852
1125
|
} from "@coderyo/pine-lite";
|
|
@@ -863,7 +1136,7 @@ export {
|
|
|
863
1136
|
createDemoChartFeatures,
|
|
864
1137
|
createDemoChartOptions,
|
|
865
1138
|
resolveChartFeatures,
|
|
866
|
-
|
|
1139
|
+
runPineLite,
|
|
867
1140
|
wireChartBridge
|
|
868
1141
|
};
|
|
869
1142
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bridge-wire.ts","../src/version.ts","../src/chart-controller.ts","../src/chart-features.ts","../src/demo-presets.ts","../src/create-chart.ts","../src/index.ts"],"sourcesContent":["import type { BridgeAdapter } from '@coderyo/bridge';\nimport {\n BRIDGE_SCHEMA_VERSION,\n isBridgeInbound,\n type BridgeInboundType,\n type BridgeOutboundType,\n} from '@coderyo/bridge';\nimport type { Interval } from '@coderyo/data';\nimport type { CrosshairPayload } from '@coderyo/renderer-lite';\nimport type { ChartController, ChartEvent } from './chart-controller.js';\nimport type { IChart } from './create-chart.js';\nimport { TRADVIEW_VERSION } from './version.js';\n\nexport const TRADVIEW_API_VERSION = 1 as const;\n\nconst CHART_EVENT_TO_BRIDGE: Partial<Record<ChartEvent, BridgeOutboundType>> = {\n connectionChange: 'chart.connectionChange',\n visibleRangeChange: 'chart.visibleRange',\n error: 'chart.error',\n symbolChange: 'chart.symbol',\n intervalChange: 'chart.interval',\n crosshairChange: 'chart.crosshair',\n destroyed: 'chart.destroyed',\n};\n\nexport interface WireChartBridgeOptions {\n controller: ChartController;\n chart: IChart;\n bridge: BridgeAdapter;\n chartId?: string;\n /** Allowlist of outbound bridge events; default all mapped events. */\n outboundEvents?: BridgeOutboundType[];\n crosshairThrottleMs?: number;\n}\n\nexport function wireChartBridge(opts: WireChartBridgeOptions): () => void {\n const chartId = opts.chartId ?? `chart-${Date.now()}`;\n const { bridge, chart, controller } = opts;\n const allow = opts.outboundEvents ? new Set(opts.outboundEvents) : null;\n\n const shouldPost = (type: BridgeOutboundType): boolean =>\n allow === null || allow.has(type);\n\n const post = (type: BridgeOutboundType, payload: Record<string, unknown>) => {\n if (!shouldPost(type)) return;\n bridge.post({ type, payload });\n };\n\n post('chart.ready', {\n chartId,\n bridgeSchemaVersion: BRIDGE_SCHEMA_VERSION,\n apiVersion: TRADVIEW_API_VERSION,\n version: TRADVIEW_VERSION,\n });\n\n const postResize = () => {\n const el = controller.getContainer();\n const r = el.getBoundingClientRect();\n post('chart.resize', {\n chartId,\n width: Math.round(r.width),\n height: Math.round(r.height),\n });\n };\n if (shouldPost('chart.resize')) postResize();\n\n let crosshairTimer: ReturnType<typeof setTimeout> | null = null;\n let crosshairPending: CrosshairPayload | null = null;\n const throttleMs = opts.crosshairThrottleMs ?? 0;\n\n const flushCrosshair = () => {\n crosshairTimer = null;\n const p = crosshairPending;\n crosshairPending = null;\n if (!p) return;\n post('chart.crosshair', {\n chartId,\n time: p.time,\n price: p.price,\n ohlcv: p.ohlcv,\n symbol: controller.getSymbol(),\n interval: controller.getInterval(),\n });\n };\n\n const handlers = new Map<ChartEvent, (p?: unknown) => void>();\n\n handlers.set('connectionChange', (state) => {\n post('chart.connectionChange', { chartId, state });\n });\n handlers.set('visibleRangeChange', (range) => {\n const r = range as { from?: number; to?: number };\n post('chart.visibleRange', { chartId, from: r.from, to: r.to });\n });\n handlers.set('error', (err) => {\n const e = err as { code?: string; message?: string };\n post('chart.error', {\n chartId,\n code: e?.code ?? 'UNKNOWN',\n message: e?.message ?? String(err),\n });\n });\n handlers.set('symbolChange', (symbol) => {\n post('chart.symbol', { chartId, symbol: String(symbol ?? '') });\n });\n handlers.set('intervalChange', (interval) => {\n post('chart.interval', { chartId, interval: String(interval ?? '') });\n });\n handlers.set('crosshairChange', (payload) => {\n const p = payload as CrosshairPayload | null;\n if (!p) return;\n if (throttleMs <= 0) {\n post('chart.crosshair', {\n chartId,\n time: p.time,\n price: p.price,\n ohlcv: p.ohlcv,\n symbol: controller.getSymbol(),\n interval: controller.getInterval(),\n });\n return;\n }\n crosshairPending = p;\n if (!crosshairTimer) {\n crosshairTimer = setTimeout(flushCrosshair, throttleMs);\n }\n });\n handlers.set('destroyed', () => {\n post('chart.destroyed', { chartId });\n });\n\n for (const [ev, fn] of handlers) {\n const bridgeType = CHART_EVENT_TO_BRIDGE[ev];\n if (!bridgeType || shouldPost(bridgeType)) {\n chart.on(ev, fn);\n }\n }\n\n const offHost = bridge.onMessage((msg) => {\n if (!isBridgeInbound(msg)) return;\n const p = msg.payload ?? {};\n switch (msg.type as BridgeInboundType) {\n case 'host.setSymbol':\n if (typeof p.symbol === 'string') chart.setSymbol(p.symbol);\n break;\n case 'host.setInterval':\n if (typeof p.interval === 'string') chart.setInterval(p.interval as Interval);\n break;\n case 'host.setTheme':\n if (p.theme === 'dark' || p.theme === 'light') chart.setTheme(p.theme);\n break;\n case 'host.setShowGrid':\n if (typeof p.showGrid === 'boolean') chart.setShowGrid(p.showGrid);\n break;\n case 'host.fitContent':\n chart.fitContent();\n break;\n case 'host.scrollToRealtime':\n chart.scrollToRealtime();\n break;\n case 'host.resize':\n chart.resize({\n width: typeof p.width === 'number' ? p.width : undefined,\n height: typeof p.height === 'number' ? p.height : undefined,\n });\n postResize();\n break;\n case 'host.destroy':\n chart.destroy();\n break;\n default:\n break;\n }\n });\n\n return () => {\n if (crosshairTimer) clearTimeout(crosshairTimer);\n offHost();\n for (const [ev, fn] of handlers) chart.off(ev, fn);\n };\n}","/** Synced by scripts/sync-versions.mjs from repo VERSION file */\nexport const TRADVIEW_VERSION = '1.0.0-rc.4' as const;\n","import type { DrawingRecord, DrawingStyleMeta } from '@coderyo/drawings';\nimport type { IndicatorConfig } from '@coderyo/indicators';\n\nimport type {\n Bar,\n DataProvider,\n HistoryQuery,\n Interval,\n RealtimeStreamMode,\n SubscribeParams,\n SymbolResolver,\n} from '@coderyo/data';\nimport { floorBarOpenTime } from '@coderyo/data';\nimport type { HistoryRequest } from '@coderyo/virtual-window';\nimport { parseInterval } from '@coderyo/data';\nimport { BarStore } from '@coderyo/series';\nimport { VirtualWindow, type FetchPolicy } from '@coderyo/virtual-window';\nimport { DrawingManager } from '@coderyo/drawings';\nimport { compilePineLite, runPineLite, type PineIrProgram } from '@coderyo/pine-lite';\nimport { PaneOrchestrator } from '@coderyo/renderer-lite';\nimport {\n mergeChartFeatures,\n PENDING_SYMBOL,\n resolveChartFeatures,\n type ChartFeatures,\n type ResolvedChartFeatures,\n} from './chart-features.js';\n\nexport interface ChartOptions {\n width?: number;\n height?: number;\n theme?: 'dark' | 'light';\n interval?: Interval;\n /** Omit for empty chart until setSymbol(). */\n symbol?: string;\n chartId?: string;\n /** Host element below main chart for MACD/RSI/KDJ panes (from ui-shell layout). */\n indicatorHost?: HTMLElement;\n dataProvider: DataProvider;\n /** Integrator feature flags (minimal defaults). */\n features?: ChartFeatures;\n /** @deprecated Use features.fetchPolicy */\n fetchPolicy?: FetchPolicy;\n scaleMode?: 'linear' | 'log';\n /** Grid lines on chart panes (default false). */\n showGrid?: boolean;\n symbolResolver?: SymbolResolver;\n drawingDefaults?: { returnToCursorAfterDraw?: boolean };\n /** @deprecated Use features.indicators */\n indicatorConfig?: IndicatorConfig;\n}\n\nexport type ChartEvent =\n | 'connectionChange'\n | 'barUpdate'\n | 'error'\n | 'visibleRangeChange'\n | 'symbolChange'\n | 'intervalChange'\n | 'crosshairChange'\n | 'destroyed'\n | 'drawingSelectionChange'\n | 'drawingContextMenu'\n | 'requestCursorTool'\n | 'featuresChange';\n\ntype EventHandler = (payload?: unknown) => void;\n\nexport class ChartController {\n private readonly store: BarStore;\n private readonly virtualWindow: VirtualWindow;\n private readonly orchestrator: PaneOrchestrator;\n private readonly handlers = new Map<ChartEvent, Set<EventHandler>>();\n private subscriptionId: string | null = null;\n private destroyed = false;\n private readonly resizeObserver: ResizeObserver;\n private loadingMore = false;\n private visibleRangeInitialized = false;\n /** Bumped on symbol/interval change to drop stale bootstrap / loadMore / WS merges. */\n private loadGeneration = 0;\n private drawingManager: DrawingManager | null = null;\n private offCrosshair: (() => void) | null = null;\n private features: ResolvedChartFeatures;\n private pineIr: PineIrProgram | null = null;\n\n constructor(\n private readonly container: HTMLElement,\n private readonly options: ChartOptions,\n ) {\n this.features = resolveChartFeatures({\n ...options.features,\n fetchPolicy: options.features?.fetchPolicy ?? options.fetchPolicy,\n indicators:\n options.features?.indicators !== undefined\n ? options.features.indicators\n : options.indicatorConfig !== undefined\n ? options.indicatorConfig\n : undefined,\n });\n\n const symbol = options.symbol?.trim() || PENDING_SYMBOL;\n const interval = parseInterval(options.interval ?? '1h');\n const fetchPolicy = this.features.gaps.fillVisibleHoles\n ? 'fill-visible-holes'\n : this.features.fetchPolicy;\n\n this.store = new BarStore(symbol || PENDING_SYMBOL, interval);\n this.virtualWindow = new VirtualWindow(this.store, { fetchPolicy });\n this.orchestrator = new PaneOrchestrator({\n container,\n indicatorRoot: options.indicatorHost,\n theme: options.theme ?? 'dark',\n scaleMode: options.scaleMode ?? 'linear',\n showGrid: options.showGrid ?? false,\n indicatorConfig: this.features.indicators,\n smoothPriceUpdate: this.features.smoothPriceUpdate,\n smoothPriceDurationMs: this.features.smoothPriceDurationMs,\n });\n\n if (options.width) container.style.width = `${options.width}px`;\n if (options.height) container.style.height = `${options.height}px`;\n\n this.resizeObserver = new ResizeObserver(() => {\n if (!this.destroyed) this.resize();\n });\n this.resizeObserver.observe(container);\n\n this.orchestrator.bus.subscribeTransform(() => {\n const bus = this.orchestrator.bus;\n if (bus.visibleToMs > bus.visibleFromMs) {\n this.virtualWindow.setVisibleRange({\n fromMs: bus.visibleFromMs,\n toMs: bus.visibleToMs,\n });\n this.visibleRangeInitialized = true;\n }\n void this.maybeLoadMore();\n this.drawingManager?.redraw();\n });\n\n const overlay = this.orchestrator.getOverlayCanvas();\n if (overlay) {\n this.orchestrator.setOverlayPointerEvents('none');\n this.drawingManager = new DrawingManager({\n canvas: overlay,\n interactionHost: overlay.parentElement ?? undefined,\n chartId: options.chartId ?? 'default',\n symbol,\n interval,\n priceToY: (p) => this.orchestrator.priceToY(p),\n timeToX: (t) => this.orchestrator.timeToX(t),\n xToTime: (x) => this.orchestrator.xToTime(x),\n yToPrice: (y) => this.orchestrator.yToPrice(y),\n returnToCursorAfterDraw: options.drawingDefaults?.returnToCursorAfterDraw ?? false,\n onRequestCursorTool: () => this.emit('requestCursorTool'),\n onSelectionChange: (id, record) =>\n this.emit('drawingSelectionChange', { id, record }),\n onContextMenu: (payload) => this.emit('drawingContextMenu', payload),\n });\n this.drawingManager.setPersistence(this.features.drawings.persist);\n this.applyDrawingLayer();\n }\n\n this.offCrosshair = this.orchestrator.subscribeCrosshair((payload) => {\n this.emit('crosshairChange', payload);\n });\n\n if (this.hasActiveSymbol()) {\n void this.bootstrap(this.loadGeneration);\n } else {\n this.emit('connectionChange', 'disconnected');\n }\n }\n\n getFeatures(): ResolvedChartFeatures {\n return { ...this.features };\n }\n\n setFeatures(patch: ChartFeatures): this {\n this.features = mergeChartFeatures(this.features, patch);\n this.applyFeatures();\n this.emit('featuresChange', this.getFeatures());\n return this;\n }\n\n hasActiveSymbol(): boolean {\n const s = this.store.symbol;\n return s.length > 0 && s !== PENDING_SYMBOL;\n }\n\n private applyFeatures(): void {\n const fetchPolicy = this.features.gaps.fillVisibleHoles\n ? 'fill-visible-holes'\n : this.features.fetchPolicy;\n this.virtualWindow.setFetchPolicy(fetchPolicy);\n\n this.orchestrator.setIndicatorConfig(this.features.indicators);\n this.orchestrator.setSmoothPriceUpdate(\n this.features.smoothPriceUpdate,\n this.features.smoothPriceDurationMs,\n );\n this.drawingManager?.setPersistence(this.features.drawings.persist);\n this.applyDrawingLayer();\n this.recompilePine();\n }\n\n private recompilePine(): void {\n if (!this.features.pineEnabled || !this.features.pineScript?.trim()) {\n this.pineIr = null;\n this.orchestrator.setPinePlots(null);\n return;\n }\n const compiled = compilePineLite(this.features.pineScript);\n if (!compiled.ok || !compiled.ir) {\n this.pineIr = null;\n this.orchestrator.setPinePlots(null);\n this.emit('error', { kind: 'pine', errors: compiled.errors });\n return;\n }\n this.pineIr = compiled.ir;\n }\n\n private applyPinePlots(bars: Bar[]): void {\n if (!this.features.pineEnabled || !this.pineIr) {\n this.orchestrator.setPinePlots(null);\n return;\n }\n const result = runPineLite(this.pineIr, bars);\n this.orchestrator.setPinePlots(\n result.plots.map((p) => ({\n title: p.title,\n values: p.values,\n color: undefined,\n })),\n );\n }\n\n /** Integrator push: update last candle close (and H/L) without WS. */\n updateLastPrice(price: number, timeMs = Date.now()): this {\n if (!this.hasActiveSymbol() || this.destroyed) return this;\n const bar = this.buildBarFromPrice(price, timeMs);\n void this.applyRealtimeBar(bar, true);\n return this;\n }\n\n private buildBarFromPrice(price: number, timeMs: number): Bar {\n const interval = this.store.interval;\n const open = floorBarOpenTime(timeMs, interval);\n const times = this.store.sortedTimes;\n const lastT = times.length > 0 ? times[times.length - 1]! : undefined;\n const existing = lastT !== undefined ? this.store.getBar(lastT) : undefined;\n\n if (existing && existing.t === open) {\n return {\n ...existing,\n c: price,\n h: Math.max(existing.h, price),\n l: Math.min(existing.l, price),\n };\n }\n\n const prevClose = existing?.c ?? price;\n return {\n t: open,\n o: prevClose,\n h: Math.max(prevClose, price),\n l: Math.min(prevClose, price),\n c: price,\n v: existing?.v ?? 0,\n };\n }\n\n private async applyRealtimeBar(\n bar: Bar,\n partial: boolean,\n loadGen = this.loadGeneration,\n ): Promise<void> {\n await this.store.mergeRealtime({ bar, partial });\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n const bars = this.virtualWindow.getBarsForRender();\n const last = bars[bars.length - 1];\n if (last && this.features.smoothPriceUpdate) {\n this.orchestrator.updateLastBar(last, {\n smooth: true,\n durationMs: this.features.smoothPriceDurationMs,\n });\n this.drawingManager?.redraw();\n } else {\n this.refreshRender(loadGen);\n }\n this.emit('barUpdate', bar);\n }\n\n private applyDrawingLayer(): void {\n if (!this.drawingManager) return;\n this.drawingManager.setLayerVisible(this.features.drawings.layer);\n this.syncOverlayPointerEvents();\n }\n\n private syncOverlayPointerEvents(): void {\n if (!this.drawingManager) return;\n const layer = this.features.drawings.layer;\n if (!layer) {\n this.orchestrator.setOverlayPointerEvents('none');\n return;\n }\n const tool = this.drawingManager.getTool();\n this.orchestrator.setOverlayPointerEvents(tool === 'cursor' ? 'none' : 'auto');\n }\n\n getContainer(): HTMLElement {\n return this.container;\n }\n\n getSymbol(): string {\n return this.store.symbol;\n }\n\n getInterval(): Interval {\n return this.store.interval;\n }\n\n async searchSymbols(query: string): Promise<import('@coderyo/data').SymbolSearchHit[]> {\n const resolver = this.options.symbolResolver;\n if (resolver?.search) return resolver.search(query);\n if (this.options.dataProvider.searchSymbols) {\n return this.options.dataProvider.searchSymbols(query);\n }\n return [];\n }\n\n async resolveSymbol(symbol: string): Promise<import('@coderyo/data').SymbolInfo | null> {\n if (this.options.symbolResolver) {\n return this.options.symbolResolver.resolve(symbol);\n }\n return { symbol };\n }\n\n on(event: ChartEvent, handler: EventHandler): this {\n if (!this.handlers.has(event)) this.handlers.set(event, new Set());\n this.handlers.get(event)!.add(handler);\n return this;\n }\n\n off(event: ChartEvent, handler: EventHandler): this {\n this.handlers.get(event)?.delete(handler);\n return this;\n }\n\n resize(size?: { width?: number; height?: number }): this {\n if (size?.width) this.container.style.width = `${size.width}px`;\n if (size?.height) this.container.style.height = `${size.height}px`;\n this.orchestrator.resize();\n return this;\n }\n\n setDrawingTool(tool: import('@coderyo/drawings').DrawingTool): this {\n this.drawingManager?.setTool(tool);\n this.syncOverlayPointerEvents();\n return this;\n }\n\n deleteSelectedDrawing(): boolean {\n return this.drawingManager?.deleteSelected() ?? false;\n }\n\n copySelectedDrawing(): DrawingRecord | null {\n return this.drawingManager?.copySelected() ?? null;\n }\n\n toggleLockSelectedDrawing(): boolean {\n return this.drawingManager?.toggleLockSelected() ?? false;\n }\n\n updateSelectedDrawingStyle(patch: DrawingStyleMeta): void {\n this.drawingManager?.updateSelectedStyle(patch);\n }\n\n deselectDrawing(): void {\n this.drawingManager?.deselect();\n }\n\n setIndicatorConfig(config: IndicatorConfig | null): void {\n this.features = mergeChartFeatures(this.features, { indicators: config });\n this.orchestrator.setIndicatorConfig(config);\n this.emit('featuresChange', this.getFeatures());\n }\n\n setReturnToCursorAfterDraw(v: boolean): void {\n this.drawingManager?.setReturnToCursorAfterDraw(v);\n }\n\n async setSymbol(symbol: string): Promise<void> {\n const trimmed = symbol.trim();\n if (!trimmed) return;\n const gen = this.beginDataContextChange();\n await this.teardownSubscription();\n await this.store.setSymbolInterval(trimmed, this.store.interval);\n this.drawingManager?.setContext(symbol, this.store.interval);\n const info = await this.resolveSymbol(symbol);\n await this.bootstrap(gen);\n this.emit('symbolChange', info ?? { symbol });\n }\n\n async setInterval(interval: Interval): Promise<void> {\n const gen = this.beginDataContextChange();\n await this.teardownSubscription();\n await this.store.setSymbolInterval(this.store.symbol, interval);\n this.drawingManager?.setContext(this.store.symbol, interval);\n if (this.hasActiveSymbol()) {\n await this.bootstrap(gen);\n }\n }\n\n setTheme(theme: 'dark' | 'light'): this {\n this.orchestrator.setTheme(theme);\n return this;\n }\n\n setShowGrid(show: boolean): this {\n this.orchestrator.setShowGrid(show);\n return this;\n }\n\n fitContent(): this {\n this.orchestrator.fitContent();\n return this;\n }\n\n scrollToRealtime(): this {\n this.orchestrator.scrollToRealtime();\n return this;\n }\n\n setLogScale(enabled: boolean): this {\n this.orchestrator.setLogScale(enabled);\n return this;\n }\n\n setFullscreen(_enabled: boolean): this {\n if (_enabled && this.container.requestFullscreen) {\n void this.container.requestFullscreen();\n } else if (document.fullscreenElement) {\n void document.exitFullscreen();\n }\n return this;\n }\n\n async exportImage(opts?: { pixelRatio?: number }): Promise<Blob> {\n const canvas = this.container.querySelector('canvas');\n if (!canvas) throw new Error('No canvas to export');\n const scale = opts?.pixelRatio ?? 2;\n const exportCanvas = document.createElement('canvas');\n exportCanvas.width = canvas.width * scale;\n exportCanvas.height = canvas.height * scale;\n const ctx = exportCanvas.getContext('2d')!;\n ctx.scale(scale, scale);\n ctx.drawImage(canvas, 0, 0);\n return new Promise((resolve, reject) => {\n exportCanvas.toBlob((b) => (b ? resolve(b) : reject(new Error('export failed'))), 'image/png');\n });\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.offCrosshair?.();\n this.offCrosshair = null;\n this.resizeObserver.disconnect();\n this.drawingManager?.destroy();\n void this.teardownSubscription();\n this.orchestrator.destroy();\n this.emit('destroyed', { chartId: this.options.chartId ?? 'default' });\n this.emit('connectionChange', 'disconnected');\n }\n\n private beginDataContextChange(): number {\n this.loadGeneration += 1;\n this.visibleRangeInitialized = false;\n this.virtualWindow.setVisibleRange({ fromMs: 0, toMs: 0 });\n this.orchestrator.resetViewState();\n this.orchestrator.clearBars();\n return this.loadGeneration;\n }\n\n private isLoadGenerationCurrent(gen: number): boolean {\n return !this.destroyed && gen === this.loadGeneration;\n }\n\n private async bootstrap(loadGen: number): Promise<void> {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n const symbol = this.store.symbol;\n const interval = this.store.interval;\n const endTime = Date.now();\n const history = await this.options.dataProvider.getHistory({\n mode: 'loadMore',\n symbol,\n interval,\n endTime,\n limit: 500,\n });\n\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return;\n\n await this.store.mergeBars(history.bars.map((bar) => ({ bar })));\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n this.refreshRender(loadGen);\n void this.resolveSymbol(symbol).then((info) => {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n this.emit('symbolChange', info ?? { symbol });\n });\n this.emit('intervalChange', interval);\n\n const streamMode: RealtimeStreamMode = this.features.tickStream\n ? 'bar+tick'\n : this.features.streamMode;\n\n const params: SubscribeParams = {\n symbol,\n interval,\n channels: this.features.tickStream ? ['bar', 'tick'] : ['bar'],\n streamMode,\n };\n\n await this.options.dataProvider.connect?.();\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n const sub = await this.options.dataProvider.subscribe(params, {\n onBar: (bar, meta) => {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return;\n void this.applyRealtimeBar(bar, meta.partial, loadGen);\n },\n onTick: (tick) => {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return;\n const bar = this.buildBarFromPrice(tick.price, tick.t);\n void this.applyRealtimeBar(bar, true, loadGen);\n },\n onConnectionChange: (state) => this.emit('connectionChange', state),\n onError: (err) => this.emit('error', err),\n });\n if (!this.isLoadGenerationCurrent(loadGen)) {\n await this.options.dataProvider.unsubscribe(sub.id);\n return;\n }\n this.subscriptionId = sub.id;\n }\n\n private async teardownSubscription(): Promise<void> {\n if (this.subscriptionId) {\n await this.options.dataProvider.unsubscribe(this.subscriptionId);\n this.subscriptionId = null;\n }\n }\n\n private async maybeLoadMore(): Promise<void> {\n if (this.destroyed || this.loadingMore) return;\n const loadGen = this.loadGeneration;\n const reqs = this.virtualWindow.planFetches();\n if (reqs.length === 0) return;\n\n this.loadingMore = true;\n try {\n for (const req of reqs) {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n const history = await this.options.dataProvider.getHistory(toHistoryQuery(req));\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (history.bars.length === 0) continue;\n await this.store.mergeBars(\n history.bars.map((bar) => ({ bar, source: 'rest' as const })),\n req.mode === 'loadMore',\n );\n }\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n this.refreshRender(loadGen);\n } catch (err) {\n this.emit('error', err);\n } finally {\n this.loadingMore = false;\n }\n }\n\n private refreshRender(loadGen = this.loadGeneration): void {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n const times = this.store.sortedTimes;\n if (times.length === 0) return;\n\n // Only seed visible range once; resetting to full series each tick triggers spurious loadMore.\n if (!this.visibleRangeInitialized) {\n this.virtualWindow.setVisibleRange({\n fromMs: times[0]!,\n toMs: times[times.length - 1]!,\n });\n this.visibleRangeInitialized = true;\n }\n\n const bars = this.virtualWindow.getBarsForRender();\n if (bars.length === 0) return;\n\n this.orchestrator.setBars(bars);\n this.applyPinePlots(bars);\n this.drawingManager?.redraw();\n this.emit('visibleRangeChange', {\n from: bars[0]!.t,\n to: bars[bars.length - 1]!.t,\n });\n }\n\n private emit(event: ChartEvent, payload?: unknown): void {\n for (const h of this.handlers.get(event) ?? []) h(payload);\n }\n}\n\nfunction toHistoryQuery(req: HistoryRequest): HistoryQuery {\n if (req.mode === 'loadMore') {\n return {\n mode: 'loadMore',\n symbol: req.symbol,\n interval: req.interval,\n endTime: req.endTime ?? Date.now(),\n limit: req.limit,\n };\n }\n return {\n mode: 'range',\n symbol: req.symbol,\n interval: req.interval,\n from: req.fromMs ?? 0,\n to: req.toMs ?? Date.now(),\n };\n}","import type { RealtimeStreamMode } from '@coderyo/data';\nimport type { IndicatorConfig } from '@coderyo/indicators';\nimport type { FetchPolicy } from '@coderyo/virtual-window';\n\nexport interface ChartGapsFeatures {\n whitespace?: boolean;\n fillVisibleHoles?: boolean;\n}\n\nexport interface ChartDrawingsFeatures {\n /** Show interactive drawing overlay (default false). API remains available when false. */\n layer?: boolean;\n /** Persist drawings to localStorage (default true when layer/API used). */\n persist?: boolean;\n}\n\nexport interface ChartFeatures {\n fetchPolicy?: FetchPolicy;\n streamMode?: RealtimeStreamMode;\n gaps?: ChartGapsFeatures;\n drawings?: ChartDrawingsFeatures;\n /** Pass config to enable MA + indicator panes; omit/null = no indicators. */\n indicators?: IndicatorConfig | null;\n /** Save indicator params to storage (default false). */\n indicatorPersist?: boolean;\n /** Ease last candle OHLC + price line to new values (~150ms). */\n smoothPriceUpdate?: boolean;\n smoothPriceDurationMs?: number;\n /** Pine-lite script source (requires pineEnabled). */\n pineScript?: string | null;\n /** Post-1.0 hooks — default false. */\n pineEnabled?: boolean;\n protobuf?: boolean;\n telemetry?: boolean;\n tickStream?: boolean;\n}\n\nexport interface ResolvedChartFeatures {\n fetchPolicy: FetchPolicy;\n streamMode: RealtimeStreamMode;\n gaps: Required<ChartGapsFeatures>;\n drawings: Required<ChartDrawingsFeatures>;\n indicators: IndicatorConfig | null;\n indicatorPersist: boolean;\n smoothPriceUpdate: boolean;\n smoothPriceDurationMs: number;\n pineScript: string | null;\n pineEnabled: boolean;\n protobuf: boolean;\n telemetry: boolean;\n tickStream: boolean;\n}\n\nexport const DEFAULT_CHART_FEATURES: ResolvedChartFeatures = {\n fetchPolicy: 'lazy-left-only',\n streamMode: 'bar',\n gaps: { whitespace: false, fillVisibleHoles: false },\n drawings: { layer: false, persist: true },\n indicators: null,\n indicatorPersist: false,\n smoothPriceUpdate: false,\n smoothPriceDurationMs: 150,\n pineScript: null,\n pineEnabled: false,\n protobuf: false,\n telemetry: false,\n tickStream: false,\n};\n\nexport function resolveChartFeatures(partial?: ChartFeatures): ResolvedChartFeatures {\n const d = DEFAULT_CHART_FEATURES;\n return {\n fetchPolicy: partial?.fetchPolicy ?? d.fetchPolicy,\n streamMode: partial?.streamMode ?? d.streamMode,\n gaps: {\n whitespace: partial?.gaps?.whitespace ?? d.gaps.whitespace,\n fillVisibleHoles: partial?.gaps?.fillVisibleHoles ?? d.gaps.fillVisibleHoles,\n },\n drawings: {\n layer: partial?.drawings?.layer ?? d.drawings.layer,\n persist: partial?.drawings?.persist ?? d.drawings.persist,\n },\n indicators: partial?.indicators !== undefined ? partial.indicators : d.indicators,\n indicatorPersist: partial?.indicatorPersist ?? d.indicatorPersist,\n smoothPriceUpdate: partial?.smoothPriceUpdate ?? d.smoothPriceUpdate,\n smoothPriceDurationMs: partial?.smoothPriceDurationMs ?? d.smoothPriceDurationMs,\n pineScript: partial?.pineScript !== undefined ? partial.pineScript : d.pineScript,\n pineEnabled: partial?.pineEnabled ?? d.pineEnabled,\n protobuf: partial?.protobuf ?? d.protobuf,\n telemetry: partial?.telemetry ?? d.telemetry,\n tickStream: partial?.tickStream ?? d.tickStream,\n };\n}\n\nexport function mergeChartFeatures(\n current: ResolvedChartFeatures,\n patch: ChartFeatures,\n): ResolvedChartFeatures {\n return resolveChartFeatures({\n fetchPolicy: patch.fetchPolicy ?? current.fetchPolicy,\n streamMode: patch.streamMode ?? current.streamMode,\n gaps: { ...current.gaps, ...patch.gaps },\n drawings: { ...current.drawings, ...patch.drawings },\n indicators: patch.indicators !== undefined ? patch.indicators : current.indicators,\n indicatorPersist: patch.indicatorPersist ?? current.indicatorPersist,\n smoothPriceUpdate: patch.smoothPriceUpdate ?? current.smoothPriceUpdate,\n smoothPriceDurationMs: patch.smoothPriceDurationMs ?? current.smoothPriceDurationMs,\n pineScript: patch.pineScript !== undefined ? patch.pineScript : current.pineScript,\n pineEnabled: patch.pineEnabled ?? current.pineEnabled,\n protobuf: patch.protobuf ?? current.protobuf,\n telemetry: patch.telemetry ?? current.telemetry,\n tickStream: patch.tickStream ?? current.tickStream,\n });\n}\n\n/** Empty chart until integrator calls setSymbol. */\nexport const PENDING_SYMBOL = '';","import type { IndicatorConfig } from '@coderyo/indicators';\nimport { DEFAULT_INDICATOR_CONFIG } from '@coderyo/indicators';\nimport { PINE_SAMPLE_SCRIPT } from '@coderyo/pine-lite';\nimport type { Interval } from '@coderyo/data';\nimport type { ChartFeatures } from './chart-features.js';\nimport type { ChartOptions } from './chart-controller.js';\n\n/** Playground / docs: opt-in full TV-like chart features. */\nexport function createDemoChartFeatures(opts: {\n indicatorConfig?: IndicatorConfig;\n returnToCursorAfterDraw?: boolean;\n}): ChartFeatures {\n return {\n fetchPolicy: 'lazy-left-only',\n streamMode: 'bar+tick',\n gaps: { whitespace: false, fillVisibleHoles: false },\n drawings: { layer: true, persist: true },\n indicators: opts.indicatorConfig ?? DEFAULT_INDICATOR_CONFIG,\n indicatorPersist: true,\n smoothPriceUpdate: true,\n smoothPriceDurationMs: 150,\n tickStream: true,\n pineEnabled: true,\n pineScript: PINE_SAMPLE_SCRIPT,\n };\n}\n\nexport function createDemoChartOptions(\n base: Pick<ChartOptions, 'dataProvider' | 'indicatorHost' | 'symbolResolver' | 'chartId'> & {\n symbol: string;\n interval: Interval;\n theme?: 'dark' | 'light';\n showGrid?: boolean;\n indicatorConfig?: IndicatorConfig;\n returnToCursorAfterDraw?: boolean;\n },\n): ChartOptions {\n const indicatorConfig = base.indicatorConfig ?? DEFAULT_INDICATOR_CONFIG;\n return {\n ...base,\n features: createDemoChartFeatures({\n indicatorConfig,\n returnToCursorAfterDraw: base.returnToCursorAfterDraw,\n }),\n indicatorConfig,\n drawingDefaults: { returnToCursorAfterDraw: base.returnToCursorAfterDraw ?? false },\n };\n}","import type { BridgeAdapter } from '@coderyo/bridge';\nimport type { BridgeOutboundType } from '@coderyo/bridge';\nimport type { DrawingRecord, DrawingStyleMeta } from '@coderyo/drawings';\nimport type { IndicatorConfig } from '@coderyo/indicators';\nimport type { DataProvider } from '@coderyo/data';\nimport { wireChartBridge, TRADVIEW_API_VERSION } from './bridge-wire.js';\nimport { ChartController, type ChartOptions } from './chart-controller.js';\nimport type { ChartFeatures, ResolvedChartFeatures } from './chart-features.js';\nimport { TRADVIEW_VERSION } from './version.js';\n\nexport { TRADVIEW_API_VERSION, TRADVIEW_VERSION };\nexport type { ChartFeatures, ResolvedChartFeatures } from './chart-features.js';\nexport { resolveChartFeatures, DEFAULT_CHART_FEATURES, PENDING_SYMBOL } from './chart-features.js';\nexport { createDemoChartFeatures, createDemoChartOptions } from './demo-presets.js';\n\nexport interface CreateChartOptions extends Omit<ChartOptions, 'dataProvider'> {\n dataProvider: DataProvider;\n bridge?: BridgeAdapter;\n chartId?: string;\n /** If set, only these bridge outbound events are posted. */\n bridgeOutboundEvents?: BridgeOutboundType[];\n bridgeCrosshairThrottleMs?: number;\n}\n\nexport interface IChart {\n setSymbol(symbol: string): IChart;\n setInterval(interval: import('@coderyo/data').Interval): IChart;\n setTheme(theme: 'dark' | 'light'): IChart;\n setShowGrid(show: boolean): IChart;\n setLogScale(enabled: boolean): IChart;\n fitContent(): IChart;\n scrollToRealtime(): IChart;\n resize(size?: { width?: number; height?: number }): IChart;\n setFullscreen(enabled: boolean): IChart;\n exportImage(opts?: { pixelRatio?: number }): Promise<Blob>;\n on(event: import('./chart-controller.js').ChartEvent, handler: (p?: unknown) => void): IChart;\n off(event: import('./chart-controller.js').ChartEvent, handler: (p?: unknown) => void): IChart;\n searchSymbols(query: string): Promise<import('@coderyo/data').SymbolSearchHit[]>;\n setDrawingTool(tool: import('@coderyo/drawings').DrawingTool): IChart;\n deleteSelectedDrawing(): boolean;\n copySelectedDrawing(): DrawingRecord | null;\n toggleLockSelectedDrawing(): boolean;\n updateSelectedDrawingStyle(patch: DrawingStyleMeta): void;\n deselectDrawing(): void;\n setIndicatorConfig(config: IndicatorConfig | null): void;\n setReturnToCursorAfterDraw(v: boolean): void;\n setFeatures(patch: ChartFeatures): IChart;\n getFeatures(): ResolvedChartFeatures;\n /** Integrator push: smooth-update last candle toward `price` (no WS required). */\n updateLastPrice(price: number, timeMs?: number): IChart;\n hasActiveSymbol(): boolean;\n destroy(): void;\n}\n\nfunction wrap(controller: ChartController, beforeDestroy?: () => void): IChart {\n return {\n setSymbol: (s) => {\n void controller.setSymbol(s);\n return wrap(controller, beforeDestroy);\n },\n setInterval: (i) => {\n void controller.setInterval(i);\n return wrap(controller, beforeDestroy);\n },\n setTheme: (t) => {\n controller.setTheme(t);\n return wrap(controller, beforeDestroy);\n },\n setShowGrid: (show) => {\n controller.setShowGrid(show);\n return wrap(controller, beforeDestroy);\n },\n setLogScale: (enabled) => {\n controller.setLogScale(enabled);\n return wrap(controller, beforeDestroy);\n },\n fitContent: () => {\n controller.fitContent();\n return wrap(controller, beforeDestroy);\n },\n scrollToRealtime: () => {\n controller.scrollToRealtime();\n return wrap(controller, beforeDestroy);\n },\n resize: (s) => {\n controller.resize(s);\n return wrap(controller, beforeDestroy);\n },\n setFullscreen: (e) => {\n controller.setFullscreen(e);\n return wrap(controller, beforeDestroy);\n },\n exportImage: (o) => controller.exportImage(o),\n on: (e, h) => {\n controller.on(e, h);\n return wrap(controller, beforeDestroy);\n },\n off: (e, h) => {\n controller.off(e, h);\n return wrap(controller, beforeDestroy);\n },\n searchSymbols: (q) => controller.searchSymbols(q),\n setDrawingTool: (tool) => {\n controller.setDrawingTool(tool);\n return wrap(controller, beforeDestroy);\n },\n deleteSelectedDrawing: () => controller.deleteSelectedDrawing(),\n copySelectedDrawing: () => controller.copySelectedDrawing(),\n toggleLockSelectedDrawing: () => controller.toggleLockSelectedDrawing(),\n updateSelectedDrawingStyle: (p) => {\n controller.updateSelectedDrawingStyle(p);\n return wrap(controller, beforeDestroy);\n },\n deselectDrawing: () => {\n controller.deselectDrawing();\n return wrap(controller, beforeDestroy);\n },\n setIndicatorConfig: (c) => {\n controller.setIndicatorConfig(c);\n return wrap(controller, beforeDestroy);\n },\n setReturnToCursorAfterDraw: (v) => {\n controller.setReturnToCursorAfterDraw(v);\n return wrap(controller, beforeDestroy);\n },\n setFeatures: (patch) => {\n controller.setFeatures(patch);\n return wrap(controller, beforeDestroy);\n },\n getFeatures: () => controller.getFeatures(),\n updateLastPrice: (price, timeMs) => {\n controller.updateLastPrice(price, timeMs);\n return wrap(controller, beforeDestroy);\n },\n hasActiveSymbol: () => controller.hasActiveSymbol(),\n destroy: () => {\n controller.destroy();\n beforeDestroy?.();\n },\n };\n}\n\nexport function createChart(\n target: HTMLElement | string,\n options: CreateChartOptions,\n): IChart {\n const el =\n typeof target === 'string'\n ? (document.querySelector(target) as HTMLElement | null)\n : target;\n if (!el) throw new Error('Chart container not found');\n const controller = new ChartController(el, options);\n let bridgeTeardown: (() => void) | undefined;\n const chart = wrap(controller, () => bridgeTeardown?.());\n if (options.bridge) {\n bridgeTeardown = wireChartBridge({\n controller,\n chart,\n bridge: options.bridge,\n chartId: options.chartId,\n outboundEvents: options.bridgeOutboundEvents,\n crosshairThrottleMs: options.bridgeCrosshairThrottleMs,\n });\n }\n return chart;\n}","export {\n createChart,\n type IChart,\n type CreateChartOptions,\n TRADVIEW_API_VERSION,\n TRADVIEW_VERSION,\n type ChartFeatures,\n type ResolvedChartFeatures,\n resolveChartFeatures,\n DEFAULT_CHART_FEATURES,\n PENDING_SYMBOL,\n createDemoChartFeatures,\n createDemoChartOptions,\n} from './create-chart.js';\nexport { ChartController, type ChartOptions, type ChartEvent } from './chart-controller.js';\nexport { wireChartBridge, type WireChartBridgeOptions } from './bridge-wire.js';\nexport {\n compilePineLite,\n runPineLite,\n PINE_SAMPLE_SCRIPT,\n PINE_EDITOR_DEFAULT,\n type PineCompileResult,\n type PineIrProgram,\n type PinePlotSeries,\n} from '@coderyo/pine-lite';"],"mappings":"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","names":["compilePineLite","runPineLite","PINE_SAMPLE_SCRIPT"]}
|
|
1
|
+
{"version":3,"sources":["../src/bridge-wire.ts","../src/version.ts","../src/chart-controller.ts","../src/fetch-chart-history.ts","../src/chart-features.ts","../src/demo-presets.ts","../src/create-chart.ts","../src/index.ts"],"sourcesContent":["import type { BridgeAdapter } from '@coderyo/bridge';\nimport {\n BRIDGE_SCHEMA_VERSION,\n isBridgeInbound,\n type BridgeInboundType,\n type BridgeOutboundType,\n} from '@coderyo/bridge';\nimport type { Interval } from '@coderyo/data';\nimport type { CrosshairPayload } from '@coderyo/renderer-lite';\nimport type { ChartController, ChartEvent } from './chart-controller.js';\nimport type { IChart } from './create-chart.js';\nimport { TRADVIEW_VERSION } from './version.js';\n\nexport const TRADVIEW_API_VERSION = 1 as const;\n\nconst CHART_EVENT_TO_BRIDGE: Partial<Record<ChartEvent, BridgeOutboundType>> = {\n connectionChange: 'chart.connectionChange',\n visibleRangeChange: 'chart.visibleRange',\n error: 'chart.error',\n symbolChange: 'chart.symbol',\n intervalChange: 'chart.interval',\n crosshairChange: 'chart.crosshair',\n destroyed: 'chart.destroyed',\n barUpdate: 'chart.barUpdate',\n};\n\nexport interface WireChartBridgeOptions {\n controller: ChartController;\n chart: IChart;\n bridge: BridgeAdapter;\n chartId?: string;\n /** Allowlist of outbound bridge events; default all mapped events. */\n outboundEvents?: BridgeOutboundType[];\n crosshairThrottleMs?: number;\n}\n\nexport function wireChartBridge(opts: WireChartBridgeOptions): () => void {\n const chartId = opts.chartId ?? `chart-${Date.now()}`;\n const { bridge, chart, controller } = opts;\n const allow = opts.outboundEvents ? new Set(opts.outboundEvents) : null;\n\n const shouldPost = (type: BridgeOutboundType): boolean =>\n allow === null || allow.has(type);\n\n const post = (type: BridgeOutboundType, payload: Record<string, unknown>) => {\n if (!shouldPost(type)) return;\n bridge.post({ type, payload });\n };\n\n post('chart.ready', {\n chartId,\n bridgeSchemaVersion: BRIDGE_SCHEMA_VERSION,\n apiVersion: TRADVIEW_API_VERSION,\n version: TRADVIEW_VERSION,\n });\n\n const postResize = () => {\n const el = controller.getContainer();\n const r = el.getBoundingClientRect();\n post('chart.resize', {\n chartId,\n width: Math.round(r.width),\n height: Math.round(r.height),\n });\n };\n if (shouldPost('chart.resize')) postResize();\n\n let crosshairTimer: ReturnType<typeof setTimeout> | null = null;\n let crosshairPending: CrosshairPayload | null = null;\n const throttleMs = opts.crosshairThrottleMs ?? 0;\n\n const flushCrosshair = () => {\n crosshairTimer = null;\n const p = crosshairPending;\n crosshairPending = null;\n if (!p) return;\n post('chart.crosshair', {\n chartId,\n time: p.time,\n price: p.price,\n ohlcv: p.ohlcv,\n symbol: controller.getSymbol(),\n interval: controller.getInterval(),\n });\n };\n\n const handlers = new Map<ChartEvent, (p?: unknown) => void>();\n\n handlers.set('connectionChange', (state) => {\n post('chart.connectionChange', { chartId, state });\n });\n handlers.set('visibleRangeChange', (range) => {\n const r = range as { from?: number; to?: number };\n post('chart.visibleRange', { chartId, from: r.from, to: r.to });\n });\n handlers.set('error', (err) => {\n const e = err as { code?: string; message?: string };\n post('chart.error', {\n chartId,\n code: e?.code ?? 'UNKNOWN',\n message: e?.message ?? String(err),\n });\n });\n handlers.set('symbolChange', (symbol) => {\n post('chart.symbol', { chartId, symbol: String(symbol ?? '') });\n });\n handlers.set('intervalChange', (interval) => {\n post('chart.interval', { chartId, interval: String(interval ?? '') });\n });\n handlers.set('crosshairChange', (payload) => {\n const p = payload as CrosshairPayload | null;\n if (!p) return;\n if (throttleMs <= 0) {\n post('chart.crosshair', {\n chartId,\n time: p.time,\n price: p.price,\n ohlcv: p.ohlcv,\n symbol: controller.getSymbol(),\n interval: controller.getInterval(),\n });\n return;\n }\n crosshairPending = p;\n if (!crosshairTimer) {\n crosshairTimer = setTimeout(flushCrosshair, throttleMs);\n }\n });\n handlers.set('destroyed', () => {\n post('chart.destroyed', { chartId });\n });\n handlers.set('barUpdate', (bar) => {\n const b = bar as { t?: number; c?: number };\n post('chart.barUpdate', { chartId, t: b?.t, c: b?.c });\n });\n\n for (const [ev, fn] of handlers) {\n const bridgeType = CHART_EVENT_TO_BRIDGE[ev];\n if (!bridgeType || shouldPost(bridgeType)) {\n chart.on(ev, fn);\n }\n }\n\n const offHost = bridge.onMessage((msg) => {\n if (!isBridgeInbound(msg)) return;\n const p = msg.payload ?? {};\n switch (msg.type as BridgeInboundType) {\n case 'host.setSymbol':\n if (typeof p.symbol === 'string') chart.setSymbol(p.symbol);\n break;\n case 'host.setInterval':\n if (typeof p.interval === 'string') chart.setInterval(p.interval as Interval);\n break;\n case 'host.setTheme':\n if (p.theme === 'dark' || p.theme === 'light') chart.setTheme(p.theme);\n break;\n case 'host.setShowGrid':\n if (typeof p.showGrid === 'boolean') chart.setShowGrid(p.showGrid);\n break;\n case 'host.fitContent':\n chart.fitContent();\n break;\n case 'host.scrollToRealtime':\n chart.scrollToRealtime();\n break;\n case 'host.resize':\n chart.resize({\n width: typeof p.width === 'number' ? p.width : undefined,\n height: typeof p.height === 'number' ? p.height : undefined,\n });\n postResize();\n break;\n case 'host.setLogScale':\n if (typeof p.enabled === 'boolean') chart.setLogScale(p.enabled);\n break;\n case 'host.setBarSpace':\n if (typeof p.px === 'number') chart.setBarSpace(p.px);\n break;\n case 'host.setVisibleRange':\n if (typeof p.fromMs === 'number' && typeof p.toMs === 'number') {\n chart.setVisibleRange({ fromMs: p.fromMs, toMs: p.toMs });\n }\n break;\n case 'host.scrollToTimestamp':\n if (typeof p.tsMs === 'number') {\n chart.scrollToTimestamp(\n p.tsMs,\n typeof p.animationMs === 'number' ? p.animationMs : undefined,\n );\n }\n break;\n case 'host.reloadHistory':\n void chart.reloadHistory();\n break;\n case 'host.setLocale':\n if (typeof p.locale === 'string') chart.setLocale(p.locale);\n break;\n case 'host.setFeatures':\n if (p.features && typeof p.features === 'object') {\n chart.setFeatures(p.features as import('./chart-features.js').ChartFeatures);\n }\n break;\n case 'host.destroy':\n chart.destroy();\n break;\n default:\n break;\n }\n });\n\n return () => {\n if (crosshairTimer) clearTimeout(crosshairTimer);\n offHost();\n for (const [ev, fn] of handlers) chart.off(ev, fn);\n };\n}","/** Synced by scripts/sync-versions.mjs from repo VERSION file */\nexport const TRADVIEW_VERSION = '1.0.1' as const;\n","import type { DrawingRecord, DrawingStyleMeta } from '@coderyo/drawings';\nimport type { IndicatorConfig } from '@coderyo/indicators';\n\nimport type {\n Bar,\n DataProvider,\n HistoryQuery,\n Interval,\n RealtimeStreamMode,\n SubscribeParams,\n SymbolResolver,\n} from '@coderyo/data';\nimport { floorBarOpenTime, intervalMs } from '@coderyo/data';\nimport type { HistoryRequest } from '@coderyo/virtual-window';\nimport { parseInterval } from '@coderyo/data';\nimport { BarStore, computeGapStartTimes, TickAggregator } from '@coderyo/series';\nimport { setLocale as setI18nLocale } from '@coderyo/i18n';\nimport { fetchChartHistory } from './fetch-chart-history.js';\nimport { VirtualWindow, type FetchPolicy } from '@coderyo/virtual-window';\nimport { DrawingManager } from '@coderyo/drawings';\nimport {\n compilePineLite,\n runPineLiteAsync,\n terminatePineWorker,\n type PineIrProgram,\n} from '@coderyo/pine-lite';\nimport { PaneOrchestrator, type ChartVisibleRange } from '@coderyo/renderer-lite';\n\nexport type { ChartVisibleRange };\nimport {\n mergeChartFeatures,\n PENDING_SYMBOL,\n resolveChartFeatures,\n type ChartFeatures,\n type ResolvedChartFeatures,\n} from './chart-features.js';\n\nexport interface ChartOptions {\n width?: number;\n height?: number;\n theme?: 'dark' | 'light';\n interval?: Interval;\n /** Omit for empty chart until setSymbol(). */\n symbol?: string;\n chartId?: string;\n /** Host element below main chart for MACD/RSI/KDJ panes (from ui-shell layout). */\n indicatorHost?: HTMLElement;\n dataProvider: DataProvider;\n /** Integrator feature flags (minimal defaults). */\n features?: ChartFeatures;\n /** @deprecated Use features.fetchPolicy */\n fetchPolicy?: FetchPolicy;\n scaleMode?: 'linear' | 'log';\n /** Grid lines on chart panes (default false). */\n showGrid?: boolean;\n symbolResolver?: SymbolResolver;\n drawingDefaults?: { returnToCursorAfterDraw?: boolean };\n /** @deprecated Use features.indicators */\n indicatorConfig?: IndicatorConfig;\n}\n\nexport type ChartEvent =\n | 'connectionChange'\n | 'barUpdate'\n | 'error'\n | 'visibleRangeChange'\n | 'symbolChange'\n | 'intervalChange'\n | 'crosshairChange'\n | 'destroyed'\n | 'drawingSelectionChange'\n | 'drawingContextMenu'\n | 'requestCursorTool'\n | 'featuresChange'\n | 'telemetry';\n\ntype EventHandler = (payload?: unknown) => void;\n\nexport class ChartController {\n private readonly store: BarStore;\n private readonly virtualWindow: VirtualWindow;\n private readonly orchestrator: PaneOrchestrator;\n private readonly handlers = new Map<ChartEvent, Set<EventHandler>>();\n private subscriptionId: string | null = null;\n private destroyed = false;\n private readonly resizeObserver: ResizeObserver;\n private loadingMore = false;\n private visibleRangeInitialized = false;\n /** Bumped on symbol/interval change to drop stale bootstrap / loadMore / WS merges. */\n private loadGeneration = 0;\n private drawingManager: DrawingManager | null = null;\n private offCrosshair: (() => void) | null = null;\n private features: ResolvedChartFeatures;\n private pineIr: PineIrProgram | null = null;\n private tickAggregator: TickAggregator | null = null;\n private catchUpInFlight = false;\n private lastCatchUpAt = 0;\n private offPageResume: (() => void) | null = null;\n\n constructor(\n private readonly container: HTMLElement,\n private readonly options: ChartOptions,\n ) {\n this.features = resolveChartFeatures({\n ...options.features,\n fetchPolicy: options.features?.fetchPolicy ?? options.fetchPolicy,\n indicators:\n options.features?.indicators !== undefined\n ? options.features.indicators\n : options.indicatorConfig !== undefined\n ? options.indicatorConfig\n : undefined,\n });\n\n const symbol = options.symbol?.trim() || PENDING_SYMBOL;\n const interval = parseInterval(options.interval ?? '1h');\n const fetchPolicy = this.features.gaps.fillVisibleHoles\n ? 'fill-visible-holes'\n : this.features.fetchPolicy;\n\n this.store = new BarStore(symbol || PENDING_SYMBOL, interval);\n this.virtualWindow = new VirtualWindow(this.store, { fetchPolicy });\n this.orchestrator = new PaneOrchestrator({\n container,\n indicatorRoot: options.indicatorHost,\n theme: options.theme ?? 'dark',\n scaleMode: options.scaleMode ?? 'linear',\n showGrid: options.showGrid ?? false,\n indicatorConfig: this.features.indicators,\n smoothPriceUpdate: this.features.smoothPriceUpdate,\n smoothPriceDurationMs: this.features.smoothPriceDurationMs,\n });\n\n if (options.width) container.style.width = `${options.width}px`;\n if (options.height) container.style.height = `${options.height}px`;\n\n this.resizeObserver = new ResizeObserver(() => {\n if (!this.destroyed) this.resize();\n });\n this.resizeObserver.observe(container);\n\n this.orchestrator.bus.subscribeTransform(() => {\n const bus = this.orchestrator.bus;\n if (bus.visibleToMs > bus.visibleFromMs) {\n this.virtualWindow.setVisibleRange({\n fromMs: bus.visibleFromMs,\n toMs: bus.visibleToMs,\n });\n this.visibleRangeInitialized = true;\n }\n void this.maybeLoadMore();\n this.drawingManager?.redraw();\n });\n\n const overlay = this.orchestrator.getOverlayCanvas();\n if (overlay) {\n this.orchestrator.setOverlayPointerEvents('none');\n this.drawingManager = new DrawingManager({\n canvas: overlay,\n interactionHost: overlay.parentElement ?? undefined,\n chartId: options.chartId ?? 'default',\n symbol,\n interval,\n priceToY: (p) => this.orchestrator.priceToY(p),\n timeToX: (t) => this.orchestrator.timeToX(t),\n xToTime: (x) => this.orchestrator.xToTime(x),\n yToPrice: (y) => this.orchestrator.yToPrice(y),\n returnToCursorAfterDraw: options.drawingDefaults?.returnToCursorAfterDraw ?? false,\n onRequestCursorTool: () => this.emit('requestCursorTool'),\n onSelectionChange: (id, record) =>\n this.emit('drawingSelectionChange', { id, record }),\n onContextMenu: (payload) => this.emit('drawingContextMenu', payload),\n });\n this.drawingManager.setPersistence(this.features.drawings.persist);\n this.applyDrawingLayer();\n }\n\n this.offCrosshair = this.orchestrator.subscribeCrosshair((payload) => {\n this.emit('crosshairChange', payload);\n });\n\n this.bindPageResumeCatchUp();\n\n if (this.hasActiveSymbol()) {\n void this.bootstrap(this.loadGeneration);\n } else {\n this.emit('connectionChange', 'disconnected');\n }\n }\n\n getFeatures(): ResolvedChartFeatures {\n return { ...this.features };\n }\n\n setFeatures(patch: ChartFeatures): this {\n this.features = mergeChartFeatures(this.features, patch);\n this.applyFeatures();\n this.emit('featuresChange', this.getFeatures());\n return this;\n }\n\n hasActiveSymbol(): boolean {\n const s = this.store.symbol;\n return s.length > 0 && s !== PENDING_SYMBOL;\n }\n\n private applyFeatures(): void {\n const fetchPolicy = this.features.gaps.fillVisibleHoles\n ? 'fill-visible-holes'\n : this.features.fetchPolicy;\n this.virtualWindow.setFetchPolicy(fetchPolicy);\n\n this.orchestrator.setIndicatorConfig(this.features.indicators);\n this.orchestrator.setSmoothPriceUpdate(\n this.features.smoothPriceUpdate,\n this.features.smoothPriceDurationMs,\n );\n this.drawingManager?.setPersistence(this.features.drawings.persist);\n this.applyDrawingLayer();\n this.recompilePine();\n }\n\n private recompilePine(): void {\n if (!this.features.pineEnabled || !this.features.pineScript?.trim()) {\n this.pineIr = null;\n this.orchestrator.setPinePlots(null);\n return;\n }\n const compiled = compilePineLite(this.features.pineScript);\n if (!compiled.ok || !compiled.ir) {\n this.pineIr = null;\n this.orchestrator.setPinePlots(null);\n this.emit('error', { kind: 'pine', errors: compiled.errors });\n return;\n }\n this.pineIr = compiled.ir;\n if (this.hasActiveSymbol()) {\n const bars = this.virtualWindow.getBarsForRender();\n if (bars.length > 0) this.applyPinePlots(bars);\n }\n }\n\n private applyPinePlots(bars: Bar[]): void {\n if (!this.features.pineEnabled || !this.pineIr) {\n this.orchestrator.setPinePlots(null);\n return;\n }\n const ir = this.pineIr;\n const useWorker = this.features.pineWorker;\n void runPineLiteAsync(ir, bars, { useWorker })\n .then((result) => {\n if (this.destroyed || this.pineIr !== ir) return;\n this.orchestrator.setPinePlots(\n result.plots.map((p) => ({\n title: p.title,\n values: p.values,\n color: undefined,\n })),\n );\n })\n .catch((err) => this.emit('error', err));\n }\n\n private trackTelemetry(event: string, data?: Record<string, unknown>): void {\n if (!this.features.telemetry) return;\n this.emit('telemetry', { event, ...data });\n }\n\n setLocale(locale: string): this {\n setI18nLocale(locale);\n this.trackTelemetry('locale', { locale });\n return this;\n }\n\n subscribeBars(handler: (bar: Bar) => void): () => void {\n const wrapper = (payload?: unknown) => handler(payload as Bar);\n this.on('barUpdate', wrapper);\n return () => this.off('barUpdate', wrapper);\n }\n\n /** Integrator push: update last candle close (and H/L) without WS. */\n updateLastPrice(price: number, timeMs = Date.now()): this {\n if (!this.hasActiveSymbol() || this.destroyed) return this;\n const bar = this.buildBarFromPrice(price, timeMs);\n void this.applyRealtimeBar(bar, true);\n return this;\n }\n\n private buildBarFromPrice(price: number, timeMs: number): Bar {\n const interval = this.store.interval;\n const open = floorBarOpenTime(timeMs, interval);\n const times = this.store.sortedTimes;\n const lastT = times.length > 0 ? times[times.length - 1]! : undefined;\n const existing = lastT !== undefined ? this.store.getBar(lastT) : undefined;\n\n if (existing && existing.t === open) {\n return {\n ...existing,\n c: price,\n h: Math.max(existing.h, price),\n l: Math.min(existing.l, price),\n };\n }\n\n const prevClose = existing?.c ?? price;\n return {\n t: open,\n o: prevClose,\n h: Math.max(prevClose, price),\n l: Math.min(prevClose, price),\n c: price,\n v: existing?.v ?? 0,\n };\n }\n\n private async applyRealtimeBar(\n bar: Bar,\n partial: boolean,\n loadGen = this.loadGeneration,\n ): Promise<void> {\n await this.store.mergeRealtime({ bar, partial });\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n const bars = this.virtualWindow.getBarsForRender();\n const last = bars[bars.length - 1];\n if (last && this.features.smoothPriceUpdate) {\n this.orchestrator.updateLastBar(last, {\n smooth: true,\n durationMs: this.features.smoothPriceDurationMs,\n });\n this.drawingManager?.redraw();\n } else {\n this.refreshRender(loadGen);\n }\n this.emit('barUpdate', bar);\n this.trackTelemetry('barUpdate', { t: bar.t, partial });\n }\n\n private applyDrawingLayer(): void {\n if (!this.drawingManager) return;\n this.drawingManager.setLayerVisible(this.features.drawings.layer);\n this.syncOverlayPointerEvents();\n }\n\n private syncOverlayPointerEvents(): void {\n if (!this.drawingManager) return;\n const layer = this.features.drawings.layer;\n if (!layer) {\n this.orchestrator.setOverlayPointerEvents('none');\n return;\n }\n const tool = this.drawingManager.getTool();\n this.orchestrator.setOverlayPointerEvents(tool === 'cursor' ? 'none' : 'auto');\n }\n\n getContainer(): HTMLElement {\n return this.container;\n }\n\n getSymbol(): string {\n return this.store.symbol;\n }\n\n getInterval(): Interval {\n return this.store.interval;\n }\n\n async searchSymbols(query: string): Promise<import('@coderyo/data').SymbolSearchHit[]> {\n const resolver = this.options.symbolResolver;\n if (resolver?.search) return resolver.search(query);\n if (this.options.dataProvider.searchSymbols) {\n return this.options.dataProvider.searchSymbols(query);\n }\n return [];\n }\n\n async resolveSymbol(symbol: string): Promise<import('@coderyo/data').SymbolInfo | null> {\n if (this.options.symbolResolver) {\n return this.options.symbolResolver.resolve(symbol);\n }\n return { symbol };\n }\n\n on(event: ChartEvent, handler: EventHandler): this {\n if (!this.handlers.has(event)) this.handlers.set(event, new Set());\n this.handlers.get(event)!.add(handler);\n return this;\n }\n\n off(event: ChartEvent, handler: EventHandler): this {\n this.handlers.get(event)?.delete(handler);\n return this;\n }\n\n resize(size?: { width?: number; height?: number }): this {\n if (size?.width) this.container.style.width = `${size.width}px`;\n if (size?.height) this.container.style.height = `${size.height}px`;\n this.orchestrator.resize();\n return this;\n }\n\n setDrawingTool(tool: import('@coderyo/drawings').DrawingTool): this {\n this.drawingManager?.setTool(tool);\n this.syncOverlayPointerEvents();\n return this;\n }\n\n deleteSelectedDrawing(): boolean {\n return this.drawingManager?.deleteSelected() ?? false;\n }\n\n copySelectedDrawing(): DrawingRecord | null {\n return this.drawingManager?.copySelected() ?? null;\n }\n\n toggleLockSelectedDrawing(): boolean {\n return this.drawingManager?.toggleLockSelected() ?? false;\n }\n\n updateSelectedDrawingStyle(patch: DrawingStyleMeta): void {\n this.drawingManager?.updateSelectedStyle(patch);\n }\n\n deselectDrawing(): void {\n this.drawingManager?.deselect();\n }\n\n setIndicatorConfig(config: IndicatorConfig | null): void {\n this.features = mergeChartFeatures(this.features, { indicators: config });\n this.orchestrator.setIndicatorConfig(config);\n this.emit('featuresChange', this.getFeatures());\n }\n\n setReturnToCursorAfterDraw(v: boolean): void {\n this.drawingManager?.setReturnToCursorAfterDraw(v);\n }\n\n async setSymbol(symbol: string): Promise<void> {\n const trimmed = symbol.trim();\n if (!trimmed) return;\n const gen = this.beginDataContextChange();\n await this.teardownSubscription();\n await this.store.setSymbolInterval(trimmed, this.store.interval);\n this.drawingManager?.setContext(symbol, this.store.interval);\n const info = await this.resolveSymbol(symbol);\n await this.bootstrap(gen);\n this.emit('symbolChange', info ?? { symbol });\n }\n\n async setInterval(interval: Interval): Promise<void> {\n const gen = this.beginDataContextChange();\n await this.teardownSubscription();\n await this.store.setSymbolInterval(this.store.symbol, interval);\n this.drawingManager?.setContext(this.store.symbol, interval);\n if (this.hasActiveSymbol()) {\n await this.bootstrap(gen);\n }\n }\n\n setTheme(theme: 'dark' | 'light'): this {\n this.orchestrator.setTheme(theme);\n return this;\n }\n\n setShowGrid(show: boolean): this {\n this.orchestrator.setShowGrid(show);\n return this;\n }\n\n fitContent(): this {\n this.orchestrator.fitContent();\n return this;\n }\n\n scrollToRealtime(): this {\n this.orchestrator.scrollToRealtime();\n return this;\n }\n\n getVisibleRange(): ChartVisibleRange | null {\n return this.orchestrator.getVisibleRange();\n }\n\n getBarSpace(): number {\n return this.orchestrator.getBarSpace();\n }\n\n setBarSpace(px: number): this {\n this.orchestrator.setBarSpace(px);\n return this;\n }\n\n setVisibleRange(range: ChartVisibleRange): this {\n this.orchestrator.setVisibleRange(range);\n const { fromMs, toMs } = range;\n if (toMs > fromMs) {\n this.virtualWindow.setVisibleRange({ fromMs, toMs });\n this.visibleRangeInitialized = true;\n }\n return this;\n }\n\n scrollToTimestamp(tsMs: number, animationMs?: number): this {\n this.orchestrator.scrollToTimestamp(tsMs, animationMs);\n return this;\n }\n\n async reloadHistory(): Promise<this> {\n if (!this.hasActiveSymbol()) return this;\n const savedRange = this.getVisibleRange();\n const savedBarSpace = this.getBarSpace();\n const loadGen = this.loadGeneration;\n const symbol = this.store.symbol;\n const interval = this.store.interval;\n\n try {\n const history = await fetchChartHistory(this.options.dataProvider, {\n mode: 'loadMore',\n symbol,\n interval,\n endTime: Date.now(),\n limit: 500,\n });\n if (!this.isLoadGenerationCurrent(loadGen)) return this;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return this;\n if (history.bars.length === 0) return this;\n\n await this.store.mergeBars(history.bars.map((bar) => ({ bar, source: 'rest' as const })));\n if (!this.isLoadGenerationCurrent(loadGen)) return this;\n\n this.orchestrator.preserveViewportOnNextSetBars();\n this.refreshRender(loadGen);\n if (savedBarSpace > 0) this.setBarSpace(savedBarSpace);\n if (savedRange) this.setVisibleRange(savedRange);\n } catch (err) {\n this.emit('error', err);\n }\n return this;\n }\n\n setLogScale(enabled: boolean): this {\n this.orchestrator.setLogScale(enabled);\n return this;\n }\n\n setFullscreen(_enabled: boolean): this {\n if (_enabled && this.container.requestFullscreen) {\n void this.container.requestFullscreen();\n } else if (document.fullscreenElement) {\n void document.exitFullscreen();\n }\n return this;\n }\n\n async exportImage(opts?: { pixelRatio?: number }): Promise<Blob> {\n const canvas = this.container.querySelector('canvas');\n if (!canvas) throw new Error('No canvas to export');\n const scale = opts?.pixelRatio ?? 2;\n const exportCanvas = document.createElement('canvas');\n exportCanvas.width = canvas.width * scale;\n exportCanvas.height = canvas.height * scale;\n const ctx = exportCanvas.getContext('2d')!;\n ctx.scale(scale, scale);\n ctx.drawImage(canvas, 0, 0);\n return new Promise((resolve, reject) => {\n exportCanvas.toBlob((b) => (b ? resolve(b) : reject(new Error('export failed'))), 'image/png');\n });\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.offPageResume?.();\n this.offPageResume = null;\n this.offCrosshair?.();\n this.offCrosshair = null;\n this.resizeObserver.disconnect();\n this.drawingManager?.destroy();\n void this.teardownSubscription();\n this.orchestrator.destroy();\n terminatePineWorker();\n this.emit('destroyed', { chartId: this.options.chartId ?? 'default' });\n this.emit('connectionChange', 'disconnected');\n }\n\n private beginDataContextChange(): number {\n this.loadGeneration += 1;\n this.visibleRangeInitialized = false;\n this.virtualWindow.setVisibleRange({ fromMs: 0, toMs: 0 });\n this.orchestrator.resetViewState();\n this.orchestrator.clearBars();\n return this.loadGeneration;\n }\n\n private isLoadGenerationCurrent(gen: number): boolean {\n return !this.destroyed && gen === this.loadGeneration;\n }\n\n private async bootstrap(loadGen: number): Promise<void> {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n const symbol = this.store.symbol;\n const interval = this.store.interval;\n const endTime = Date.now();\n if (this.features.protobuf) {\n this.emit('error', {\n code: 'PROTOBUF_UNAVAILABLE',\n message: 'Protobuf encoding requires protocol v1.1 (not in 1.0.0)',\n });\n }\n\n const history = await fetchChartHistory(this.options.dataProvider, {\n mode: 'loadMore',\n symbol,\n interval,\n endTime,\n limit: 500,\n });\n\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return;\n\n await this.store.mergeBars(history.bars.map((bar) => ({ bar })));\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n this.refreshRender(loadGen);\n void this.resolveSymbol(symbol).then((info) => {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n this.emit('symbolChange', info ?? { symbol });\n });\n this.emit('intervalChange', interval);\n\n const streamMode: RealtimeStreamMode = this.features.tickStream\n ? 'bar+tick'\n : this.features.streamMode;\n const tickOnly = streamMode === 'tick';\n\n const params: SubscribeParams = {\n symbol,\n interval,\n channels: tickOnly ? ['tick'] : this.features.tickStream ? ['bar', 'tick'] : ['bar'],\n streamMode,\n };\n\n this.tickAggregator = tickOnly\n ? new TickAggregator(interval, (bar, partial) => {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return;\n void this.applyRealtimeBar(bar, partial, loadGen);\n })\n : null;\n\n await this.options.dataProvider.connect?.();\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n const sub = await this.options.dataProvider.subscribe(params, {\n onBar: tickOnly\n ? undefined\n : (bar, meta) => {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return;\n void this.applyRealtimeBar(bar, meta.partial, loadGen);\n },\n onTick: (tick) => {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return;\n if (this.tickAggregator) {\n this.tickAggregator.ingest(tick);\n return;\n }\n const bar = this.buildBarFromPrice(tick.price, tick.t);\n void this.applyRealtimeBar(bar, true, loadGen);\n },\n onConnectionChange: (state) => {\n this.emit('connectionChange', state);\n // Only backfill on reconnect; initial connect loads history in bootstrap.\n if (state === 'connected' && this.subscriptionId != null) {\n void this.catchUpMissedBars();\n }\n },\n onError: (err) => this.emit('error', err),\n });\n if (!this.isLoadGenerationCurrent(loadGen)) {\n await this.options.dataProvider.unsubscribe(sub.id);\n return;\n }\n this.subscriptionId = sub.id;\n }\n\n private async teardownSubscription(): Promise<void> {\n this.tickAggregator?.flush();\n this.tickAggregator = null;\n if (this.subscriptionId) {\n await this.options.dataProvider.unsubscribe(this.subscriptionId);\n this.subscriptionId = null;\n }\n }\n\n private bindPageResumeCatchUp(): void {\n if (typeof document === 'undefined') return;\n\n const onResume = () => {\n if (document.visibilityState !== 'visible') return;\n void this.catchUpMissedBars();\n };\n\n document.addEventListener('visibilitychange', onResume);\n const cleanups: Array<() => void> = [\n () => document.removeEventListener('visibilitychange', onResume),\n ];\n\n if (typeof window !== 'undefined') {\n const onFocus = () => void this.catchUpMissedBars();\n window.addEventListener('focus', onFocus);\n cleanups.push(() => window.removeEventListener('focus', onFocus));\n }\n\n this.offPageResume = () => {\n for (const fn of cleanups) fn();\n };\n }\n\n /**\n * Backfill bars missed while the tab/window was backgrounded or WS delivery paused.\n */\n private async catchUpMissedBars(): Promise<void> {\n if (this.destroyed || !this.hasActiveSymbol()) return;\n\n const now = Date.now();\n if (now - this.lastCatchUpAt < 400) return;\n if (this.catchUpInFlight) return;\n\n const times = this.store.sortedTimes;\n if (times.length === 0) return;\n\n const lastT = times[times.length - 1]!;\n const interval = this.store.interval;\n const to = now + intervalMs(interval);\n if (to <= lastT) return;\n\n this.catchUpInFlight = true;\n this.lastCatchUpAt = now;\n const loadGen = this.loadGeneration;\n const symbol = this.store.symbol;\n\n try {\n const history = await fetchChartHistory(this.options.dataProvider, {\n mode: 'range',\n symbol,\n interval,\n from: lastT,\n to,\n });\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (this.store.symbol !== symbol || this.store.interval !== interval) return;\n if (history.bars.length === 0) return;\n\n await this.store.mergeBars(\n history.bars.map((bar) => ({ bar, source: 'rest' as const })),\n );\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n this.orchestrator.preserveViewportOnNextSetBars();\n this.refreshRender(loadGen);\n } catch (err) {\n this.emit('error', err);\n } finally {\n this.catchUpInFlight = false;\n }\n }\n\n private async maybeLoadMore(): Promise<void> {\n if (this.destroyed || this.loadingMore) return;\n const loadGen = this.loadGeneration;\n const reqs = this.virtualWindow.planFetches();\n if (reqs.length === 0) return;\n\n this.loadingMore = true;\n try {\n for (const req of reqs) {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n const history = await fetchChartHistory(\n this.options.dataProvider,\n toHistoryQuery(req),\n );\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n if (history.bars.length === 0) continue;\n await this.store.mergeBars(\n history.bars.map((bar) => ({ bar, source: 'rest' as const })),\n req.mode === 'loadMore',\n );\n }\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n this.refreshRender(loadGen);\n } catch (err) {\n this.emit('error', err);\n } finally {\n this.loadingMore = false;\n }\n }\n\n private refreshRender(loadGen = this.loadGeneration): void {\n if (!this.isLoadGenerationCurrent(loadGen)) return;\n\n const times = this.store.sortedTimes;\n if (times.length === 0) return;\n\n // Only seed visible range once; resetting to full series each tick triggers spurious loadMore.\n if (!this.visibleRangeInitialized) {\n this.virtualWindow.setVisibleRange({\n fromMs: times[0]!,\n toMs: times[times.length - 1]!,\n });\n this.visibleRangeInitialized = true;\n }\n\n const bars = this.virtualWindow.getBarsForRender();\n if (bars.length === 0) return;\n\n const gaps = this.features.gaps.whitespace\n ? computeGapStartTimes(\n bars.map((b) => b.t),\n this.store.interval,\n )\n : undefined;\n this.orchestrator.setBars(bars, gaps);\n this.applyPinePlots(bars);\n this.drawingManager?.redraw();\n this.emit('visibleRangeChange', {\n from: bars[0]!.t,\n to: bars[bars.length - 1]!.t,\n });\n }\n\n private emit(event: ChartEvent, payload?: unknown): void {\n for (const h of this.handlers.get(event) ?? []) h(payload);\n }\n}\n\nfunction toHistoryQuery(req: HistoryRequest): HistoryQuery {\n if (req.mode === 'loadMore') {\n return {\n mode: 'loadMore',\n symbol: req.symbol,\n interval: req.interval,\n endTime: req.endTime ?? Date.now(),\n limit: req.limit,\n };\n }\n return {\n mode: 'range',\n symbol: req.symbol,\n interval: req.interval,\n from: req.fromMs ?? 0,\n to: req.toMs ?? Date.now(),\n };\n}","import type { Bar, DataProvider, HistoryQuery } from '@coderyo/data';\nimport { intervalMs } from '@coderyo/data';\n\n/** REST with optional WS `requestWsHistory` fallback when capabilities allow. */\nexport async function fetchChartHistory(\n provider: DataProvider,\n query: HistoryQuery,\n): Promise<{ bars: Bar[]; nextCursor?: string; hasMore?: boolean }> {\n const caps = await provider.getCapabilities?.();\n if (caps?.wsHistory && provider.requestWsHistory) {\n try {\n if (query.mode === 'range') {\n const bars = await provider.requestWsHistory({\n symbol: query.symbol,\n interval: query.interval,\n from: query.from,\n to: query.to,\n });\n return { bars, hasMore: false };\n }\n if (query.mode === 'loadMore') {\n const ms = intervalMs(query.interval);\n const from = query.endTime - ms * query.limit;\n const bars = await provider.requestWsHistory({\n symbol: query.symbol,\n interval: query.interval,\n from,\n to: query.endTime,\n });\n return { bars, hasMore: false };\n }\n } catch {\n /* fall through to REST */\n }\n }\n return provider.getHistory(query);\n}","import type { RealtimeStreamMode } from '@coderyo/data';\nimport type { IndicatorConfig } from '@coderyo/indicators';\nimport type { FetchPolicy } from '@coderyo/virtual-window';\n\nexport interface ChartGapsFeatures {\n whitespace?: boolean;\n fillVisibleHoles?: boolean;\n}\n\nexport interface ChartDrawingsFeatures {\n /** Show interactive drawing overlay (default false). API remains available when false. */\n layer?: boolean;\n /** Persist drawings to localStorage (default true when layer/API used). */\n persist?: boolean;\n}\n\nexport interface ChartFeatures {\n fetchPolicy?: FetchPolicy;\n streamMode?: RealtimeStreamMode;\n gaps?: ChartGapsFeatures;\n drawings?: ChartDrawingsFeatures;\n /** Pass config to enable MA + indicator panes; omit/null = no indicators. */\n indicators?: IndicatorConfig | null;\n /** Save indicator params to storage (default false). */\n indicatorPersist?: boolean;\n /** Ease last candle OHLC + price line to new values (~150ms). */\n smoothPriceUpdate?: boolean;\n smoothPriceDurationMs?: number;\n /** Pine-lite script source (requires pineEnabled). */\n pineScript?: string | null;\n /** Post-1.0 hooks — default false. */\n pineEnabled?: boolean;\n protobuf?: boolean;\n telemetry?: boolean;\n tickStream?: boolean;\n /** Run Pine-lite VM in a Web Worker when available (default true). */\n pineWorker?: boolean;\n}\n\nexport interface ResolvedChartFeatures {\n fetchPolicy: FetchPolicy;\n streamMode: RealtimeStreamMode;\n gaps: Required<ChartGapsFeatures>;\n drawings: Required<ChartDrawingsFeatures>;\n indicators: IndicatorConfig | null;\n indicatorPersist: boolean;\n smoothPriceUpdate: boolean;\n smoothPriceDurationMs: number;\n pineScript: string | null;\n pineEnabled: boolean;\n protobuf: boolean;\n telemetry: boolean;\n tickStream: boolean;\n pineWorker: boolean;\n}\n\nexport const DEFAULT_CHART_FEATURES: ResolvedChartFeatures = {\n fetchPolicy: 'lazy-left-only',\n streamMode: 'bar',\n gaps: { whitespace: false, fillVisibleHoles: false },\n drawings: { layer: false, persist: true },\n indicators: null,\n indicatorPersist: false,\n smoothPriceUpdate: false,\n smoothPriceDurationMs: 150,\n pineScript: null,\n pineEnabled: false,\n protobuf: false,\n telemetry: false,\n tickStream: false,\n pineWorker: true,\n};\n\nexport function resolveChartFeatures(partial?: ChartFeatures): ResolvedChartFeatures {\n const d = DEFAULT_CHART_FEATURES;\n return {\n fetchPolicy: partial?.fetchPolicy ?? d.fetchPolicy,\n streamMode: partial?.streamMode ?? d.streamMode,\n gaps: {\n whitespace: partial?.gaps?.whitespace ?? d.gaps.whitespace,\n fillVisibleHoles: partial?.gaps?.fillVisibleHoles ?? d.gaps.fillVisibleHoles,\n },\n drawings: {\n layer: partial?.drawings?.layer ?? d.drawings.layer,\n persist: partial?.drawings?.persist ?? d.drawings.persist,\n },\n indicators: partial?.indicators !== undefined ? partial.indicators : d.indicators,\n indicatorPersist: partial?.indicatorPersist ?? d.indicatorPersist,\n smoothPriceUpdate: partial?.smoothPriceUpdate ?? d.smoothPriceUpdate,\n smoothPriceDurationMs: partial?.smoothPriceDurationMs ?? d.smoothPriceDurationMs,\n pineScript: partial?.pineScript !== undefined ? partial.pineScript : d.pineScript,\n pineEnabled: partial?.pineEnabled ?? d.pineEnabled,\n protobuf: partial?.protobuf ?? d.protobuf,\n telemetry: partial?.telemetry ?? d.telemetry,\n tickStream: partial?.tickStream ?? d.tickStream,\n pineWorker: partial?.pineWorker ?? d.pineWorker,\n };\n}\n\nexport function mergeChartFeatures(\n current: ResolvedChartFeatures,\n patch: ChartFeatures,\n): ResolvedChartFeatures {\n return resolveChartFeatures({\n fetchPolicy: patch.fetchPolicy ?? current.fetchPolicy,\n streamMode: patch.streamMode ?? current.streamMode,\n gaps: { ...current.gaps, ...patch.gaps },\n drawings: { ...current.drawings, ...patch.drawings },\n indicators: patch.indicators !== undefined ? patch.indicators : current.indicators,\n indicatorPersist: patch.indicatorPersist ?? current.indicatorPersist,\n smoothPriceUpdate: patch.smoothPriceUpdate ?? current.smoothPriceUpdate,\n smoothPriceDurationMs: patch.smoothPriceDurationMs ?? current.smoothPriceDurationMs,\n pineScript: patch.pineScript !== undefined ? patch.pineScript : current.pineScript,\n pineEnabled: patch.pineEnabled ?? current.pineEnabled,\n protobuf: patch.protobuf ?? current.protobuf,\n telemetry: patch.telemetry ?? current.telemetry,\n tickStream: patch.tickStream ?? current.tickStream,\n pineWorker: patch.pineWorker ?? current.pineWorker,\n });\n}\n\n/** Empty chart until integrator calls setSymbol. */\nexport const PENDING_SYMBOL = '';","import type { IndicatorConfig } from '@coderyo/indicators';\nimport { DEFAULT_INDICATOR_CONFIG } from '@coderyo/indicators';\nimport { PINE_SAMPLE_SCRIPT } from '@coderyo/pine-lite';\nimport type { Interval } from '@coderyo/data';\nimport type { ChartFeatures } from './chart-features.js';\nimport type { ChartOptions } from './chart-controller.js';\n\n/** Playground / docs: opt-in full TV-like chart features. */\nexport function createDemoChartFeatures(opts: {\n indicatorConfig?: IndicatorConfig;\n returnToCursorAfterDraw?: boolean;\n}): ChartFeatures {\n return {\n fetchPolicy: 'lazy-left-only',\n streamMode: 'bar+tick',\n gaps: { whitespace: false, fillVisibleHoles: false },\n drawings: { layer: true, persist: true },\n indicators: opts.indicatorConfig ?? DEFAULT_INDICATOR_CONFIG,\n indicatorPersist: true,\n smoothPriceUpdate: true,\n smoothPriceDurationMs: 150,\n tickStream: true,\n pineEnabled: true,\n pineScript: PINE_SAMPLE_SCRIPT,\n };\n}\n\nexport function createDemoChartOptions(\n base: Pick<ChartOptions, 'dataProvider' | 'indicatorHost' | 'symbolResolver' | 'chartId'> & {\n symbol: string;\n interval: Interval;\n theme?: 'dark' | 'light';\n showGrid?: boolean;\n indicatorConfig?: IndicatorConfig;\n returnToCursorAfterDraw?: boolean;\n },\n): ChartOptions {\n const indicatorConfig = base.indicatorConfig ?? DEFAULT_INDICATOR_CONFIG;\n return {\n ...base,\n features: createDemoChartFeatures({\n indicatorConfig,\n returnToCursorAfterDraw: base.returnToCursorAfterDraw,\n }),\n indicatorConfig,\n drawingDefaults: { returnToCursorAfterDraw: base.returnToCursorAfterDraw ?? false },\n };\n}","import type { BridgeAdapter } from '@coderyo/bridge';\nimport type { BridgeOutboundType } from '@coderyo/bridge';\nimport type { DrawingRecord, DrawingStyleMeta } from '@coderyo/drawings';\nimport type { IndicatorConfig } from '@coderyo/indicators';\nimport type { DataProvider } from '@coderyo/data';\nimport { wireChartBridge, TRADVIEW_API_VERSION } from './bridge-wire.js';\nimport { ChartController, type ChartOptions } from './chart-controller.js';\nimport type { ChartFeatures, ResolvedChartFeatures } from './chart-features.js';\nimport { TRADVIEW_VERSION } from './version.js';\nimport type { ChartVisibleRange } from '@coderyo/renderer-lite';\n\nexport { TRADVIEW_API_VERSION, TRADVIEW_VERSION };\nexport type { ChartVisibleRange };\nexport type { ChartFeatures, ResolvedChartFeatures } from './chart-features.js';\nexport { resolveChartFeatures, DEFAULT_CHART_FEATURES, PENDING_SYMBOL } from './chart-features.js';\nexport { createDemoChartFeatures, createDemoChartOptions } from './demo-presets.js';\n\nexport interface CreateChartOptions extends Omit<ChartOptions, 'dataProvider'> {\n dataProvider: DataProvider;\n bridge?: BridgeAdapter;\n chartId?: string;\n /** If set, only these bridge outbound events are posted. */\n bridgeOutboundEvents?: BridgeOutboundType[];\n bridgeCrosshairThrottleMs?: number;\n}\n\nexport interface IChart {\n setSymbol(symbol: string): IChart;\n setInterval(interval: import('@coderyo/data').Interval): IChart;\n setTheme(theme: 'dark' | 'light'): IChart;\n setShowGrid(show: boolean): IChart;\n setLogScale(enabled: boolean): IChart;\n fitContent(): IChart;\n scrollToRealtime(): IChart;\n /** Visible time range in ms (`fromMs` / `toMs`), or `null` if unknown. */\n getVisibleRange(): ChartVisibleRange | null;\n /** Bar spacing in px (zoom). Alias for LWC `barSpacing`. */\n getBarSpace(): number;\n setBarSpace(px: number): IChart;\n /** Restore viewport time range after re-bootstrap. */\n setVisibleRange(range: ChartVisibleRange): IChart;\n /** Scroll so `tsMs` aligns to the right edge of the viewport. */\n scrollToTimestamp(tsMs: number, animationMs?: number): IChart;\n /** Re-fetch recent history without clearing scroll/zoom. */\n reloadHistory(): Promise<IChart>;\n resize(size?: { width?: number; height?: number }): IChart;\n setFullscreen(enabled: boolean): IChart;\n exportImage(opts?: { pixelRatio?: number }): Promise<Blob>;\n on(event: import('./chart-controller.js').ChartEvent, handler: (p?: unknown) => void): IChart;\n off(event: import('./chart-controller.js').ChartEvent, handler: (p?: unknown) => void): IChart;\n searchSymbols(query: string): Promise<import('@coderyo/data').SymbolSearchHit[]>;\n setDrawingTool(tool: import('@coderyo/drawings').DrawingTool): IChart;\n deleteSelectedDrawing(): boolean;\n copySelectedDrawing(): DrawingRecord | null;\n toggleLockSelectedDrawing(): boolean;\n updateSelectedDrawingStyle(patch: DrawingStyleMeta): void;\n deselectDrawing(): void;\n setIndicatorConfig(config: IndicatorConfig | null): void;\n setReturnToCursorAfterDraw(v: boolean): void;\n setFeatures(patch: ChartFeatures): IChart;\n getFeatures(): ResolvedChartFeatures;\n /** Integrator push: smooth-update last candle toward `price` (no WS required). */\n updateLastPrice(price: number, timeMs?: number): IChart;\n hasActiveSymbol(): boolean;\n setLocale(locale: string): IChart;\n /** Subscribe to realtime bar updates; returns unsubscribe. */\n subscribeBars(handler: (bar: import('@coderyo/data').Bar) => void): () => void;\n destroy(): void;\n}\n\nfunction wrap(controller: ChartController, beforeDestroy?: () => void): IChart {\n return {\n setSymbol: (s) => {\n void controller.setSymbol(s);\n return wrap(controller, beforeDestroy);\n },\n setInterval: (i) => {\n void controller.setInterval(i);\n return wrap(controller, beforeDestroy);\n },\n setTheme: (t) => {\n controller.setTheme(t);\n return wrap(controller, beforeDestroy);\n },\n setShowGrid: (show) => {\n controller.setShowGrid(show);\n return wrap(controller, beforeDestroy);\n },\n setLogScale: (enabled) => {\n controller.setLogScale(enabled);\n return wrap(controller, beforeDestroy);\n },\n fitContent: () => {\n controller.fitContent();\n return wrap(controller, beforeDestroy);\n },\n scrollToRealtime: () => {\n controller.scrollToRealtime();\n return wrap(controller, beforeDestroy);\n },\n getVisibleRange: () => controller.getVisibleRange(),\n getBarSpace: () => controller.getBarSpace(),\n setBarSpace: (px) => {\n controller.setBarSpace(px);\n return wrap(controller, beforeDestroy);\n },\n setVisibleRange: (range) => {\n controller.setVisibleRange(range);\n return wrap(controller, beforeDestroy);\n },\n scrollToTimestamp: (tsMs, animationMs) => {\n controller.scrollToTimestamp(tsMs, animationMs);\n return wrap(controller, beforeDestroy);\n },\n reloadHistory: async () => {\n await controller.reloadHistory();\n return wrap(controller, beforeDestroy);\n },\n resize: (s) => {\n controller.resize(s);\n return wrap(controller, beforeDestroy);\n },\n setFullscreen: (e) => {\n controller.setFullscreen(e);\n return wrap(controller, beforeDestroy);\n },\n exportImage: (o) => controller.exportImage(o),\n on: (e, h) => {\n controller.on(e, h);\n return wrap(controller, beforeDestroy);\n },\n off: (e, h) => {\n controller.off(e, h);\n return wrap(controller, beforeDestroy);\n },\n searchSymbols: (q) => controller.searchSymbols(q),\n setDrawingTool: (tool) => {\n controller.setDrawingTool(tool);\n return wrap(controller, beforeDestroy);\n },\n deleteSelectedDrawing: () => controller.deleteSelectedDrawing(),\n copySelectedDrawing: () => controller.copySelectedDrawing(),\n toggleLockSelectedDrawing: () => controller.toggleLockSelectedDrawing(),\n updateSelectedDrawingStyle: (p) => {\n controller.updateSelectedDrawingStyle(p);\n return wrap(controller, beforeDestroy);\n },\n deselectDrawing: () => {\n controller.deselectDrawing();\n return wrap(controller, beforeDestroy);\n },\n setIndicatorConfig: (c) => {\n controller.setIndicatorConfig(c);\n return wrap(controller, beforeDestroy);\n },\n setReturnToCursorAfterDraw: (v) => {\n controller.setReturnToCursorAfterDraw(v);\n return wrap(controller, beforeDestroy);\n },\n setFeatures: (patch) => {\n controller.setFeatures(patch);\n return wrap(controller, beforeDestroy);\n },\n getFeatures: () => controller.getFeatures(),\n updateLastPrice: (price, timeMs) => {\n controller.updateLastPrice(price, timeMs);\n return wrap(controller, beforeDestroy);\n },\n hasActiveSymbol: () => controller.hasActiveSymbol(),\n setLocale: (locale) => {\n controller.setLocale(locale);\n return wrap(controller, beforeDestroy);\n },\n subscribeBars: (handler) => controller.subscribeBars(handler),\n destroy: () => {\n controller.destroy();\n beforeDestroy?.();\n },\n };\n}\n\nexport function createChart(\n target: HTMLElement | string,\n options: CreateChartOptions,\n): IChart {\n const el =\n typeof target === 'string'\n ? (document.querySelector(target) as HTMLElement | null)\n : target;\n if (!el) throw new Error('Chart container not found');\n const controller = new ChartController(el, options);\n let bridgeTeardown: (() => void) | undefined;\n const chart = wrap(controller, () => bridgeTeardown?.());\n if (options.bridge) {\n bridgeTeardown = wireChartBridge({\n controller,\n chart,\n bridge: options.bridge,\n chartId: options.chartId,\n outboundEvents: options.bridgeOutboundEvents,\n crosshairThrottleMs: options.bridgeCrosshairThrottleMs,\n });\n }\n return chart;\n}","export {\n createChart,\n type IChart,\n type CreateChartOptions,\n TRADVIEW_API_VERSION,\n TRADVIEW_VERSION,\n type ChartFeatures,\n type ResolvedChartFeatures,\n resolveChartFeatures,\n DEFAULT_CHART_FEATURES,\n PENDING_SYMBOL,\n createDemoChartFeatures,\n createDemoChartOptions,\n} from './create-chart.js';\nexport {\n ChartController,\n type ChartOptions,\n type ChartEvent,\n type ChartVisibleRange,\n} from './chart-controller.js';\nexport { wireChartBridge, type WireChartBridgeOptions } from './bridge-wire.js';\nexport {\n compilePineLite,\n runPineLite,\n PINE_SAMPLE_SCRIPT,\n PINE_EDITOR_DEFAULT,\n type PineCompileResult,\n type PineIrProgram,\n type PinePlotSeries,\n} from '@coderyo/pine-lite';"],"mappings":"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","names":["intervalMs","intervalMs","compilePineLite","PINE_SAMPLE_SCRIPT"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coderyo/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -10,14 +10,15 @@
|
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@coderyo/data": "1.0.
|
|
14
|
-
"@coderyo/
|
|
15
|
-
"@coderyo/
|
|
16
|
-
"@coderyo/virtual-window": "1.0.
|
|
17
|
-
"@coderyo/indicators": "1.0.
|
|
18
|
-
"@coderyo/renderer-lite": "1.0.
|
|
19
|
-
"@coderyo/
|
|
20
|
-
"@coderyo/
|
|
13
|
+
"@coderyo/data": "1.0.1",
|
|
14
|
+
"@coderyo/bridge": "1.0.1",
|
|
15
|
+
"@coderyo/series": "1.0.1",
|
|
16
|
+
"@coderyo/virtual-window": "1.0.1",
|
|
17
|
+
"@coderyo/indicators": "1.0.1",
|
|
18
|
+
"@coderyo/renderer-lite": "1.0.1",
|
|
19
|
+
"@coderyo/pine-lite": "1.0.1",
|
|
20
|
+
"@coderyo/i18n": "1.0.1",
|
|
21
|
+
"@coderyo/drawings": "1.0.1"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
24
|
"tsup": "^8.5.0",
|