Local data and capture
Read chart data and capture images locally for an assistant to use.
Open a session after widget readiness. Reads and capture need only the read effect:
// Run inside the widget's ready callback.
const chart = widget.activeChart();
const sdk = await chart.openAutomation({ commands: [], policy: { effects: ['read'] } });
const series = sdk.data.series();
const range = chart.getVisibleRange();
if (range && series.find(item => item.id === 'main')?.readiness === 'ready') {
const result = await sdk.data.read({
seriesId: 'main',
from: Math.round(range.from * 1000),
to: Math.round(range.to * 1000),
limit: 2000,
});
console.log(result.rows, result.coverage);
}
const image = await sdk.capture.image();
console.log(image.blob, image.width, image.height);
// On component teardown (chart removal also closes the session):
sdk.close();commands: [] installs no native command families. Each call above uses a fresh request for the current chart; pass sdk.request() captured earlier to reject results from a chart that has since changed.
To avoid downloading the automation runtime for read-only use, bundle the SDK and create the session yourself. Keep the chart and screenshot index paired:
import { createNativeChartAutomation } from '@lumencharts/chart-automation/sdk';
const sdk = createNativeChartAutomation({
chartId: 'primary',
chart: widget.workspaceChart(0),
capturePng: () => widget.takeClientScreenshot({ chartIndex: 0, strictCapture: true }),
policy: { effects: ['read'] },
});capturePng may return either a PNG data URL or a PNG Blob. A Blob is validated from its header only, so it avoids base64 decoding for large charts.
Time, fields and coverage
SDK timestamps use integer UTC milliseconds. The native visible-range API uses seconds, hence the conversion above. Inside a command, read through context.execute('data.read', input) so the read shares the command's request, deadline and target fence. Main-series data is raw OHLCV, not transformed display candles. Open, high, low and close are required finite numbers; volume may be omitted.
Every discovered series declares its numeric fields, units and readiness. Fields are required and non-null by default. optional: true permits omission; nullable: true permits explicit null. Rows must contain an integer time and only declared fields. Timestamps must be unique, increasing and inside the requested range. Descriptors are snapshotted before asynchronous work so later provider changes cannot alter validation for a pending read.
The native adapter exposes main candles. Comparison, study and Pine output series require a host data adapter; they are not automatically extracted from arbitrary indicator buffers. Pending series reject local reads with busy; failed series reject with unavailable.
Reads never fetch missing history. An oversized matching window rejects instead of silently returning a partial slice. coverage.complete means the requested window is inside the reported loaded bounds; it does not promise a candle for every clock interval or exhaustive market history. requestHistory is a separate, optional host operation that requires the external effect.
Capture and image transport
Capture returns a PNG Blob with dimensions, target, capture time, visible range and revision. The revision is a session change counter, not a persisted document version. Capture rejects stale work if the chart selection, data or visible range changes while it is pending.
The current capture scope is the exact chart at native dimensions. Cropping, custom dimensions, layer filtering and image editing are not SDK options. Your application can process the returned image separately. Uploads, attachment identities, retention and provider-specific image formats belong to that application.
Events and cleanup
const unsubscribe = sdk.events.subscribe(event => {
console.log(event.type, event.target, event.revision);
});
// Release when the observer is no longer needed.
unsubscribe();Events include selection, data, study-ready and disposed. Data notifications are coalesced within a microtask; selection and disposal are immediate. A study-ready event first delivers any queued data notification, so events arrive in commit order. Payloads are immutable. The native session destroys itself when its chart is removed; explicit destroy() is also safe to call repeatedly.