@alphacharts/indicators 0.0.0-stage → 0.1.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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -2
  3. package/dist/all-_xzUPrL7.js +21 -0
  4. package/dist/all-_xzUPrL7.js.map +1 -0
  5. package/dist/all.js +10 -0
  6. package/dist/all.js.map +1 -0
  7. package/dist/define-XUgQMhSl.js +687 -0
  8. package/dist/define-XUgQMhSl.js.map +1 -0
  9. package/dist/index.js +744 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/registry-DdYYyZN_.js +53 -0
  12. package/dist/registry-DdYYyZN_.js.map +1 -0
  13. package/dist/runner-B53M0IsJ.js +237 -0
  14. package/dist/runner-B53M0IsJ.js.map +1 -0
  15. package/dist/studies.js +1 -0
  16. package/dist/tv-volume-BYSbfrVk.js +3454 -0
  17. package/dist/tv-volume-BYSbfrVk.js.map +1 -0
  18. package/dist/types/all.d.ts +3 -0
  19. package/dist/types/chart/marker-floor.d.ts +9 -0
  20. package/dist/types/chart/studies.d.ts +192 -0
  21. package/dist/types/define.d.ts +46 -0
  22. package/dist/types/engine/feed.d.ts +88 -0
  23. package/dist/types/engine/graph.d.ts +136 -0
  24. package/dist/types/engine/kernels.d.ts +9 -0
  25. package/dist/types/engine/study.d.ts +40 -0
  26. package/dist/types/index.d.ts +15 -0
  27. package/dist/types/registry.d.ts +7 -0
  28. package/dist/types/runner.d.ts +91 -0
  29. package/dist/types/studies/all.d.ts +2 -0
  30. package/dist/types/studies/cycle.d.ts +7 -0
  31. package/dist/types/studies/index.d.ts +13 -0
  32. package/dist/types/studies/ma.d.ts +26 -0
  33. package/dist/types/studies/math.d.ts +28 -0
  34. package/dist/types/studies/momentum.d.ts +30 -0
  35. package/dist/types/studies/overlap.d.ts +14 -0
  36. package/dist/types/studies/patterns.d.ts +62 -0
  37. package/dist/types/studies/price.d.ts +6 -0
  38. package/dist/types/studies/sar.d.ts +2 -0
  39. package/dist/types/studies/statistic.d.ts +9 -0
  40. package/dist/types/studies/tv-osc.d.ts +18 -0
  41. package/dist/types/studies/tv-trend.d.ts +20 -0
  42. package/dist/types/studies/tv-volume.d.ts +15 -0
  43. package/dist/types/studies/volatility.d.ts +3 -0
  44. package/dist/types/studies/volume.d.ts +3 -0
  45. package/dist/types/types.d.ts +169 -0
  46. package/dist/types/wasm.d.ts +2 -0
  47. package/dist/types/worker.d.ts +1 -0
  48. package/dist/worker.js +8 -0
  49. package/dist/worker.js.map +1 -0
  50. package/package.json +72 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["joinFeed","SOURCE_NAMES","Feed","Node","Graph","defineStudy","Col","setKernels","describeJoin","FEED_FIELDS","createRunner","resolveParams","WorkerRunner","runStudy","CancelledError","serveWorker","InlineRunner","StudyEngine","CHUNK","validateDef","registerStudy","listStudies","registerStudies","getStudy","marked","v","text","markerFloor","floor","o","n","seen","j","col","PLUGIN_ID","Study","host","id","source","volume","ownRunner","onDispose","def","inputs","saved","onlyLast","kept","k","reset","next","partial","plot","isOverlayLine","engine","plotOffset","visible","sh","style","parseColor","plotKey","out","c","name","series","line","f","key","bars","cfg","bar","runner","p","e","color","time","need","d","chart","sd","st","i","close","ohlc","open","high","low","vol","COL_O","COL_H","COL_L","COL_C","COL_V","nan","which","last","lastTime","feeds","run","res","err","b","lowerBound","at","l","withAlpha","so","overlay","cols","add","s","type","anchor","prim","BarShading","price","times","rgba","down","by","m","t","value","maxAbs","q","column","cond","own","view","lo","hi","step","X","Y","ctx","polyline","off","drawn","first","x","side","y","dir","shape","params","mid","a","css","cssColor","alpha","fillBetween","flush","width","pen","connect","zigzag","back","kind","StudiesPlugin","resolve","api","sources","src","live","target","base","used","bump","alive","state","ss","byId","installStudies","have","opts","addStudy","study","enableWasm","loadKernels","disableWasm"],"sources":["../src/chart/marker-floor.ts","../src/chart/studies.ts","../src/wasm.ts"],"sourcesContent":["// Which marks of a markers plot are kept when it asks for only the most recent\n// ones (`plotshape(cond, last=3)` keeps the last three marked bars,\n// `within=100` the marks on the final hundred). Decided from the finished\n// column each time marks are drawn, never stored, so a tick, an appended bar\n// and a batch over all the bars give the same marks: a mark that falls out of\n// the last N goes when a newer one arrives, and the live bar's mark comes and\n// goes with its condition, as the condition does.\n\n/** A mark is a present value (not NaN), and for a text mark a non-zero one. */\nconst marked = (v: number | undefined, text: boolean) => v !== undefined && v === v && !(text && v === 0);\n\n/**\n * The first bar index whose mark is kept, over bars `[0, n)` of `col`: marks at\n * or after it are drawn, those before are not. 0 when the plot asks for no limit.\n */\nexport function markerFloor(col: ArrayLike<number>, n: number, o: { last?: number; within?: number; text?: boolean }): number {\n let floor = o.within !== undefined ? Math.max(0, n - o.within) : 0;\n if (o.last !== undefined) {\n let seen = 0;\n for (let j = n - 1; j >= floor; j--) {\n if (!marked(col[j], !!o.text)) continue;\n if (++seen === o.last) return j;\n }\n }\n return floor;\n}\n","// Studies on a chart, through the core plugin API.\n//\n// `addStudy(chart, source, study, inputs)` creates one core series per drawn\n// plot (lines, histograms, areas, band edges) in the source's pane or a pane of\n// its own, and draws what the series types cannot (fills between plots,\n// markers, ZigZag, lines joined across gaps or shifted back in time) from the\n// plugin's `drawPane` on the overlay. The studies follow the source:\n// - a live bar appends or revises the engine's last bar and updates each\n// output series by one point (O(1) per tick),\n// - setData/prepend/reindex on the source recompute the whole study (on the\n// runner when one is given; ticks that arrive meanwhile are folded into a\n// second recompute),\n// - removing the source removes its studies.\n// Output series carry the ids `study:<instance>:<plot>` so a saved layout\n// (`chart.saveState()`) restores them; the plugin's own state (`toJSON`) holds\n// what each study is: study id, inputs, source/volume series ids, visibility\n// and style overrides, keyed by study instance id.\n//\n// Beyond lines and fills a study can colour the source's candles (`barcolor`\n// plots; several studies compose on one source), shade the background of its\n// pane (`bgcolor` plots, a core `BarShading` primitive: no part in autoscale),\n// colour a line per point (`colorBy`), draw on the chart's left axis\n// (`scale: \"left\"`), and read outside series its host gives it\n// (`setFeed` / `pushFeedBar`, see engine/feed.ts for the join).\n//\n// Limits: a study plot with a negative shift or `connect` is drawn on the\n// overlay, so it does not take part in autoscale or the crosshair readout. A\n// line's dash style is not drawn on series lines (the core line has none).\n\nimport {\n BarShading, COL_C, COL_H, COL_L, COL_O, COL_V, cssColor, parseColor,\n type Chart, type ChartPlugin, type DataChange, type PluginApi, type PluginPaneView, type PriceLine, type Series, type SeriesData, type SeriesType,\n} from \"@alphacharts/core\";\nimport { Feed, type FeedBar, type FeedBars, type FeedConfig } from \"../engine/feed.js\";\nimport { StudyEngine, resolveParams } from \"../engine/study.js\";\nimport { getStudy } from \"../registry.js\";\nimport { markerFloor } from \"./marker-floor.js\";\nimport { CancelledError, type StudyRunner } from \"../runner.js\";\nimport type { BarColumns, BarInput, InputValue, Params, PlotDef, StudyDef } from \"../types.js\";\n\nexport const PLUGIN_ID = \"alphacharts.studies\";\n\ntype AnySeries = Series<SeriesType>;\ntype SourceSeries = Series<\"candles\" | \"bars\" | \"line\" | \"area\" | \"histogram\">;\n\nexport interface AddStudyOptions {\n /** Volume series (histogram or line) for studies that need volume. */\n volume?: Series<\"histogram\" | \"line\" | \"area\">;\n /** Instance id; default `s<n>`. Layout state is keyed by it. */\n id?: string;\n /** Batch evaluation off the UI thread; ticks always run inline. */\n runner?: StudyRunner;\n /** Called once when the study is dropped or disposed (removed, source removed, layout restored over it). */\n onDispose?: () => void;\n /**\n * Whether `StudiesPlugin.toJSON` saves this study (default true). A study\n * that something else rebuilds on restore (a script, through\n * `restoreScript`) sets it false: the plugin could not recreate it, and a\n * layout holding it would be refused.\n */\n persist?: boolean;\n}\n\nexport interface PlotStyle {\n color?: string;\n width?: number;\n}\n\n/** A series the study draws, with what is needed to keep it current. */\ninterface OutSeries {\n plot: PlotDef;\n key: string;\n col: number;\n series: Series<\"line\" | \"histogram\" | \"area\">;\n offset: number;\n /** Time of the last point written, to know when an update must become a rewrite. */\n lastTime: number;\n}\n\nexport class Study {\n readonly def: StudyDef;\n private params: Params;\n private engine: StudyEngine;\n private outs: OutSeries[] = [];\n private lines: { series: AnySeries; line: PriceLine }[] = [];\n /** Background shading: one primitive per bgcolor plot, attached to the series of the pane it shades. */\n private shades: { plot: Extract<PlotDef, { kind: \"bgcolor\" }>; col: number; prim: BarShading; anchor: AnySeries }[] = [];\n /** Outside series the host gave this study, by key. */\n private feeds = new Map<string, Feed>();\n private sameScale = true;\n private styles: Record<string, PlotStyle> = {};\n private shown = true;\n private pane = 0;\n private scaleId = \"right\";\n private version = 0;\n private job: { cancel(): void } | null = null;\n /** A tick arrived while a job was pending (caught up on adoption). */\n private dirty = false;\n /** A replace/prepend arrived while a job was pending: the job's data is stale. */\n private structural = false;\n /** Set when a computation failed: the study stops following the source and says why. */\n error: Error | null = null;\n private ready_: Promise<void> = Promise.resolve();\n disposed = false;\n /** Decimals a separate-pane study's axis and labels show when its def does not set `minMove`: two, more when the values are small. */\n private decimals = 2;\n /** Whether the plugin saves this study (see `AddStudyOptions.persist`). */\n persist = true;\n\n /** @internal */\n constructor(\n private readonly host: StudiesPlugin,\n readonly id: string,\n def: StudyDef,\n inputs: Readonly<Record<string, InputValue>>,\n private readonly source: SourceSeries,\n private readonly volume: Series<\"histogram\" | \"line\" | \"area\"> | undefined,\n saved?: { visible?: boolean; styles?: Record<string, PlotStyle> },\n private readonly ownRunner?: StudyRunner,\n private readonly onDispose?: () => void,\n ) {\n this.def = def;\n this.params = resolveParams(def, inputs);\n this.engine = new StudyEngine(def, this.params);\n this.checkSource();\n if (saved?.styles) this.styles = { ...saved.styles };\n if (saved?.visible === false) this.shown = false;\n this.createSeries();\n this.recompute();\n }\n\n inputs(): Params {\n return this.params;\n }\n\n get visible(): boolean {\n return this.shown;\n }\n\n /** Resolves when the last requested computation has been applied to the chart. */\n ready(): Promise<void> {\n return this.ready_;\n }\n\n /**\n * Redraw from the engine's columns after they were written from outside (a\n * computation that arrives late, e.g. a script worker): the last bar when\n * `onlyLast`, else every bar.\n */\n refresh(onlyLast = true): void {\n if (this.disposed || this.error || this.engine.length === 0) return;\n if (onlyLast) this.tickSync();\n else this.syncAll();\n this.host.api?.requestRender(true);\n }\n\n /** Output series, in plot order. */\n series(): readonly AnySeries[] {\n return this.outs.map((o) => o.series as unknown as AnySeries);\n }\n\n /**\n * Change inputs; unspecified ones keep their value, and the keys in `reset` go back to their defaults (a preset that\n * has no value for an input the study has). Validated before anything changes. Outside series the study was given stay.\n */\n setInputs(partial: Readonly<Record<string, InputValue>>, reset: readonly string[] = []): void {\n const kept: Record<string, InputValue> = { ...this.params };\n for (const k of reset) delete kept[k];\n const next = resolveParams(this.def, { ...kept, ...partial });\n // A line whose shift is worked out from an input is in the pane or on the overlay by its sign; the series exists on one of them.\n for (const plot of this.def.plots) {\n if (plot.kind === \"line\" && typeof plot.offset === \"function\" && isOverlayLine(plot, this.params) !== isOverlayLine(plot, next))\n throw new TypeError(`${plot.title}: this input would move its line between the pane and the overlay; add the study again`);\n }\n const engine = new StudyEngine(this.def, next);\n this.params = next;\n for (const o of this.outs) if (o.plot.kind === \"line\") o.offset = plotOffset(o.plot, next);\n this.engine = engine;\n this.retitle();\n this.recompute();\n this.host.changed();\n }\n\n setVisible(visible: boolean): void {\n this.shown = visible;\n for (const o of this.outs) o.series.applyOptions({ visible } as never);\n for (const sh of this.shades) sh.prim.setVisible(visible);\n if (this.hasBarColor()) this.host.syncBarColors(this.source);\n this.host.changed();\n }\n\n setStyle(plotKey: string, style: PlotStyle): void {\n if (style.color !== undefined) parseColor(style.color);\n this.styles[plotKey] = { ...this.styles[plotKey], ...style };\n for (const o of this.outs) {\n if (o.key.split(\":\")[0] !== plotKey) continue;\n o.series.applyOptions(this.seriesOptions(o.plot, o.key) as never);\n }\n // a shade or a bar colour is not a series: it is drawn again from the columns\n if (!this.job && this.engine.length > 0 && (this.shades.length > 0 || this.hasBarColor())) this.syncOverlays();\n this.host.changed();\n }\n\n remove(): void {\n this.host.removeStudy(this.id);\n }\n\n /** The last computed value of each column (undefined while in warm-up), by column name. */\n lastValues(): Record<string, number | undefined> {\n const n = this.engine.length;\n const out: Record<string, number | undefined> = {};\n this.def.columns.forEach((c, k) => {\n const v = n > 0 ? this.engine.column(k)[n - 1]! : Number.NaN;\n out[c] = v === v ? v : undefined;\n });\n return out;\n }\n\n /** Output column `name` over the source bars (a view: copy it to keep it). */\n column(name: string): Float64Array {\n const k = this.def.columns.indexOf(name);\n if (k < 0) throw new RangeError(`${this.def.id} has no column \"${name}\"`);\n return this.engine.column(k);\n }\n\n /** Bar times of the columns. */\n times(): Float64Array {\n return this.engine.graph.time.v.subarray(0, this.engine.length);\n }\n\n /** The study as saved: its id, definition, inputs, source series ids, visibility and styles. `StudiesPlugin.toJSON` is a list of these. */\n state() {\n return {\n id: this.id,\n study: this.def.id,\n inputs: { ...this.params } as Record<string, InputValue>,\n source: this.source.options().id,\n ...(this.volume && { volume: this.volume.options().id }),\n visible: this.shown,\n styles: this.styles,\n };\n }\n\n /** @internal Detach without removing series (the chart already did). */\n drop(): void {\n if (!this.disposed) this.onDispose?.();\n this.disposed = true;\n this.job?.cancel();\n }\n\n /** @internal */\n dispose(chart: Chart): void {\n this.drop();\n for (const { series, line } of this.lines) chart.removePriceLine(series as never, line);\n for (const sh of this.shades) sh.anchor.detachPrimitive(sh.prim);\n for (const o of this.outs) chart.removeSeries(o.series);\n this.outs = [];\n this.lines = [];\n this.shades = [];\n }\n\n // ---- outside series -------------------------------------------------------------\n\n /**\n * Give the study outside series `key` (see engine/feed.ts for what a feed is and how it is joined), replacing the\n * previous bars of that key, and compute everything again. The study keeps its own copy.\n */\n setFeed(key: string, bars: FeedBars, cfg: FeedConfig): void {\n let f = this.feeds.get(key);\n if (!f) this.feeds.set(key, (f = new Feed()));\n f.load(bars, cfg, `outside series ${key}`);\n this.recompute();\n this.host.changed();\n }\n\n /** Keys of the outside series given so far. */\n feedKeys(): string[] {\n return [...this.feeds.keys()];\n }\n\n /**\n * A live bar of outside series `key` (same time as its last bar revises it, a later time appends). Only the study's\n * last bar is evaluated again, and only when it sees a different feed bar through the join; otherwise nothing is\n * recomputed or redrawn.\n */\n pushFeedBar(key: string, bar: FeedBar): void {\n const f = this.feeds.get(key);\n if (!f) throw new RangeError(`${this.def.id}: no outside series \"${key}\"; give it with setFeed first`);\n f.apply(bar, `outside series ${key}`); // the study's own copy: what a later full computation sends\n if (this.disposed || this.error) return;\n if (this.job) {\n // a batch that started before this bar is in flight: run again when it lands\n this.structural = true;\n return;\n }\n const runner = this.ownRunner ?? this.host.runner;\n if (runner?.canRun(this.def)) {\n // every revision goes to the runner, the forming bar's too: a chart bar that opens as the longer bar finishes must see its final\n // values, not those of its first tick (the runner answers a revision no chart bar sees as idle, at the cost of one message)\n runner.feedBar?.(this.def, key, bar);\n return;\n }\n if (this.engine.pushFeed(key, bar)) {\n this.tickSync();\n this.host.api?.requestRender();\n }\n }\n\n // ---- bar colours (composed by the plugin) --------------------------------------------\n\n /** @internal */\n hasBarColor(): boolean {\n return this.def.plots.some((p) => p.kind === \"barcolor\");\n }\n\n /** @internal The source series this study colours. */\n barColorSource(): SourceSeries {\n return this.source;\n }\n\n /** @internal Colour of the bar at engine row `j` from this study's barcolor plots: the latest that applies, 0 if none. */\n barColorAt(j: number): number {\n const e = this.engine;\n let c = 0;\n if (j < 0) return c;\n for (const p of this.def.plots) {\n if (p.kind !== \"barcolor\") continue;\n const v = e.outputs[this.def.columns.indexOf(p.col)]!.v[j]!;\n if (v === v && v !== 0) c = parseColor(this.color(p));\n }\n return c;\n }\n\n /** @internal Time and colour of every row (0 = none). */\n barColors(): { time: Float64Array; color: Uint32Array } {\n const n = this.engine.length;\n const color = new Uint32Array(n);\n for (let j = 0; j < n; j++) color[j] = this.barColorAt(j);\n return { time: this.engine.graph.time.v.slice(0, n), color };\n }\n\n /** @internal Engine row of the bar at `time` (the last row when it is the last bar's time), -1 if none. */\n rowOf(time: number): number {\n const n = this.engine.length;\n return n > 0 && this.engine.graph.time.v[n - 1] === time ? n - 1 : -1;\n }\n\n /** @internal Time of the last row, NaN when empty. */\n lastTime(): number {\n const n = this.engine.length;\n return n > 0 ? this.engine.graph.time.v[n - 1]! : Number.NaN;\n }\n\n get isShown(): boolean {\n return this.shown && !this.error && !this.disposed;\n }\n\n // ---- source ------------------------------------------------------------------\n\n private get ohlc(): boolean {\n return this.source.data.shape === \"ohlc\";\n }\n\n private checkSource(): void {\n const need = this.def.needs;\n if (!this.ohlc) {\n if (need !== \"value\") throw new TypeError(`${this.def.id} needs ${need} bars; the source series holds single values`);\n if (this.params.source !== undefined && this.params.source !== \"close\") {\n throw new RangeError(`${this.def.id}: a single-value source has only \"close\", not \"${this.params.source}\"`);\n }\n }\n if (need === \"ohlcv\" && !this.volume) throw new TypeError(`${this.def.id} needs volume: pass the volume series as options.volume`);\n if (!this.ohlc && this.def.plots.some((p) => p.kind === \"barcolor\")) throw new TypeError(`${this.def.id} colours bars; the source series holds single values, not candles or bars`);\n }\n\n /** Whether `d` is the store of one of this study's inputs. */\n private watches(d: SeriesData | null): \"source\" | \"volume\" | null {\n if (d === this.source.data) return \"source\";\n if (this.volume && d === this.volume.data) return \"volume\";\n return null;\n }\n\n private bars(): BarColumns {\n const chart = this.host.chart;\n const sd = this.source.data;\n const st = sd.store;\n let n = 0;\n for (let i = st.first; i < st.end; i++) if (sd.has(i)) n++;\n const time = new Float64Array(n), close = new Float64Array(n);\n const ohlc = this.ohlc;\n const open = ohlc ? new Float64Array(n) : undefined, high = ohlc ? new Float64Array(n) : undefined, low = ohlc ? new Float64Array(n) : undefined;\n const vol = this.volume ? new Float64Array(n) : undefined;\n let k = 0;\n for (let i = st.first; i < st.end; i++) {\n if (!sd.has(i)) continue;\n time[k] = chart.logicalToTime(i);\n if (ohlc) {\n open![k] = sd.get(i, COL_O);\n high![k] = sd.get(i, COL_H);\n low![k] = sd.get(i, COL_L);\n close[k] = sd.get(i, COL_C);\n } else close[k] = sd.get(i, COL_V);\n if (vol) vol[k] = this.volume!.data.get(i, COL_V);\n k++;\n }\n return { time, close, ...(ohlc && { open, high, low }), ...(vol && { volume: vol }) } as BarColumns;\n }\n\n private barAt(i: number): BarInput {\n const sd = this.source.data;\n const nan = Number.NaN;\n return {\n time: this.host.chart.logicalToTime(i),\n open: this.ohlc ? sd.get(i, COL_O) : nan,\n high: this.ohlc ? sd.get(i, COL_H) : nan,\n low: this.ohlc ? sd.get(i, COL_L) : nan,\n close: this.ohlc ? sd.get(i, COL_C) : sd.get(i, COL_V),\n volume: this.volume ? this.volume.data.get(i, COL_V) : nan,\n };\n }\n\n // ---- following the source ------------------------------------------------------\n\n /** @internal */\n onChange(c: DataChange): void {\n if (this.disposed || this.error || c.kind === \"color\") return;\n const which = this.watches(c.series);\n if (c.series === null) {\n // A removal elsewhere rebuilt the timeline: nothing of ours moved unless an input died.\n return;\n }\n if (!which) return;\n if (this.job) {\n if (c.kind === \"update\") this.dirty = true;\n else this.structural = true;\n return;\n }\n if (c.kind !== \"update\") {\n this.recompute();\n return;\n }\n const sd = this.source.data;\n const last = sd.lastIndex();\n if (last === undefined) return this.recompute();\n if (which === \"volume\" && c.lo > last) return; // a volume bar for a time the source has not reached\n if (which === \"volume\" && c.lo < last) return this.recompute(); // a late volume revision of an earlier bar\n const bar = this.barAt(last);\n const e = this.engine;\n const n = e.length;\n const lastTime = n > 0 ? e.graph.time.v[n - 1]! : Number.NaN;\n if (n > 0 && bar.time === lastTime) e.reviseLast(bar);\n else if (n === 0 || bar.time > lastTime) e.push(bar);\n else return this.recompute();\n this.tickSync();\n this.host.api?.requestRender();\n }\n\n /** Recompute everything from the source's bars. */\n private recompute(): void {\n this.version++;\n this.job?.cancel();\n this.job = null;\n this.dirty = false;\n this.structural = false;\n this.error = null;\n const bars = this.bars();\n const runner = this.ownRunner ?? this.host.runner;\n if (!runner || !runner.canRun(this.def)) {\n for (const [k, f] of this.feeds) this.engine.setFeed(k, f.snapshot(), f);\n this.engine.load(bars);\n this.syncAll();\n this.ready_ = Promise.resolve();\n return;\n }\n const v = this.version;\n const feeds = this.feeds.size > 0 ? Object.fromEntries([...this.feeds].map(([k, f]) => [k, { align: f.align, spanMs: f.spanMs, bars: f.snapshot() }])) : undefined;\n const run = runner.run(this.def, { studyId: this.def.id, params: this.params, bars, ...(feeds && { feeds }) });\n this.job = run;\n this.ready_ = run.promise.then(\n (res) => {\n if (v !== this.version || this.disposed) return;\n this.job = null;\n this.engine.graph.adopt(res.buffers, res.n);\n if (this.structural) {\n this.recompute();\n return;\n }\n if (this.dirty) {\n this.dirty = false;\n this.catchUp();\n }\n this.syncAll();\n },\n (err: unknown) => {\n if (err instanceof CancelledError || v !== this.version || this.disposed) return;\n this.job = null;\n this.error = err instanceof Error ? err : new Error(String(err));\n throw this.error;\n },\n );\n }\n\n /** Bring an adopted engine up to the source's current last bars (ticks that arrived during the job). */\n private catchUp(): void {\n const e = this.engine;\n const b = this.bars();\n const n = b.time.length;\n if (e.length === 0 || n === 0) return this.fullLoad(b);\n const lastTime = e.graph.time.v[e.length - 1]!;\n let k = lowerBound(b.time, n, lastTime);\n const at = (j: number): BarInput => ({\n time: b.time[j]!, open: b.open?.[j] ?? Number.NaN, high: b.high?.[j] ?? Number.NaN, low: b.low?.[j] ?? Number.NaN, close: b.close[j]!, volume: b.volume?.[j] ?? Number.NaN,\n });\n if (k < n && b.time[k] === lastTime) e.reviseLast(at(k++));\n else if (k < n && k === 0) return this.fullLoad(b);\n for (; k < n; k++) e.push(at(k));\n }\n\n private fullLoad(b: BarColumns): void {\n this.engine.load(b);\n }\n\n // ---- output series ---------------------------------------------------------------\n\n private title(): string {\n const l = this.def.label?.(this.params);\n return l ? `${this.def.name} (${l})` : this.def.name;\n }\n\n private retitle(): void {\n this.outs.forEach((o, i) => o.series.applyOptions({ title: i === 0 ? this.title() : o.plot.title } as never));\n }\n\n private color(plot: PlotDef & { color?: string }): string {\n return this.styles[plot.key]?.color ?? (plot as { color: string }).color;\n }\n\n private seriesOptions(plot: PlotDef, key: string): Record<string, unknown> {\n const st = this.styles[plot.key];\n const color = st?.color;\n switch (plot.kind) {\n case \"line\": return { color: color ?? plot.color, lineWidth: st?.width ?? plot.width ?? 1.5 };\n case \"band\": return { color: color ?? plot.color, lineWidth: st?.width ?? plot.width ?? 1 };\n case \"histogram\": return { color: color ?? plot.color };\n case \"area\": {\n const c = color ?? plot.color;\n return { lineColor: c, topColor: withAlpha(c, 0.28), bottomColor: withAlpha(c, 0.02), lineWidth: st?.width ?? 1.5 };\n }\n default: return {};\n }\n void key;\n }\n\n private createSeries(): void {\n const chart = this.host.chart;\n const so = this.source.options();\n if (this.def.pane === \"overlay\") {\n this.pane = so.pane;\n this.scaleId = this.def.scale ?? so.priceScaleId;\n } else {\n this.pane = this.host.freePane();\n this.scaleId = this.def.scale ?? \"right\";\n }\n const overlay = this.def.pane === \"overlay\";\n // an overlay on the source's own scale reads like its source; on the other axis (or in a pane of its own) it has its own scale and format\n this.sameScale = overlay && this.scaleId === so.priceScaleId;\n const cols = this.def.columns;\n const add = (plot: PlotDef, key: string, type: \"line\" | \"histogram\" | \"area\", col: string, offset: number) => {\n const s = chart.addSeries(type, {\n id: `study:${this.id}:${key}`, pane: this.pane, priceScaleId: this.scaleId, title: this.outs.length === 0 ? this.title() : plot.title,\n lastValueVisible: !this.sameScale, priceLineVisible: false, visible: this.shown, ...this.seriesOptions(plot, key),\n // Overlays read like their source; oscillators show two decimals instead of whatever the data happens to carry.\n priceFormat: this.sameScale ? so.priceFormat : { type: \"price\", minMove: this.def.minMove ?? 10 ** -this.decimals },\n } as never) as unknown as Series<\"line\" | \"histogram\" | \"area\">;\n this.outs.push({ plot, key, col: cols.indexOf(col), series: s, offset, lastTime: Number.NaN });\n };\n for (const plot of this.def.plots) {\n switch (plot.kind) {\n case \"line\":\n if (!isOverlayLine(plot, this.params)) add(plot, plot.key, \"line\", plot.col, plotOffset(plot, this.params));\n break;\n case \"histogram\": add(plot, plot.key, \"histogram\", plot.col, 0); break;\n case \"area\": add(plot, plot.key, \"area\", plot.col, 0); break;\n case \"band\":\n add(plot, `${plot.key}:upper`, \"line\", plot.upper, 0);\n add(plot, `${plot.key}:lower`, \"line\", plot.lower, 0);\n break;\n default: break;\n }\n }\n const anchor = this.outs[0]?.series as unknown as AnySeries | undefined;\n for (const plot of this.def.plots) {\n if (plot.kind !== \"bgcolor\") continue;\n // shades the pane the study draws in: the source's for an overlay, else the pane its first series made\n const host = overlay ? (this.source as unknown as AnySeries) : anchor;\n if (!host) throw new TypeError(`${this.def.id}: bgcolor shades the study's pane, and a study in its own pane needs a plot to hold it`);\n const prim = new BarShading();\n prim.setVisible(this.shown);\n host.attachPrimitive(prim);\n this.shades.push({ plot, col: cols.indexOf(plot.col), prim, anchor: host });\n }\n if (anchor) {\n for (const plot of this.def.plots) {\n if (plot.kind !== \"hline\") continue;\n const price = typeof plot.value === \"function\" ? plot.value(this.params) : plot.value;\n const line = chart.createPriceLine(anchor as never, { price, color: plot.color, lineStyle: plot.style ?? \"dashed\", lineWidth: 1, axisLabelVisible: false });\n this.lines.push({ series: anchor, line });\n }\n }\n }\n\n private syncAll(): void {\n const e = this.engine;\n const n = e.length;\n const times = e.graph.time.v;\n for (const o of this.outs) this.writeSeries(o, e.outputs[o.col]!.v, times, n);\n this.syncOverlays();\n this.host.api?.requestRender(true);\n }\n\n /** Background shades and bar colours, from the engine's columns (every bar). */\n private syncOverlays(): void {\n const e = this.engine;\n const n = e.length;\n const times = e.graph.time.v;\n for (const sh of this.shades) {\n const col = e.outputs[sh.col]!.v;\n const rgba = parseColor(this.color(sh.plot));\n const color = new Uint32Array(n);\n for (let j = 0; j < n; j++) color[j] = col[j]! === col[j]! && col[j] !== 0 ? rgba : 0;\n sh.prim.set(times.slice(0, n), color);\n }\n if (this.hasBarColor()) this.host.syncBarColors(this.source);\n }\n\n private writeSeries(o: OutSeries, col: Float64Array, times: Float64Array, n: number): void {\n const down = o.plot.kind === \"histogram\" && o.plot.colorDown ? { up: parseColor(this.color(o.plot)), down: parseColor(o.plot.colorDown) } : null;\n const by = o.plot.kind === \"line\" && o.plot.colorBy ? { col: this.engine.outputs[this.def.columns.indexOf(o.plot.colorBy.col)]!.v, color: parseColor(o.plot.colorBy.color) } : null;\n let m = 0;\n for (let j = 0; j < n; j++) {\n const t = j + o.offset;\n if (t >= 0 && t < n && col[j] === col[j]) m++;\n }\n const time = new Float64Array(m), value = new Float64Array(m);\n const color = down || by ? new Uint32Array(m) : undefined;\n let k = 0;\n for (let j = 0; j < n; j++) {\n const t = j + o.offset;\n if (t < 0 || t >= n || col[j] !== col[j]) continue;\n time[k] = times[t]!;\n value[k] = col[j]!;\n if (down) color![k] = col[j]! >= 0 ? down.up : down.down;\n else if (by) color![k] = by.col[j]! === by.col[j]! && by.col[j] !== 0 ? by.color : 0;\n k++;\n }\n let maxAbs = 0;\n for (let q = 0; q < m; q++) maxAbs = Math.max(maxAbs, Math.abs(value[q]!));\n this.widen(maxAbs);\n o.series.setData({ time, value, ...(color && { color }) } as never);\n o.lastTime = m > 0 ? time[m - 1]! : Number.NaN;\n }\n\n /** Show enough decimals for values below 1 (three significant digits); only ever grows. A def's own `minMove` wins; an overlay reads like its source. */\n private widen(maxAbs: number): void {\n if (this.sameScale || this.def.minMove !== undefined || !(maxAbs > 0) || maxAbs >= 1) return;\n const d = Math.min(8, 2 - Math.floor(Math.log10(maxAbs)));\n if (d <= this.decimals) return;\n this.decimals = d;\n for (const o of this.outs) o.series.applyOptions({ priceFormat: { type: \"price\", minMove: 10 ** -d } } as never);\n }\n\n /** The output series that draws `column`, or undefined when no plot does (a column that is only an input to others). */\n seriesOfColumn(column: string): AnySeries | undefined {\n const k = this.def.columns.indexOf(column);\n return this.outs.find((o) => o.col === k)?.series as unknown as AnySeries | undefined;\n }\n\n /** After one appended or revised bar: one point per output series. */\n private tickSync(): void {\n const e = this.engine;\n const n = e.length;\n const times = e.graph.time.v;\n const t = times[n - 1]!;\n const cols = this.def.columns;\n for (const sh of this.shades) {\n const v = e.outputs[sh.col]!.v[n - 1]!;\n sh.prim.setAt(t, v === v && v !== 0 ? parseColor(this.color(sh.plot)) : 0);\n }\n if (this.hasBarColor()) this.host.syncBarColors(this.source, true);\n for (const o of this.outs) {\n const j = n - 1 - o.offset;\n if (j < 0) continue;\n const col = e.outputs[o.col]!.v;\n const v = col[j]!;\n if (v === v) {\n this.widen(Math.abs(v));\n const down = o.plot.kind === \"histogram\" && o.plot.colorDown;\n const by = o.plot.kind === \"line\" ? o.plot.colorBy : undefined;\n const cond = by ? e.outputs[cols.indexOf(by.col)]!.v[j]! : Number.NaN;\n const own = by && cond === cond && cond !== 0 ? by.color : undefined;\n o.series.update({ time: t, value: v, ...(down && { color: v >= 0 ? this.color(o.plot) : down }), ...(own && { color: own }) } as never);\n o.lastTime = t;\n } else if (o.lastTime === t) this.writeSeries(o, col, times, n); // a point turned absent: rewrite\n }\n }\n\n // ---- overlay drawing ---------------------------------------------------------------\n\n /** @internal */\n draw(ctx: CanvasRenderingContext2D, view: PluginPaneView): void {\n if (!this.shown || view.pane !== this.pane) return;\n const e = this.engine;\n const n = e.length;\n if (n === 0) return;\n const times = e.graph.time.v;\n const lo = Math.max(0, lowerBound(times, n, view.xToTime(0)) - 1);\n const hi = Math.min(n, lowerBound(times, n, view.xToTime(view.width)) + 2);\n if (hi <= lo) return;\n const step = Math.max(1, Math.floor((hi - lo) / (view.width * 2)));\n const X = (j: number) => view.timeToX(times[j]!);\n const Y = (v: number) => view.priceToY(v, this.scaleId);\n const col = (name: string) => e.outputs[this.def.columns.indexOf(name)]!.v;\n for (const plot of this.def.plots) {\n switch (plot.kind) {\n case \"band\": fillBetween(ctx, lo, hi, step, X, Y, col(plot.upper), col(plot.lower), this.styles[plot.key]?.color ?? plot.fill, 0); break;\n case \"fill\": fillBetween(ctx, lo, hi, step, X, Y, col(plot.a), col(plot.b), this.styles[plot.key]?.color ?? plot.color, 0); break;\n case \"line\":\n if (isOverlayLine(plot, this.params)) polyline(ctx, lo, hi, step, n, X, Y, col(plot.col), plotOffset(plot, this.params), !!plot.connect, this.color(plot), this.styles[plot.key]?.width ?? plot.width ?? 1.5);\n break;\n case \"markers\": this.drawMarkers(ctx, plot, lo, hi, X, Y, col(plot.col), n); break;\n case \"zigzag\": zigzag(ctx, lo, hi, X, Y, col(plot.price), col(plot.back), times, this.color(plot), plot.width ?? 1.5); break;\n default: break;\n }\n }\n }\n\n private drawMarkers(ctx: CanvasRenderingContext2D, plot: Extract<PlotDef, { kind: \"markers\" }>, lo: number, hi: number, X: (j: number) => number, Y: (v: number) => number, col: Float64Array, n: number): void {\n const off = plotOffset(plot, this.params);\n const high = this.engine.graph.high.v, low = this.engine.graph.low.v;\n const color = this.color(plot);\n ctx.save();\n ctx.fillStyle = color;\n ctx.strokeStyle = color;\n ctx.font = \"10px system-ui, sans-serif\";\n ctx.textAlign = \"center\";\n let drawn = 0;\n // `last` / `within` cut the marks to the newest ones, judged over every bar, not only the visible ones.\n const first = Math.max(lo, markerFloor(col, n, plot));\n for (let j = first; j < hi && drawn < 4000; j++) {\n const v = col[j]!;\n if (v !== v || (plot.text && v === 0)) continue;\n const b = j + off;\n if (b < 0 || b >= n) continue;\n const x = X(b);\n const side = plot.position === \"sign\" ? (v > 0 ? \"below\" : \"above\") : plot.position;\n let y: number, dir: 1 | -1;\n if (side === \"value\") { y = Y(v); dir = 1; }\n else if (side === \"above\") { y = Y(high[b]!) - 8; dir = -1; }\n else { y = Y(low[b]!) + 8; dir = 1; }\n if (plot.text) {\n ctx.textBaseline = dir < 0 ? \"bottom\" : \"top\";\n ctx.fillText(String(Math.round(v)), x, side === \"above\" ? y - 2 : y + 2);\n } else shape(ctx, plot.shape, x, y, side === \"above\" ? -1 : 1);\n drawn++;\n }\n ctx.restore();\n }\n}\n\n// ---- drawing helpers -----------------------------------------------------------------\n\n/** A plot's shift in bars: the number written, or the function of the study's inputs. */\nfunction plotOffset(p: Extract<PlotDef, { kind: \"line\" | \"markers\" }>, params: Params): number {\n return typeof p.offset === \"function\" ? p.offset(params) : (p.offset ?? 0);\n}\n\nfunction isOverlayLine(p: Extract<PlotDef, { kind: \"line\" }>, params: Params): boolean {\n return plotOffset(p, params) < 0 || !!p.connect;\n}\n\nfunction lowerBound(a: Float64Array, n: number, t: number): number {\n let lo = 0, hi = n;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (a[mid]! < t) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nfunction withAlpha(css: string, alpha: number): string {\n const c = parseColor(css);\n return cssColor(((c & 0xffffff00) | Math.round(alpha * 255)) >>> 0);\n}\n\nfunction fillBetween(ctx: CanvasRenderingContext2D, lo: number, hi: number, step: number, X: (j: number) => number, Y: (v: number) => number, a: Float64Array, b: Float64Array, color: string, _off: number): void {\n ctx.save();\n ctx.fillStyle = color;\n let run: number[] = [];\n const flush = () => {\n if (run.length > 1) {\n ctx.beginPath();\n ctx.moveTo(X(run[0]!), Y(a[run[0]!]!));\n for (let k = 1; k < run.length; k++) ctx.lineTo(X(run[k]!), Y(a[run[k]!]!));\n for (let k = run.length - 1; k >= 0; k--) ctx.lineTo(X(run[k]!), Y(b[run[k]!]!));\n ctx.closePath();\n ctx.fill();\n }\n run = [];\n };\n for (let j = lo; j < hi; j += step) {\n if (a[j] === a[j] && b[j] === b[j]) run.push(j);\n else flush();\n }\n flush();\n ctx.restore();\n}\n\nfunction polyline(ctx: CanvasRenderingContext2D, lo: number, hi: number, step: number, n: number, X: (j: number) => number, Y: (v: number) => number, col: Float64Array, off: number, connect: boolean, color: string, width: number): void {\n ctx.save();\n ctx.strokeStyle = color;\n ctx.lineWidth = width;\n ctx.beginPath();\n let pen = false;\n for (let j = lo; j < hi; j += step) {\n const v = col[j]!, b = j + off;\n if (v !== v || b < 0 || b >= n) {\n if (!connect) pen = false;\n continue;\n }\n if (pen) ctx.lineTo(X(b), Y(v));\n else ctx.moveTo(X(b), Y(v));\n pen = true;\n }\n ctx.stroke();\n ctx.restore();\n}\n\nfunction zigzag(ctx: CanvasRenderingContext2D, lo: number, hi: number, X: (j: number) => number, Y: (v: number) => number, price: Float64Array, back: Float64Array, times: Float64Array, color: string, width: number): void {\n void times;\n ctx.save();\n ctx.strokeStyle = color;\n ctx.lineWidth = width;\n ctx.beginPath();\n let pen = false;\n // start a little left of the view so the segment entering it is drawn\n for (let j = Math.max(0, lo - 2000); j < hi; j++) {\n const p = price[j]!;\n if (p !== p) continue;\n const at = j - back[j]!;\n if (pen) ctx.lineTo(X(at), Y(p));\n else ctx.moveTo(X(at), Y(p));\n pen = true;\n }\n ctx.stroke();\n ctx.restore();\n}\n\nfunction shape(ctx: CanvasRenderingContext2D, kind: string, x: number, y: number, dir: 1 | -1): void {\n const r = 4;\n ctx.beginPath();\n switch (kind) {\n case \"square\": ctx.rect(x - r, y - r, 2 * r, 2 * r); ctx.fill(); return;\n case \"diamond\": ctx.moveTo(x, y - r - 1); ctx.lineTo(x + r + 1, y); ctx.lineTo(x, y + r + 1); ctx.lineTo(x - r - 1, y); ctx.closePath(); ctx.fill(); return;\n case \"triangleUp\": case \"arrowUp\": ctx.moveTo(x, y - r); ctx.lineTo(x + r, y + r); ctx.lineTo(x - r, y + r); ctx.closePath(); ctx.fill(); return;\n case \"triangleDown\": case \"arrowDown\": ctx.moveTo(x, y + r); ctx.lineTo(x + r, y - r); ctx.lineTo(x - r, y - r); ctx.closePath(); ctx.fill(); return;\n case \"cross\": ctx.moveTo(x - r, y - r); ctx.lineTo(x + r, y + r); ctx.moveTo(x + r, y - r); ctx.lineTo(x - r, y + r); ctx.stroke(); return;\n default: ctx.arc(x, y, r - 1, 0, Math.PI * 2); ctx.fill(); void dir;\n }\n}\n\n// ---- the plugin -------------------------------------------------------------------------\n\ninterface SavedStudy {\n id: string;\n study: string;\n inputs: Record<string, InputValue>;\n source: string;\n volume?: string;\n visible: boolean;\n styles: Record<string, PlotStyle>;\n}\n\nexport class StudiesPlugin implements ChartPlugin {\n readonly id = PLUGIN_ID;\n api: PluginApi | null = null;\n private readonly studies = new Map<string, Study>();\n private counter = 0;\n /** Sources whose bars the plugin has coloured: the plugin owns their colour column while a barcolor study exists. */\n private readonly coloured = new Set<SourceSeries>();\n\n constructor(readonly chart: Chart, readonly runner: StudyRunner | undefined, private readonly resolve: (id: string) => StudyDef) {}\n\n install(api: PluginApi): void {\n this.api = api;\n }\n\n uninstall(): void {\n const sources = [...this.coloured];\n for (const s of [...this.studies.values()]) s.dispose(this.chart);\n this.studies.clear();\n for (const src of sources) this.syncBarColors(src);\n this.api = null;\n }\n\n /**\n * Bring the colours of `source`'s candles in line with every visible study that colours them: per bar, the latest\n * study (in creation order) whose barcolor applies wins. With no such study the colour column is removed, so the\n * candles are exactly as they were. `last`: only the source's last bar (a tick).\n * @internal\n */\n syncBarColors(source: SourceSeries, last = false): void {\n const live = [...this.studies.values()].filter((s) => s.barColorSource() === source && s.hasBarColor() && s.isShown);\n const target = source as unknown as Series<\"candles\">;\n if (live.length === 0) {\n if (this.coloured.delete(source)) target.clearBarColors();\n return;\n }\n this.coloured.add(source);\n if (last) {\n const t = live[0]!.lastTime();\n if (t !== t) return;\n let c = 0;\n for (const s of live) if (s.lastTime() === t) c = s.barColorAt(s.rowOf(t)) || c;\n target.setBarColors({ time: Float64Array.of(t), color: Uint32Array.of(c) });\n return;\n }\n const base = live[0]!.barColors();\n const time = base.time, color = base.color;\n for (let k = 1; k < live.length; k++) {\n const o = live[k]!.barColors();\n let j = 0;\n for (let i = 0; i < o.time.length; i++) {\n while (j < time.length && time[j]! < o.time[i]!) j++;\n if (j < time.length && time[j] === o.time[i] && o.color[i] !== 0) color[j] = o.color[i]!;\n }\n }\n target.setBarColors({ time, color });\n }\n\n dataChanged(c: DataChange): void {\n for (const s of this.studies.values()) s.onChange(c);\n this.reap();\n }\n\n drawPane(ctx: CanvasRenderingContext2D, view: PluginPaneView): void {\n for (const s of this.studies.values()) s.draw(ctx, view);\n }\n\n list(): Study[] {\n return [...this.studies.values()];\n }\n\n get(id: string): Study | undefined {\n return this.studies.get(id);\n }\n\n /** @internal */\n changed(): void {\n this.api?.requestRender(true);\n }\n\n /** Lowest pane index >= 1 holding no series (reuses a gap), else a new pane. */\n freePane(): number {\n const used = new Set(this.chart.series().map((s) => s.options().pane));\n let p = 1;\n while (used.has(p)) p++;\n return p;\n }\n\n add(def: StudyDef, inputs: Readonly<Record<string, InputValue>>, source: SourceSeries, o: AddStudyOptions = {}, saved?: { visible?: boolean; styles?: Record<string, PlotStyle> }): Study {\n const id = o.id ?? this.nextId();\n if (this.studies.has(id)) throw new Error(`alphacharts: a study with id \"${id}\" already exists`);\n const bump = /^s(\\d+)$/.exec(id);\n if (bump) this.counter = Math.max(this.counter, Number(bump[1]));\n const s = new Study(this, id, def, inputs, source, o.volume, saved, o.runner, o.onDispose);\n s.persist = o.persist !== false;\n this.studies.set(id, s);\n // a study computed inline has already written once, before it was registered to be composed\n if (s.hasBarColor()) this.syncBarColors(source);\n return s;\n }\n\n removeStudy(id: string): void {\n const s = this.studies.get(id);\n if (!s) return;\n this.studies.delete(id);\n s.dispose(this.chart);\n if (s.hasBarColor()) this.syncBarColors(s.barColorSource());\n this.changed();\n }\n\n /** Drop studies whose source series was removed from the chart. */\n private reap(): void {\n const alive = new Set<SeriesData>(this.chart.series().map((s) => s.data));\n for (const [id, s] of this.studies) {\n const inputs = s as unknown as { source: SourceSeries; volume?: Series<\"histogram\" | \"line\" | \"area\"> };\n if (!alive.has(inputs.source.data) || (inputs.volume && !alive.has(inputs.volume.data))) {\n this.studies.delete(id);\n s.dispose(this.chart);\n if (!alive.has(inputs.source.data)) this.coloured.delete(inputs.source);\n else if (s.hasBarColor()) this.syncBarColors(inputs.source);\n }\n }\n }\n\n /** Never hand out an id at or below `n` again: ids of removed studies stay retired, so an alert that still names one cannot land on a different study. */\n reserveIds(n: number): void {\n this.counter = Math.max(this.counter, n);\n }\n\n /** The highest `s<n>` number handed out or restored so far. */\n idHighWater(): number {\n return this.counter;\n }\n\n private nextId(): string {\n return `s${++this.counter}`;\n }\n\n toJSON(): unknown {\n return { version: 1, studies: [...this.studies.values()].filter((s) => s.persist).map((s) => s.state()) };\n }\n\n /** Throws what `fromJSON(state)` would, changing nothing: the layout is refused whole when a study cannot be rebuilt. */\n validateState(state: unknown, ctx: { seriesIds: readonly string[] }): void {\n const st = state as { version?: number; studies?: SavedStudy[] };\n if (st?.version !== 1 || !Array.isArray(st.studies)) throw new TypeError(\"alphacharts studies: unrecognised layout state\");\n const seen = new Set<string>();\n for (const ss of st.studies) {\n if (seen.has(ss.id)) throw new Error(`alphacharts studies: the layout repeats study id \"${ss.id}\"`);\n seen.add(ss.id);\n if (!ctx.seriesIds.includes(ss.source)) throw new Error(`alphacharts studies: study \"${ss.id}\" needs series \"${ss.source}\", which the layout does not contain`);\n if (ss.volume && !ctx.seriesIds.includes(ss.volume)) throw new Error(`alphacharts studies: study \"${ss.id}\" needs volume series \"${ss.volume}\"`);\n resolveParams(this.resolve(ss.study), ss.inputs);\n }\n }\n\n /** Called after the chart restored its series: rebuild each study over the restored series. */\n fromJSON(state: unknown): void {\n const st = state as { version?: number; studies?: SavedStudy[] };\n if (st?.version !== 1 || !Array.isArray(st.studies)) throw new TypeError(\"alphacharts studies: unrecognised layout state\");\n for (const s of this.studies.values()) s.drop();\n this.studies.clear();\n const byId = new Map(this.chart.series().map((s) => [s.options().id, s]));\n for (const ss of st.studies) {\n const source = byId.get(ss.source);\n if (!source) throw new Error(`alphacharts studies: study \"${ss.id}\" needs series \"${ss.source}\", which the layout does not contain`);\n const volume = ss.volume ? byId.get(ss.volume) : undefined;\n if (ss.volume && !volume) throw new Error(`alphacharts studies: study \"${ss.id}\" needs volume series \"${ss.volume}\"`);\n // The restored layout already holds this study's output series (bare); replace them with live ones.\n for (const s of [...byId.values()]) if (s.options().id.startsWith(`study:${ss.id}:`)) this.chart.removeSeries(s);\n this.add(this.resolve(ss.study), ss.inputs, source as SourceSeries, { id: ss.id, ...(volume && { volume: volume as never }) }, { visible: ss.visible, styles: ss.styles });\n }\n // Output series of studies this plugin does not save (a script's) came back bare in the layout: whoever owns the study rebuilds them.\n const live = new Set<unknown>([...this.studies.values()].flatMap((s) => s.series()));\n for (const s of this.chart.series()) if (s.options().id.startsWith(\"study:\") && !live.has(s)) this.chart.removeSeries(s);\n }\n}\n\n// ---- public entry points -------------------------------------------------------------------\n\n/** Install the studies plugin on a chart (idempotent). Restoring a layout that holds studies needs this first. */\nexport function installStudies(chart: Chart, opts: { runner?: StudyRunner; resolve?: (id: string) => StudyDef } = {}): StudiesPlugin {\n const have = chart.plugin<StudiesPlugin>(PLUGIN_ID);\n if (have) return have;\n const p = new StudiesPlugin(chart, opts.runner, opts.resolve ?? getStudy);\n chart.addPlugin(p);\n return p;\n}\n\n/**\n * Add a study over `source`. `study` is a definition (tree-shakable) or the id of\n * a registered one. Throws on unknown inputs, out-of-range values or a source\n * that lacks what the study needs.\n */\nexport function addStudy(chart: Chart, source: SourceSeries, study: StudyDef | string, inputs: Readonly<Record<string, InputValue>> = {}, opts: AddStudyOptions = {}): Study {\n const def = typeof study === \"string\" ? getStudy(study) : study;\n const plugin = installStudies(chart, opts.runner ? { runner: opts.runner } : {});\n return plugin.add(def, inputs, source, opts);\n}\n","// Opt in to the WASM batch kernels. Resolves once they are instantiated; rejects\n// (and leaves the JS loops in place) when the runtime has no WASM SIMD.\nimport { loadKernels } from \"@alphacharts/wasm\";\nimport { setKernels } from \"./engine/kernels.js\";\n\nexport async function enableWasm(): Promise<void> {\n setKernels(await loadKernels());\n}\n\nexport function disableWasm(): void {\n setKernels(null);\n}\n"],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ //#region src/registry.ts
2
+ var e = /* @__PURE__ */ new Map();
3
+ function t(t) {
4
+ let n = e.get(t.id);
5
+ if (n !== t) {
6
+ if (n) throw Error(`alphacharts: study "${t.id}" is already registered with a different definition`);
7
+ a(t), e.set(t.id, t);
8
+ }
9
+ }
10
+ function n(e) {
11
+ for (let n of e) t(n);
12
+ }
13
+ function r(t) {
14
+ let n = e.get(t);
15
+ if (!n) throw Error(`alphacharts: unknown study "${t}" (register it with registerStudy)`);
16
+ return n;
17
+ }
18
+ function i() {
19
+ return [...e.values()];
20
+ }
21
+ function a(e) {
22
+ let t = new Set(e.columns);
23
+ if (t.size !== e.columns.length) throw Error(`${e.id}: duplicate column names`);
24
+ let n = /* @__PURE__ */ new Set(), r = (n, r) => {
25
+ if (!t.has(n)) throw Error(`${e.id}: plot "${r}" uses unknown column "${n}"`);
26
+ };
27
+ for (let t of e.plots) {
28
+ if (n.has(t.key)) throw Error(`${e.id}: duplicate plot key "${t.key}"`);
29
+ switch (n.add(t.key), t.kind) {
30
+ case "line":
31
+ r(t.col, t.key), t.colorBy && r(t.colorBy.col, t.key);
32
+ break;
33
+ case "histogram":
34
+ case "area":
35
+ case "markers":
36
+ case "barcolor":
37
+ case "bgcolor":
38
+ r(t.col, t.key);
39
+ break;
40
+ case "band":
41
+ r(t.upper, t.key), r(t.lower, t.key);
42
+ break;
43
+ case "fill":
44
+ r(t.a, t.key), r(t.b, t.key);
45
+ break;
46
+ case "zigzag": r(t.price, t.key), r(t.back, t.key);
47
+ }
48
+ }
49
+ }
50
+ //#endregion
51
+ export { a, t as i, i as n, n as r, r as t };
52
+
53
+ //# sourceMappingURL=registry-DdYYyZN_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-DdYYyZN_.js","names":["studies","registerStudy","prev","def","validateDef","registerStudies","d","defs","getStudy","id","listStudies","cols","keys","need","c","key","p"],"sources":["../src/registry.ts"],"sourcesContent":["// Study registry. Studies are plain objects, so an app that imports only what it\n// uses (`import { rsi } from \"@alphacharts/indicators/studies\"`) ships only that;\n// the registry holds the ones an app registers by id (`registerStudies`).\n\nimport type { StudyDef } from \"./types.js\";\n\nconst studies = new Map<string, StudyDef>();\n\nexport function registerStudy(def: StudyDef): void {\n const prev = studies.get(def.id);\n if (prev === def) return;\n if (prev) throw new Error(`alphacharts: study \"${def.id}\" is already registered with a different definition`);\n validateDef(def);\n studies.set(def.id, def);\n}\n\nexport function registerStudies(defs: readonly StudyDef[]): void {\n for (const d of defs) registerStudy(d);\n}\n\nexport function getStudy(id: string): StudyDef {\n const d = studies.get(id);\n if (!d) throw new Error(`alphacharts: unknown study \"${id}\" (register it with registerStudy)`);\n return d;\n}\n\nexport function listStudies(): StudyDef[] {\n return [...studies.values()];\n}\n\n/** Catch an inconsistent definition when it is registered, not when it is drawn. */\nexport function validateDef(def: StudyDef): void {\n const cols = new Set(def.columns);\n if (cols.size !== def.columns.length) throw new Error(`${def.id}: duplicate column names`);\n const keys = new Set<string>();\n const need = (c: string, key: string) => {\n if (!cols.has(c)) throw new Error(`${def.id}: plot \"${key}\" uses unknown column \"${c}\"`);\n };\n for (const p of def.plots) {\n if (keys.has(p.key)) throw new Error(`${def.id}: duplicate plot key \"${p.key}\"`);\n keys.add(p.key);\n switch (p.kind) {\n case \"line\": need(p.col, p.key); if (p.colorBy) need(p.colorBy.col, p.key); break;\n case \"histogram\": case \"area\": case \"markers\": case \"barcolor\": case \"bgcolor\": need(p.col, p.key); break;\n case \"band\": need(p.upper, p.key); need(p.lower, p.key); break;\n case \"fill\": need(p.a, p.key); need(p.b, p.key); break;\n case \"zigzag\": need(p.price, p.key); need(p.back, p.key); break;\n case \"hline\": break;\n }\n }\n}\n"],"mappings":";AAMA,IAAMA,oBAAU,IAAI,IAAsB;AAE1C,SAAgBC,EAAc,GAAqB;CACjD,IAAMC,IAAOF,EAAQ,IAAIG,EAAI,EAAE;CAC/B,IAAID,MAASC,GACb;MAAID,GAAM,MAAU,MAAM,uBAAuBC,EAAI,GAAG,oDAAoD;EAE5G,AADAC,EAAYD,CAAG,GACfH,EAAQ,IAAIG,EAAI,IAAIA,CAAG;CAFqF;AAG9G;AAEA,SAAgBE,EAAgB,GAAiC;CAC/D,KAAK,IAAMC,KAAKC,GAAM,EAAcD,CAAC;AACvC;AAEA,SAAgBE,EAAS,GAAsB;CAC7C,IAAMF,IAAIN,EAAQ,IAAIS,CAAE;CACxB,IAAI,CAACH,GAAG,MAAU,MAAM,+BAA+BG,EAAG,mCAAmC;CAC7F,OAAOH;AACT;AAEA,SAAgBI,IAA0B;CACxC,OAAO,CAAC,GAAGV,EAAQ,OAAO,CAAC;AAC7B;AAGA,SAAgBI,EAAY,GAAqB;CAC/C,IAAMO,IAAO,IAAI,IAAIR,EAAI,OAAO;CAChC,IAAIQ,EAAK,SAASR,EAAI,QAAQ,QAAQ,MAAU,MAAM,GAAGA,EAAI,GAAG,yBAAyB;CACzF,IAAMS,oBAAO,IAAI,IAAY,GACvBC,KAAQ,GAAW,MAAgB;EACvC,IAAI,CAACF,EAAK,IAAIG,CAAC,GAAG,MAAU,MAAM,GAAGX,EAAI,GAAG,UAAUY,EAAI,yBAAyBD,EAAE,EAAE;CACzF;CACA,KAAK,IAAME,KAAKb,EAAI,OAAO;EACzB,IAAIS,EAAK,IAAII,EAAE,GAAG,GAAG,MAAU,MAAM,GAAGb,EAAI,GAAG,wBAAwBa,EAAE,IAAI,EAAE;EAE/E,QADAJ,EAAK,IAAII,EAAE,GAAG,GACNA,EAAE,MAAV;GACE,KAAK;IAA4B,AAApBH,EAAKG,EAAE,KAAKA,EAAE,GAAG,GAAOA,EAAE,WAASH,EAAKG,EAAE,QAAQ,KAAKA,EAAE,GAAG;IAAG;GAC5E,KAAK;GAAa,KAAK;GAAQ,KAAK;GAAW,KAAK;GAAY,KAAK;IAAW,EAAKA,EAAE,KAAKA,EAAE,GAAG;IAAG;GACpG,KAAK;IAA8B,AAAtBH,EAAKG,EAAE,OAAOA,EAAE,GAAG,GAAGH,EAAKG,EAAE,OAAOA,EAAE,GAAG;IAAG;GACzD,KAAK;IAA0B,AAAlBH,EAAKG,EAAE,GAAGA,EAAE,GAAG,GAAGH,EAAKG,EAAE,GAAGA,EAAE,GAAG;IAAG;GACjD,KAAK,UAAgC,AAAtBH,EAAKG,EAAE,OAAOA,EAAE,GAAG,GAAGH,EAAKG,EAAE,MAAMA,EAAE,GAAG;EAEzD;CACF;AACF"}
@@ -0,0 +1,237 @@
1
+ import { _ as e, h as t } from "./define-XUgQMhSl.js";
2
+ //#region src/engine/study.ts
3
+ function n(e, t = {}) {
4
+ let n = {}, i = new Set(e.inputs.map((e) => e.key));
5
+ for (let n of Object.keys(t)) if (!i.has(n)) throw RangeError(`${e.id}: unknown input "${n}" (known: ${[...i].join(", ") || "none"})`);
6
+ for (let i of e.inputs) {
7
+ let a = t[i.key] ?? i.default;
8
+ r(e.id, i, a), n[i.key] = a;
9
+ }
10
+ return n;
11
+ }
12
+ function r(t, n, r) {
13
+ let i = `${t}.${n.key}`;
14
+ switch (n.type) {
15
+ case "int":
16
+ case "float":
17
+ if (typeof r != "number" || !Number.isFinite(r)) throw TypeError(`${i}: expected a finite number, got ${String(r)}`);
18
+ if (n.type === "int" && !Number.isInteger(r)) throw RangeError(`${i}: expected an integer, got ${r}`);
19
+ if (n.min !== void 0 && r < n.min) throw RangeError(`${i}: ${r} is below the minimum ${n.min}`);
20
+ if (n.max !== void 0 && r > n.max) throw RangeError(`${i}: ${r} is above the maximum ${n.max}`);
21
+ return;
22
+ case "bool":
23
+ if (typeof r != "boolean") throw TypeError(`${i}: expected a boolean, got ${String(r)}`);
24
+ return;
25
+ case "source":
26
+ case "select": {
27
+ let t = n.type === "source" ? n.options ?? e : n.options;
28
+ if (typeof r != "string" || !t?.includes(r)) throw RangeError(`${i}: "${String(r)}" is not one of ${t?.join(", ") ?? "(none)"}`);
29
+ }
30
+ }
31
+ }
32
+ var i = class {
33
+ def;
34
+ graph;
35
+ outputs;
36
+ params;
37
+ constructor(e, r = {}) {
38
+ if (this.def = e, this.params = n(e, r), this.graph = new t(), this.outputs = e.build(this.graph, this.params), this.outputs.length !== e.columns.length) throw Error(`${e.id}: build returned ${this.outputs.length} columns, declared ${e.columns.length}`);
39
+ }
40
+ get length() {
41
+ return this.graph.n;
42
+ }
43
+ load(e) {
44
+ let t = this.graph, n = e.time.length;
45
+ this.requireColumns(e), t.clear(), t.reserve(n), t.time.v.set(e.time), t.close.v.set(e.close), e.open && t.open.v.set(e.open), e.high && t.high.v.set(e.high), e.low && t.low.v.set(e.low), e.volume && t.volume.v.set(e.volume), t.n = n, t.run(0, n);
46
+ }
47
+ async loadChunked(e, t, n, r) {
48
+ let i = this.graph, a = e.time.length;
49
+ this.requireColumns(e), i.clear(), i.reserve(a), i.time.v.set(e.time), i.close.v.set(e.close), e.open && i.open.v.set(e.open), e.high && i.high.v.set(e.high), e.low && i.low.v.set(e.low), e.volume && i.volume.v.set(e.volume), i.n = a;
50
+ for (let e = 0; e < a; e += t) {
51
+ if (r()) return !1;
52
+ i.run(e, Math.min(a, e + t)), await n();
53
+ }
54
+ return !r();
55
+ }
56
+ setFeed(e, t, n) {
57
+ this.graph.feed(e).load(t, n, `outside series ${e}`);
58
+ }
59
+ pushFeed(e, t) {
60
+ let n = this.graph.feeds.get(e);
61
+ if (!n) throw RangeError(`${this.def.id}: no outside series "${e}"`);
62
+ let r = this.graph.n, i = r > 0 ? this.graph.time.v[r - 1] : NaN, a = r > 0 ? n.lookup(i) : -1, o = n.apply(t, `outside series ${e}`);
63
+ if (r === 0) return !1;
64
+ let s = n.lookup(i), c = s !== a || s >= 0 && s === n.n - 1 && o === "revised";
65
+ return c && this.graph.run(r - 1, r), c;
66
+ }
67
+ push(e) {
68
+ let t = this.graph, n = t.n;
69
+ if (n > 0 && !(e.time > t.time.v[n - 1])) throw RangeError(`push: time ${e.time} is not after the last bar ${t.time.v[n - 1]}`);
70
+ t.reserve(n + 1), this.write(n, e), t.n = n + 1, t.run(n, n + 1);
71
+ }
72
+ reviseLast(e) {
73
+ let t = this.graph, n = t.n - 1;
74
+ if (n < 0) throw RangeError("reviseLast: no bars");
75
+ if (e.time !== t.time.v[n]) throw RangeError(`reviseLast: time ${e.time} differs from the last bar ${t.time.v[n]}`);
76
+ this.write(n, e), t.run(n, n + 1);
77
+ }
78
+ column(e) {
79
+ return this.outputs[e].v.subarray(0, this.graph.n);
80
+ }
81
+ write(e, t) {
82
+ let n = this.graph;
83
+ n.time.v[e] = t.time, n.open.v[e] = t.open, n.high.v[e] = t.high, n.low.v[e] = t.low, n.close.v[e] = t.close, n.volume.v[e] = t.volume;
84
+ }
85
+ requireColumns(e) {
86
+ let t = e.time.length, n = this.def.needs, r = (e, n) => {
87
+ if (!n) throw TypeError(`${this.def.id} needs ${e} bars`);
88
+ if (n.length !== t) throw RangeError(`${this.def.id}: ${e} has ${n.length} rows, time has ${t}`);
89
+ };
90
+ if (r("close", e.close), n !== "value") for (let t of [
91
+ "open",
92
+ "high",
93
+ "low"
94
+ ]) r(t, e[t]);
95
+ n === "ohlcv" && r("volume", e.volume);
96
+ }
97
+ };
98
+ function a(e, t, n) {
99
+ let r = new i(e, t);
100
+ return r.load(n), r.outputs.map((e) => e.v.slice(0, r.length));
101
+ }
102
+ //#endregion
103
+ //#region src/runner.ts
104
+ var o = 65536, s = class extends Error {
105
+ constructor() {
106
+ super("study run cancelled"), this.name = "CancelledError";
107
+ }
108
+ }, c = () => new Promise((e) => setTimeout(e, 0)), l = class {
109
+ canRun() {
110
+ return !0;
111
+ }
112
+ run(e, t) {
113
+ let n = !1;
114
+ return {
115
+ promise: (async () => {
116
+ let r = new i(e, t.params);
117
+ for (let [e, n] of Object.entries(t.feeds ?? {})) r.setFeed(e, n.bars, n);
118
+ if (!await r.loadChunked(t.bars, 65536, c, () => n)) throw new s();
119
+ return {
120
+ n: r.length,
121
+ buffers: r.graph.cols.map((e) => e.v)
122
+ };
123
+ })(),
124
+ cancel: () => void (n = !0)
125
+ };
126
+ }
127
+ dispose() {}
128
+ }, u = class {
129
+ worker;
130
+ isBuiltin;
131
+ nextId = 1;
132
+ dead = null;
133
+ pending = /* @__PURE__ */ new Map();
134
+ constructor(e, t) {
135
+ this.worker = e, this.isBuiltin = t, e.addEventListener("message", (e) => {
136
+ let t = e.data, n = this.pending.get(t.id);
137
+ n && (this.pending.delete(t.id), t.type === "result" ? n.resolve({
138
+ n: t.n,
139
+ buffers: t.buffers
140
+ }) : t.type === "cancelled" ? n.reject(new s()) : n.reject(/* @__PURE__ */ Error(`study worker: ${t.message}`)));
141
+ }), e.addEventListener("error", (e) => {
142
+ let t = /* @__PURE__ */ Error(`study worker failed: ${e.message ?? "unknown error"}`);
143
+ this.dead = t;
144
+ for (let e of this.pending.values()) e.reject(t);
145
+ this.pending.clear();
146
+ });
147
+ }
148
+ canRun(e) {
149
+ return this.isBuiltin(e);
150
+ }
151
+ run(e, t) {
152
+ if (this.dead) return {
153
+ promise: Promise.reject(this.dead),
154
+ cancel: () => {}
155
+ };
156
+ let n = this.nextId++;
157
+ return {
158
+ promise: new Promise((r, i) => {
159
+ this.pending.set(n, {
160
+ resolve: r,
161
+ reject: i
162
+ });
163
+ let a = t.bars, o = [
164
+ a.time,
165
+ a.close,
166
+ a.open,
167
+ a.high,
168
+ a.low,
169
+ a.volume
170
+ ].filter((e) => !!e).map((e) => e.buffer);
171
+ this.worker.postMessage({
172
+ type: "run",
173
+ id: n,
174
+ studyId: e.id,
175
+ params: t.params,
176
+ bars: a
177
+ }, o);
178
+ }),
179
+ cancel: () => this.worker.postMessage({
180
+ type: "cancel",
181
+ id: n
182
+ })
183
+ };
184
+ }
185
+ dispose() {
186
+ this.worker.terminate();
187
+ let e = new s();
188
+ for (let t of this.pending.values()) t.reject(e);
189
+ this.pending.clear();
190
+ }
191
+ };
192
+ function d(e, t) {
193
+ let n = /* @__PURE__ */ new Set();
194
+ return (r) => {
195
+ let a = r;
196
+ a.type === "cancel" ? n.add(a.id) : a.type === "run" && (async () => {
197
+ try {
198
+ let r = t(a.studyId);
199
+ if (!r) throw Error(`unknown study "${a.studyId}"`);
200
+ let o = new i(r, a.params ?? {});
201
+ if (!await o.loadChunked(a.bars, 65536, c, () => n.has(a.id))) {
202
+ e({
203
+ type: "cancelled",
204
+ id: a.id
205
+ });
206
+ return;
207
+ }
208
+ let s = o.graph.cols.map((e) => e.v);
209
+ e({
210
+ type: "result",
211
+ id: a.id,
212
+ n: o.length,
213
+ buffers: s
214
+ }, s.map((e) => e.buffer));
215
+ } catch (t) {
216
+ e({
217
+ type: "error",
218
+ id: a.id,
219
+ message: t instanceof Error ? t.message : String(t)
220
+ });
221
+ } finally {
222
+ n.delete(a.id);
223
+ }
224
+ })();
225
+ };
226
+ }
227
+ function f(e, t) {
228
+ try {
229
+ return t ? new u(t(), (t) => e.has(t.id)) : new l();
230
+ } catch {
231
+ return new l();
232
+ }
233
+ }
234
+ //#endregion
235
+ export { f as a, n as c, u as i, a as l, s as n, d as o, l as r, i as s, o as t };
236
+
237
+ //# sourceMappingURL=runner-B53M0IsJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-B53M0IsJ.js","names":["SOURCE_NAMES","Graph","resolveParams","out","known","def","i","k","given","inp","v","checkInput","where","id","opts","StudyEngine","params","g","d","n","a","chunk","cancelled","pause","key","bars","cfg","f","t","before","change","bar","after","affected","b","need","chk","name","runStudy","e","c","CHUNK","CancelledError","yieldNow","r","InlineRunner","req","WorkerRunner","worker","isBuiltin","m","p","err","transfer","serveWorker","data","find","buffers","createRunner","factory","builtinIds"],"sources":["../src/engine/study.ts","../src/runner.ts"],"sourcesContent":["// Running a study definition: parameter validation, the streaming engine and\n// the one-shot batch function the worker uses.\n\nimport { Graph, SOURCE_NAMES, type Col } from \"./graph.js\";\nimport type { BarColumns, BarInput, InputDef, InputValue, Params, StudyDef } from \"../types.js\";\nimport type { FeedBar, FeedConfig, FeedBars } from \"./feed.js\";\n\n/** Validate `given` against the study's inputs and fill defaults. Throws on anything unknown or out of range. */\nexport function resolveParams(def: StudyDef, given: Readonly<Record<string, InputValue>> = {}): Params {\n const out: Record<string, InputValue> = {};\n const known = new Set(def.inputs.map((i) => i.key));\n for (const k of Object.keys(given)) if (!known.has(k)) throw new RangeError(`${def.id}: unknown input \"${k}\" (known: ${[...known].join(\", \") || \"none\"})`);\n for (const inp of def.inputs) {\n const v = given[inp.key] ?? inp.default;\n checkInput(def.id, inp, v);\n out[inp.key] = v;\n }\n return out;\n}\n\nfunction checkInput(id: string, inp: InputDef, v: InputValue): void {\n const where = `${id}.${inp.key}`;\n switch (inp.type) {\n case \"int\":\n case \"float\": {\n if (typeof v !== \"number\" || !Number.isFinite(v)) throw new TypeError(`${where}: expected a finite number, got ${String(v)}`);\n if (inp.type === \"int\" && !Number.isInteger(v)) throw new RangeError(`${where}: expected an integer, got ${v}`);\n if (inp.min !== undefined && v < inp.min) throw new RangeError(`${where}: ${v} is below the minimum ${inp.min}`);\n if (inp.max !== undefined && v > inp.max) throw new RangeError(`${where}: ${v} is above the maximum ${inp.max}`);\n return;\n }\n case \"bool\":\n if (typeof v !== \"boolean\") throw new TypeError(`${where}: expected a boolean, got ${String(v)}`);\n return;\n case \"source\":\n case \"select\": {\n const opts = inp.type === \"source\" ? (inp.options ?? SOURCE_NAMES) : inp.options;\n if (typeof v !== \"string\" || !opts?.includes(v)) throw new RangeError(`${where}: \"${String(v)}\" is not one of ${opts?.join(\", \") ?? \"(none)\"}`);\n }\n }\n}\n\n/** A study bound to parameters and a graph: appends, revises and batch-loads bars. */\nexport class StudyEngine {\n readonly graph: Graph;\n readonly outputs: readonly Col[];\n readonly params: Params;\n\n constructor(readonly def: StudyDef, params: Readonly<Record<string, InputValue>> = {}) {\n this.params = resolveParams(def, params);\n this.graph = new Graph();\n this.outputs = def.build(this.graph, this.params);\n if (this.outputs.length !== def.columns.length) throw new Error(`${def.id}: build returned ${this.outputs.length} columns, declared ${def.columns.length}`);\n }\n\n get length(): number {\n return this.graph.n;\n }\n\n /** Replace all bars and compute. */\n load(d: BarColumns): void {\n const g = this.graph;\n const n = d.time.length;\n this.requireColumns(d);\n g.clear();\n g.reserve(n);\n g.time.v.set(d.time);\n g.close.v.set(d.close);\n if (d.open) g.open.v.set(d.open);\n if (d.high) g.high.v.set(d.high);\n if (d.low) g.low.v.set(d.low);\n if (d.volume) g.volume.v.set(d.volume);\n g.n = n;\n g.run(0, n);\n }\n\n /**\n * Like `load`, but evaluates in chunks of `chunk` bars and awaits `pause()`\n * between them, so a runner can service cancel messages. Stops quietly and\n * returns false when `cancelled()` turns true.\n */\n async loadChunked(d: BarColumns, chunk: number, pause: () => Promise<void>, cancelled: () => boolean): Promise<boolean> {\n const g = this.graph;\n const n = d.time.length;\n this.requireColumns(d);\n g.clear();\n g.reserve(n);\n g.time.v.set(d.time);\n g.close.v.set(d.close);\n if (d.open) g.open.v.set(d.open);\n if (d.high) g.high.v.set(d.high);\n if (d.low) g.low.v.set(d.low);\n if (d.volume) g.volume.v.set(d.volume);\n g.n = n;\n for (let a = 0; a < n; a += chunk) {\n if (cancelled()) return false;\n g.run(a, Math.min(n, a + chunk));\n await pause();\n }\n return !cancelled();\n }\n\n /** Give the study outside series `key`: bars in their own time and how to join them (copied). Run the study again afterwards. */\n setFeed(key: string, bars: FeedBars, cfg: FeedConfig): void {\n this.graph.feed(key).load(bars, cfg, `outside series ${key}`);\n }\n\n /**\n * A live bar of outside series `key`: the feed's last bar is replaced or one is appended, and what the study computed\n * on the feed's bars follows. When the study's last bar now sees a different feed row (or the same one revised), that\n * bar is evaluated again and `true` is returned; otherwise nothing of the study is recomputed. O(1) amortised.\n */\n pushFeed(key: string, bar: FeedBar): boolean {\n const f = this.graph.feeds.get(key);\n if (!f) throw new RangeError(`${this.def.id}: no outside series \"${key}\"`);\n const n = this.graph.n;\n const t = n > 0 ? this.graph.time.v[n - 1]! : Number.NaN;\n const before = n > 0 ? f.lookup(t) : -1;\n const change = f.apply(bar, `outside series ${key}`);\n if (n === 0) return false;\n const after = f.lookup(t);\n const affected = after !== before || (after >= 0 && after === f.n - 1 && change === \"revised\");\n if (affected) this.graph.run(n - 1, n);\n return affected;\n }\n\n /** Append a bar (time later than the last). */\n push(b: BarInput): void {\n const g = this.graph;\n const i = g.n;\n if (i > 0 && !(b.time > g.time.v[i - 1]!)) throw new RangeError(`push: time ${b.time} is not after the last bar ${g.time.v[i - 1]}`);\n g.reserve(i + 1);\n this.write(i, b);\n g.n = i + 1;\n g.run(i, i + 1);\n }\n\n /** Replace the last bar (a tick revision). */\n reviseLast(b: BarInput): void {\n const g = this.graph;\n const i = g.n - 1;\n if (i < 0) throw new RangeError(\"reviseLast: no bars\");\n if (b.time !== g.time.v[i]) throw new RangeError(`reviseLast: time ${b.time} differs from the last bar ${g.time.v[i]}`);\n this.write(i, b);\n g.run(i, i + 1);\n }\n\n /** Output column `k` as a view over the bars loaded (valid until the next push that grows the graph). */\n column(k: number): Float64Array {\n return this.outputs[k]!.v.subarray(0, this.graph.n);\n }\n\n private write(i: number, b: BarInput): void {\n const g = this.graph;\n g.time.v[i] = b.time;\n g.open.v[i] = b.open;\n g.high.v[i] = b.high;\n g.low.v[i] = b.low;\n g.close.v[i] = b.close;\n g.volume.v[i] = b.volume;\n }\n\n private requireColumns(d: BarColumns): void {\n const n = d.time.length;\n const need = this.def.needs;\n const chk = (name: string, a: Float64Array | undefined) => {\n if (!a) throw new TypeError(`${this.def.id} needs ${name} bars`);\n if (a.length !== n) throw new RangeError(`${this.def.id}: ${name} has ${a.length} rows, time has ${n}`);\n };\n chk(\"close\", d.close);\n if (need !== \"value\") for (const k of [\"open\", \"high\", \"low\"] as const) chk(k, d[k]);\n if (need === \"ohlcv\") chk(\"volume\", d.volume);\n }\n}\n\n/** One-shot: run a study over columns and return its output columns (copies, length n). */\nexport function runStudy(def: StudyDef, params: Readonly<Record<string, InputValue>>, d: BarColumns): Float64Array[] {\n const e = new StudyEngine(def, params);\n e.load(d);\n return e.outputs.map((c) => c.v.slice(0, e.length));\n}\n","// Running a study's batch computation off the UI thread.\n//\n// Protocol (structured clone; the arrays are transferred, never copied):\n// main -> worker { type: \"run\", id, studyId, params, bars } bars: BarColumns\n// { type: \"cancel\", id }\n// worker -> main { type: \"result\", id, n, buffers } every graph column, in registration order\n// { type: \"cancelled\", id }\n// { type: \"error\", id, message }\n// The worker evaluates in chunks and yields between them, so a cancel message\n// is serviced within one chunk. Only built-in studies (looked up by id in the\n// worker's own registry) run in a worker; a study defined at runtime does not\n// exist there, so `createRunner` callers use InlineRunner for it (`canRun`).\n\nimport type { FeedBar, FeedData } from \"./engine/feed.js\";\nimport { StudyEngine } from \"./engine/study.js\";\nimport type { BarColumns, InputValue, StudyDef } from \"./types.js\";\n\nexport const CHUNK = 1 << 16;\n\nexport interface RunRequest {\n studyId: string;\n params: Readonly<Record<string, InputValue>>;\n /** Transferred to the runner when it is a worker: do not use afterwards. */\n bars: BarColumns;\n /** Outside series by key, each a copy the runner may keep or transfer. Only a runner that can run a study that reads them (a script) uses them. */\n feeds?: Record<string, FeedData>;\n}\n\nexport interface RunResult {\n n: number;\n /** All graph columns (inputs, state, outputs), in registration order. */\n buffers: Float64Array[];\n}\n\nexport class CancelledError extends Error {\n constructor() {\n super(\"study run cancelled\");\n this.name = \"CancelledError\";\n }\n}\n\nexport interface StudyRunner {\n /** Whether this runner can evaluate `def` (a worker only knows built-ins). */\n canRun(def: StudyDef): boolean;\n /** Rejects with CancelledError when `cancel(handle)` is called first. */\n run(def: StudyDef, req: RunRequest): { promise: Promise<RunResult>; cancel(): void };\n /**\n * A live bar of outside series `key` for a study this runner holds state for; the runner answers through the channel\n * its ticks use. Optional: a runner that keeps no per-study state (every batch starts afresh) does not have it.\n */\n feedBar?(def: StudyDef, key: string, bar: FeedBar): void;\n dispose(): void;\n}\n\nconst yieldNow = (): Promise<void> => new Promise((r) => setTimeout(r, 0));\n\n/** Main-thread fallback: same chunked evaluation, same cancellation. */\nexport class InlineRunner implements StudyRunner {\n canRun(): boolean {\n return true;\n }\n run(def: StudyDef, req: RunRequest) {\n let cancelled = false;\n const promise = (async (): Promise<RunResult> => {\n const e = new StudyEngine(def, req.params);\n for (const [key, f] of Object.entries(req.feeds ?? {})) e.setFeed(key, f.bars, f);\n const done = await e.loadChunked(req.bars, CHUNK, yieldNow, () => cancelled);\n if (!done) throw new CancelledError();\n return { n: e.length, buffers: e.graph.cols.map((c) => c.v) };\n })();\n return { promise, cancel: () => void (cancelled = true) };\n }\n dispose(): void {}\n}\n\nexport interface WorkerLike {\n postMessage(msg: unknown, transfer?: Transferable[]): void;\n addEventListener(type: \"message\", fn: (e: { data: unknown }) => void): void;\n addEventListener(type: \"error\", fn: (e: { message?: string }) => void): void;\n terminate(): void;\n}\n\ntype WorkerReply =\n | { type: \"result\"; id: number; n: number; buffers: Float64Array[] }\n | { type: \"cancelled\"; id: number }\n | { type: \"error\"; id: number; message: string };\n\n/** Runs built-in studies in a Web Worker. `isBuiltin` says which ids the worker knows. */\nexport class WorkerRunner implements StudyRunner {\n private nextId = 1;\n /** Set once the worker has failed: later runs reject at once instead of waiting on a dead worker. */\n private dead: Error | null = null;\n private readonly pending = new Map<number, { resolve(r: RunResult): void; reject(e: Error): void }>();\n\n constructor(private readonly worker: WorkerLike, private readonly isBuiltin: (def: StudyDef) => boolean) {\n worker.addEventListener(\"message\", (e) => {\n const m = e.data as WorkerReply;\n const p = this.pending.get(m.id);\n if (!p) return;\n this.pending.delete(m.id);\n if (m.type === \"result\") p.resolve({ n: m.n, buffers: m.buffers });\n else if (m.type === \"cancelled\") p.reject(new CancelledError());\n else p.reject(new Error(`study worker: ${m.message}`));\n });\n worker.addEventListener(\"error\", (e) => {\n const err = new Error(`study worker failed: ${e.message ?? \"unknown error\"}`);\n this.dead = err;\n for (const p of this.pending.values()) p.reject(err);\n this.pending.clear();\n });\n }\n\n canRun(def: StudyDef): boolean {\n return this.isBuiltin(def);\n }\n\n run(def: StudyDef, req: RunRequest) {\n if (this.dead) return { promise: Promise.reject(this.dead), cancel: () => {} };\n const id = this.nextId++;\n const promise = new Promise<RunResult>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n const b = req.bars;\n const transfer = [b.time, b.close, b.open, b.high, b.low, b.volume].filter((a): a is Float64Array => !!a).map((a) => a.buffer);\n this.worker.postMessage({ type: \"run\", id, studyId: def.id, params: req.params, bars: b }, transfer);\n });\n return { promise, cancel: () => this.worker.postMessage({ type: \"cancel\", id }) };\n }\n\n dispose(): void {\n this.worker.terminate();\n const err = new CancelledError();\n for (const p of this.pending.values()) p.reject(err);\n this.pending.clear();\n }\n}\n\n/** Worker-side message handler: wire it to `self.onmessage` (see worker.ts). */\nexport function serveWorker(\n post: (msg: WorkerReply, transfer?: Transferable[]) => void,\n find: (id: string) => StudyDef | undefined,\n): (data: unknown) => void {\n const cancelled = new Set<number>();\n return (data) => {\n const m = data as { type: string; id: number; studyId?: string; params?: Record<string, InputValue>; bars?: BarColumns };\n if (m.type === \"cancel\") {\n cancelled.add(m.id);\n return;\n }\n if (m.type !== \"run\") return;\n void (async () => {\n try {\n const def = find(m.studyId!);\n if (!def) throw new Error(`unknown study \"${m.studyId}\"`);\n const e = new StudyEngine(def, m.params ?? {});\n const done = await e.loadChunked(m.bars!, CHUNK, yieldNow, () => cancelled.has(m.id));\n if (!done) {\n post({ type: \"cancelled\", id: m.id });\n return;\n }\n const buffers = e.graph.cols.map((c) => c.v);\n post({ type: \"result\", id: m.id, n: e.length, buffers }, buffers.map((b) => b.buffer));\n } catch (err) {\n post({ type: \"error\", id: m.id, message: err instanceof Error ? err.message : String(err) });\n } finally {\n cancelled.delete(m.id);\n }\n })();\n };\n}\n\n/**\n * A worker runner on the worker `factory` creates, otherwise (no factory, or the worker would not start) the inline fallback.\n * The package never guesses where its worker lives: the host's bundler spells the URL out,\n * `() => new Worker(new URL(\"@alphacharts/indicators/worker\", import.meta.url), { type: \"module\" })`.\n */\nexport function createRunner(builtinIds: ReadonlySet<string>, factory?: () => WorkerLike): StudyRunner {\n try {\n if (!factory) return new InlineRunner();\n return new WorkerRunner(factory(), (d) => builtinIds.has(d.id));\n } catch {\n return new InlineRunner();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { g as accelerator, xn as acos, pr as ad, Sn as add, mr as adosc, t as adr, _r as adx, vr as adxr, F as alligator, I as alma, n as anchoredVwap, yr as apo, br as aroon, xr as aroonosc, Cn as asin, wn as atan, lr as atr, ir as avgprice, _ as awesome, r as barsPerYear, Jr as bbands, Yr as bbpb, Xr as bbw, Jn as beta, Sr as bop, v as bullBearPower, Cr as cci, nt as cdl2Crows, rt as cdl3BlackCrows, it as cdl3Inside, at as cdl3LineStrike, ot as cdl3Outside, st as cdl3StarsInSouth, ct as cdl3WhiteSoldiers, lt as cdlAbandonedBaby, ut as cdlAdvanceBlock, dt as cdlBeltHold, ft as cdlBreakaway, pt as cdlClosingMarubozu, mt as cdlConcealBabySwall, ht as cdlCounterAttack, gt as cdlDarkCloudCover, _t as cdlDoji, vt as cdlDojiStar, yt as cdlDragonflyDoji, bt as cdlEngulfing, xt as cdlEveningDojiStar, St as cdlEveningStar, Ct as cdlGapSideSideWhite, wt as cdlGravestoneDoji, Tt as cdlHammer, Et as cdlHangingMan, Dt as cdlHarami, Ot as cdlHaramiCross, kt as cdlHighWave, At as cdlHikkake, jt as cdlHikkakeMod, Mt as cdlHomingPigeon, Nt as cdlIdentical3Crows, Pt as cdlInNeck, Ft as cdlInvertedHammer, It as cdlKicking, Lt as cdlKickingByLength, Rt as cdlLadderBottom, zt as cdlLongLeggedDoji, Bt as cdlLongLine, Vt as cdlMarubozu, Ht as cdlMatHold, Ut as cdlMatchingLow, Wt as cdlMorningDojiStar, Gt as cdlMorningStar, Kt as cdlOnNeck, qt as cdlPiercing, Jt as cdlRickshawMan, Yt as cdlRiseFall3Methods, Xt as cdlSeparatingLines, Zt as cdlShootingStar, Qt as cdlShortLine, $t as cdlSpinningTop, en as cdlStalledPattern, tn as cdlStickSandwich, nn as cdlTakuri, rn as cdlTasukiGap, in as cdlThrusting, an as cdlTriStar, on as cdlUnique3River, sn as cdlUpsideGap2Crows, cn as cdlXSideGap3Methods, Tn as ceil, i as chaikinMf, L as chandeKrollStop, y as choppiness, wr as cmo, b as connorsRsi, x as coppock, Yn as correl, En as cos, Dn as cosh, Zr as dema, On as div, R as donchian, S as dpo, Tr as dx, a as elderForce, Qr as ema, z as envelopes, o as eom, kn as exp, C as fisher, An as floor, B as fractals, s as histVol, V as hma, mn as htDcPeriod, hn as htDcPhase, gn as htPhasor, _n as htSine, vn as htTrendMode, yn as htTrendline, H as ichimoku, $r as kama, U as keltner, c as klinger, w as kst, Xn as linearreg, Zn as linearregAngle, Qn as linearregIntercept, $n as linearregSlope, W as linregChannel, jn as ln, Mn as log10, G as lsma, ei as ma, K as maCross, q as maRibbon, Er as macd, Dr as macdext, Or as macdfix, bn as mama, T as massIndex, Pn as max, Fn as maxindex, J as mcginley, Y as median, ar as medprice, kr as mfi, ti as midpoint, ni as midprice, In as min, Ln as minindex, Rn as minmax, zn as minmaxindex, Ar as minusDi, jr as minusDm, Mr as mom, Bn as mult, ur as natr, l as netVolume, hr as obv, u as pivotPoints, Pr as plusDi, Fr as plusDm, Ir as ppo, X as priceChannel, d as pvt, E as rankCorr, Lr as roc, Rr as rocp, zr as rocr, Br as rocr100, Vr as rsi, D as rviVigor, O as rviVolatility, un as sar, fn as sarext, k as schaffTc, Vn as sin, Hn as sinh, ii as sma, A as smiErgodic, Z as smma, Un as sqrt, tr as stddev, Hr as stoch, j as stochTv, Ur as stochf, Wr as stochrsi, Wn as sub, Gn as sum, Q as supertrend, ai as t3, Kn as tan, qn as tanh, oi as tema, dr as trange, si as trima, Gr as trix, nr as tsf, M as tsi, sr as typprice, Kr as ultosc, rr as variance, p as volume, m as volumeOsc, P as vortex, h as vwap, et as vwma, cr as wclprice, qr as willr, ci as wma, tt as zigzag } from "./tv-volume-BYSbfrVk.js";