@alphacharts/script 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,342 @@
1
+ import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as f, u as p } from "./sandbox-p2HPP8yl.js";
2
+ import { CancelledError as m, addStudy as h } from "@alphacharts/indicators";
3
+ //#region src/runner.ts
4
+ var g = (e) => new l(e.message, e.from === void 0 ? null : {
5
+ from: e.from,
6
+ to: e.to ?? e.from
7
+ }, e.kind === "compile" ? "build" : e.kind), _ = class {
8
+ factory;
9
+ worker = null;
10
+ nextId = 1;
11
+ nextSid = 1;
12
+ infos = /* @__PURE__ */ new WeakMap();
13
+ pending = /* @__PURE__ */ new Map();
14
+ listeners = /* @__PURE__ */ new Map();
15
+ tickTimers = /* @__PURE__ */ new Map();
16
+ dead = /* @__PURE__ */ new Set();
17
+ limits;
18
+ disposed = !1;
19
+ constructor(e, t = {}) {
20
+ this.factory = e, this.limits = {
21
+ ...n,
22
+ ...t
23
+ };
24
+ }
25
+ setLimits(e) {
26
+ this.limits = {
27
+ ...this.limits,
28
+ ...e
29
+ };
30
+ }
31
+ attach(e, t, n) {
32
+ let r = this.nextSid++;
33
+ return this.infos.set(e, {
34
+ sid: r,
35
+ source: t
36
+ }), this.listeners.set(r, n), r;
37
+ }
38
+ detach(e) {
39
+ this.listeners.delete(e), this.dead.delete(e), this.clearTick(e), this.post({
40
+ type: "dispose",
41
+ sid: e
42
+ });
43
+ }
44
+ canRun(e) {
45
+ return this.infos.has(e);
46
+ }
47
+ ensure() {
48
+ if (this.disposed) throw new l("the script runner was disposed");
49
+ if (!this.worker) {
50
+ let e = this.factory();
51
+ e.addEventListener("message", (e) => this.onMessage(e.data)), e.addEventListener("error", (e) => this.fail(new l(`script worker failed: ${e.message ?? "unknown error"}`, null, "runtime"))), this.worker = e;
52
+ }
53
+ return this.worker;
54
+ }
55
+ post(e, t = []) {
56
+ this.disposed || (e.type !== "dispose" || this.worker) && this.ensure().postMessage(e, t);
57
+ }
58
+ run(e, t) {
59
+ let n = this.infos.get(e);
60
+ if (!n) return {
61
+ promise: Promise.reject(new l("not a script study")),
62
+ cancel: () => {}
63
+ };
64
+ let r = this.nextId++;
65
+ this.dead.delete(n.sid);
66
+ let i = t.bars;
67
+ return {
68
+ promise: new Promise((e, a) => {
69
+ let o = setTimeout(() => this.timeout(r, `the script did not finish within ${this.limits.batchMs} ms and was terminated`), this.limits.batchMs);
70
+ this.pending.set(r, {
71
+ resolve: e,
72
+ reject: a,
73
+ timer: o
74
+ });
75
+ let s = Object.values(t.feeds ?? {}).flatMap((e) => [
76
+ e.bars.time,
77
+ e.bars.open,
78
+ e.bars.high,
79
+ e.bars.low,
80
+ e.bars.close,
81
+ e.bars.volume
82
+ ]), c = [
83
+ i.time,
84
+ i.close,
85
+ i.open,
86
+ i.high,
87
+ i.low,
88
+ i.volume,
89
+ ...s
90
+ ].filter((e) => !!e).map((e) => e.buffer);
91
+ try {
92
+ this.post({
93
+ type: "run",
94
+ id: r,
95
+ sid: n.sid,
96
+ source: n.source,
97
+ params: t.params,
98
+ bars: i,
99
+ ...t.feeds && { feeds: t.feeds },
100
+ limits: this.limits
101
+ }, c);
102
+ } catch (e) {
103
+ clearTimeout(o), this.pending.delete(r), a(e instanceof Error ? e : Error(String(e)));
104
+ }
105
+ }),
106
+ cancel: () => {
107
+ this.post({
108
+ type: "cancel",
109
+ id: r
110
+ }), this.settle(r)?.reject(new m());
111
+ }
112
+ };
113
+ }
114
+ sendBar(e, t, n) {
115
+ this.listeners.has(e) && !this.dead.has(e) && (this.arm(e), this.post({
116
+ type: "bar",
117
+ sid: e,
118
+ index: t,
119
+ bar: n
120
+ }));
121
+ }
122
+ feedBar(e, t, n) {
123
+ let r = this.infos.get(e);
124
+ r && this.listeners.has(r.sid) && !this.dead.has(r.sid) && (this.arm(r.sid), this.post({
125
+ type: "feed-bar",
126
+ sid: r.sid,
127
+ key: t,
128
+ bar: n
129
+ }));
130
+ }
131
+ arm(e) {
132
+ !this.tickTimers.has(e) && this.pending.size === 0 && this.tickTimers.set(e, setTimeout(() => {
133
+ this.tickTimers.delete(e), this.terminateWorker(new l(`a tick took longer than ${this.limits.tickMs} ms; the script was terminated`, null, "budget"));
134
+ }, this.limits.tickMs));
135
+ }
136
+ clearTick(e) {
137
+ let t = this.tickTimers.get(e);
138
+ t !== void 0 && clearTimeout(t), this.tickTimers.delete(e);
139
+ }
140
+ settle(e) {
141
+ let t = this.pending.get(e);
142
+ if (t) return clearTimeout(t.timer), this.pending.delete(e), t;
143
+ }
144
+ onMessage(e) {
145
+ switch (e.type) {
146
+ case "result":
147
+ this.settle(e.id)?.resolve({
148
+ n: e.n,
149
+ buffers: e.buffers
150
+ });
151
+ return;
152
+ case "cancelled":
153
+ this.settle(e.id)?.reject(new m());
154
+ return;
155
+ case "error":
156
+ this.settle(e.id)?.reject(g(e.error));
157
+ return;
158
+ case "values":
159
+ this.clearTick(e.sid), this.listeners.get(e.sid)?.values(e.index, e.values);
160
+ return;
161
+ case "idle":
162
+ this.clearTick(e.sid);
163
+ return;
164
+ case "tick-error":
165
+ this.clearTick(e.sid), this.listeners.get(e.sid)?.error(g(e.error));
166
+ return;
167
+ }
168
+ }
169
+ timeout(e, t) {
170
+ let n = this.settle(e);
171
+ n && (n.reject(new l(t, null, "budget")), this.terminateWorker(new l(t, null, "budget")));
172
+ }
173
+ terminateWorker(e) {
174
+ this.worker?.terminate(), this.worker = null;
175
+ let t = e ?? new l("the script worker was terminated", null, "budget");
176
+ for (let e of [...this.pending.keys()]) this.settle(e)?.reject(t);
177
+ for (let e of this.tickTimers.values()) clearTimeout(e);
178
+ this.tickTimers.clear();
179
+ for (let [e, n] of this.listeners) this.dead.has(e) || (this.dead.add(e), n.error(t));
180
+ }
181
+ fail(e) {
182
+ this.terminateWorker(e);
183
+ }
184
+ dispose() {
185
+ this.terminateWorker(), this.disposed = !0, this.listeners.clear();
186
+ }
187
+ }, v = class extends Error {
188
+ diagnostics;
189
+ constructor(e) {
190
+ super(e.filter((e) => e.severity === "error").map((e) => `${e.line}:${e.column}: ${e.message}`).join("\n")), this.diagnostics = e, this.name = "ScriptDiagnosticsError";
191
+ }
192
+ }, y = 0;
193
+ function b(e, t) {
194
+ let n = new r(e), i = t instanceof l ? t : null, a = i?.span?.from ?? 0, o = i?.span?.to ?? 0, s = n.at(a), c = n.at(o);
195
+ return {
196
+ severity: "error",
197
+ message: t instanceof Error ? t.message : String(t),
198
+ line: s.line,
199
+ column: s.column,
200
+ endLine: c.line,
201
+ endColumn: c.column,
202
+ from: a,
203
+ to: o
204
+ };
205
+ }
206
+ function x(t, n, r, o, s) {
207
+ let l = e(r);
208
+ if (!l.ok) throw new v(l.diagnostics);
209
+ let u = !s.runner;
210
+ if (!s.runner && !s.workerFactory) throw Error("runScript needs a workerFactory or a runner: the package does not guess where its worker lives");
211
+ let d = s.runner ?? new _(s.workerFactory, s.limits), f = new Set(l.colorInputs.map((e) => e.key)), p = {}, m = {};
212
+ for (let [e, t] of Object.entries(o)) f.has(e) ? m[e] = String(t) : p[e] = t;
213
+ let g = a(l.plan.dependencies);
214
+ if (g.length > 0 && !(s.intervalMs > 0)) throw TypeError("this script reads outside series: pass options.intervalMs, the length of one bar of the chart, in milliseconds");
215
+ let x = new Map(g.map((e) => [e.key, e])), S = /* @__PURE__ */ new Set(), C = s.id ?? `script${++y}`, w = null, T = { error: null }, E = (e) => {
216
+ let t = b(r, e);
217
+ T.error = t, s.onError?.(t);
218
+ }, D = {
219
+ ...l.study,
220
+ id: `script:${C}`
221
+ }, O = 0, k = i(D, (e) => {
222
+ let t = A;
223
+ d.sendBar(O, e, {
224
+ time: t.time.v[e],
225
+ open: t.open.v[e],
226
+ high: t.high.v[e],
227
+ low: t.low.v[e],
228
+ close: t.close.v[e],
229
+ volume: t.volume.v[e]
230
+ });
231
+ }, !0), A = null, j = {
232
+ ...k,
233
+ build: (e, t) => (A = e, k.build(e, t))
234
+ };
235
+ O = d.attach(j, r, {
236
+ values(e, t) {
237
+ if (!w || w.disposed) return;
238
+ let n = j.columns, r = w.times().length;
239
+ e >= r || (n.forEach((n, r) => {
240
+ w.column(n)[e] = t[r];
241
+ }), w.refresh(e === r - 1));
242
+ },
243
+ error: E
244
+ });
245
+ let M = (e, t) => {
246
+ for (let n of l.colorInputs.find((t) => t.key === e).plotKeys) w.setStyle(n, { color: t });
247
+ };
248
+ w = h(t, n, j, p, {
249
+ runner: d,
250
+ id: C,
251
+ persist: !1,
252
+ ...s.volume && { volume: s.volume },
253
+ onDispose: () => {
254
+ d.detach(O), u && d.dispose();
255
+ }
256
+ });
257
+ for (let [e, t] of Object.entries(m)) M(e, t);
258
+ return w.ready().catch(E), {
259
+ study: w,
260
+ compiled: l,
261
+ feeds: g,
262
+ setSeries(e, t) {
263
+ let n = x.get(e);
264
+ if (!n) throw RangeError(`this script reads no outside series "${e}" (it reads: ${g.map((e) => JSON.stringify(e.key)).join(", ") || "none"})`);
265
+ w.setFeed(e, t, c(n.timeframe, s.intervalMs)), S.add(e), w.ready().catch(E);
266
+ },
267
+ pushSeries(e, t) {
268
+ if (!x.has(e)) throw RangeError(`this script reads no outside series "${e}"`);
269
+ S.has(e) && w.pushFeedBar(e, t);
270
+ },
271
+ get error() {
272
+ return T.error;
273
+ },
274
+ set error(e) {
275
+ T.error = e;
276
+ },
277
+ setInputs(e, t = []) {
278
+ let n = {};
279
+ for (let e of t) {
280
+ let t = l.colorInputs.find((t) => t.key === e);
281
+ t && (m[e] = t.default, M(e, t.default));
282
+ }
283
+ for (let [t, r] of Object.entries(e)) f.has(t) ? (m[t] = String(r), M(t, String(r))) : n[t] = r;
284
+ let r = t.filter((e) => !f.has(e));
285
+ (Object.keys(n).length > 0 || r.length > 0) && (T.error = null, w.setInputs(n, r), w.ready().catch(E));
286
+ },
287
+ remove() {
288
+ w.remove();
289
+ },
290
+ ready: () => w.ready(),
291
+ toJSON() {
292
+ return {
293
+ version: 1,
294
+ source: r,
295
+ inputs: {
296
+ ...w.inputs(),
297
+ ...m
298
+ },
299
+ series: n.options().id,
300
+ ...s.volume && { volume: s.volume.options().id },
301
+ visible: w.visible
302
+ };
303
+ }
304
+ };
305
+ }
306
+ function S(e, t, n) {
307
+ if (t?.version !== 1 || typeof t.source != "string") throw TypeError("unrecognised saved script");
308
+ let r = new Map(e.series().map((e) => [e.options().id, e])), i = r.get(t.series);
309
+ if (!i) throw Error(`the saved script needs series "${t.series}"`);
310
+ let a = t.volume ? r.get(t.volume) : void 0, o = x(e, i, t.source, t.inputs, {
311
+ ...n,
312
+ ...a && { volume: a }
313
+ });
314
+ return t.visible || o.study.setVisible(!1), o;
315
+ }
316
+ //#endregion
317
+ //#region src/ui-adapter.ts
318
+ function C(e) {
319
+ return { run(t, n, r) {
320
+ try {
321
+ let i = x(t.chart, t.source, n, {}, {
322
+ ...e,
323
+ ...t.volume ? { volume: t.volume } : {},
324
+ onError: r
325
+ });
326
+ return {
327
+ diagnostics: [],
328
+ remove: () => i.remove()
329
+ };
330
+ } catch (e) {
331
+ if (e instanceof v) return {
332
+ diagnostics: e.diagnostics,
333
+ remove: () => {}
334
+ };
335
+ throw e;
336
+ }
337
+ } };
338
+ }
339
+ //#endregion
340
+ export { f as BLOCKED_GLOBALS, n as DEFAULT_LIMITS, v as ScriptDiagnosticsError, l as ScriptError, _ as ScriptRunner, c as alignFor, e as compile, C as createScriptRunAdapter, d as describeJoin, t as feedKey, a as feedsOf, o as formatDiagnostic, s as lockdown, p as parseTimeframe, S as restoreScript, x as runScript, u as serveScripts };
341
+
342
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["compile","feedKey","DEFAULT_LIMITS","LineMap","feedsOf","formatDiagnostic","lockdown","alignFor","ScriptError","serveScripts","describeJoin","BLOCKED_GLOBALS","parseTimeframe","toError","ScriptRunner","factory","limits","l","sid","def","listener","w","m","transfer","info","id","b","req","timer","feedBars","f","a","reject","CancelledError","p","message","err","reason","t","ScriptDiagnosticsError","diagnostics","d","counter","toDiagnostic","lm","source","se","e","from","to","runScript","r","text","ownRunner","opts","runner","colorKeys","c","schema","colors","k","v","inputs","feeds","feedRef","loaded","study","handleRef","report","base","mirror","withBridge","g","lastGraph","i","cols","n","index","values","colorOf","plot","key","addStudy","chart","x","bars","bar","rest","reset","partial","dropped","restoreScript","saved","byId","s","src","vol","h","createScriptRunAdapter","target","code","onRuntimeError"],"sources":["../src/runner.ts","../src/run.ts","../src/ui-adapter.ts"],"sourcesContent":["// Main-thread side of the script sandbox: a StudyRunner the indicators package\n// can use (batch runs in the worker) plus the tick channel (one bar in, that\n// bar's output values back). Owns the watchdog: a worker that does not answer\n// within the budget is terminated and replaced, and the failure is reported.\n\nimport { CancelledError, type BarColumns, type BarInput, type FeedBar, type RunRequest, type RunResult, type StudyDef, type StudyRunner, type WorkerLike } from \"@alphacharts/indicators\";\nimport { ScriptError } from \"./diag.js\";\nimport { DEFAULT_LIMITS, type Limits } from \"./limits.js\";\nimport type { ErrorInfo, FromWorker, ToWorker } from \"./sandbox.js\";\n\nexport interface ScriptInfo { sid: number; source: string }\n\nexport interface TickListener {\n values(index: number, values: Float64Array): void;\n error(e: ScriptError): void;\n}\n\nconst toError = (e: ErrorInfo): ScriptError => new ScriptError(e.message, e.from !== undefined ? { from: e.from, to: e.to ?? e.from } : null, e.kind === \"compile\" ? \"build\" : e.kind);\n\nexport class ScriptRunner implements StudyRunner {\n private worker: WorkerLike | null = null;\n private nextId = 1;\n private nextSid = 1;\n private readonly infos = new WeakMap<StudyDef, ScriptInfo>();\n private readonly pending = new Map<number, { resolve(r: RunResult): void; reject(e: Error): void; timer: ReturnType<typeof setTimeout> | undefined }>();\n private readonly listeners = new Map<number, TickListener>();\n private tickTimers = new Map<number, ReturnType<typeof setTimeout>>();\n /** Instances whose computed state died with a terminated worker: their bars are not sent until a new batch result. */\n private readonly dead = new Set<number>();\n private limits: Limits;\n private disposed = false;\n\n constructor(private readonly factory: () => WorkerLike, limits: Partial<Limits> = {}) {\n this.limits = { ...DEFAULT_LIMITS, ...limits };\n }\n\n /** Change budgets for later requests. */\n setLimits(l: Partial<Limits>): void {\n this.limits = { ...this.limits, ...l };\n }\n\n /** Bind a (mirror) definition to a script instance. Returns the instance id. */\n attach(def: StudyDef, source: string, listener: TickListener): number {\n const sid = this.nextSid++;\n this.infos.set(def, { sid, source });\n this.listeners.set(sid, listener);\n return sid;\n }\n\n detach(sid: number): void {\n this.listeners.delete(sid);\n this.dead.delete(sid);\n this.clearTick(sid);\n this.post({ type: \"dispose\", sid });\n }\n\n canRun(def: StudyDef): boolean {\n return this.infos.has(def);\n }\n\n private ensure(): WorkerLike {\n if (this.disposed) throw new ScriptError(\"the script runner was disposed\");\n if (!this.worker) {\n const w = this.factory();\n w.addEventListener(\"message\", (e) => this.onMessage(e.data as FromWorker));\n w.addEventListener(\"error\", (e) => this.fail(new ScriptError(`script worker failed: ${e.message ?? \"unknown error\"}`, null, \"runtime\")));\n this.worker = w;\n }\n return this.worker;\n }\n\n private post(m: ToWorker, transfer: Transferable[] = []): void {\n if (this.disposed) return;\n if (m.type === \"dispose\" && !this.worker) return;\n this.ensure().postMessage(m, transfer);\n }\n\n run(def: StudyDef, req: RunRequest) {\n const info = this.infos.get(def);\n if (!info) return { promise: Promise.reject(new ScriptError(\"not a script study\")), cancel: () => {} };\n const id = this.nextId++;\n this.dead.delete(info.sid);\n const b = req.bars as BarColumns;\n const promise = new Promise<RunResult>((resolve, reject) => {\n const timer = setTimeout(() => this.timeout(id, `the script did not finish within ${this.limits.batchMs} ms and was terminated`), this.limits.batchMs);\n this.pending.set(id, { resolve, reject, timer });\n const feedBars = Object.values(req.feeds ?? {}).flatMap((f) => [f.bars.time, f.bars.open, f.bars.high, f.bars.low, f.bars.close, f.bars.volume]);\n const transfer = [b.time, b.close, b.open, b.high, b.low, b.volume, ...feedBars].filter((a): a is Float64Array => !!a).map((a) => a.buffer);\n try {\n this.post({ type: \"run\", id, sid: info.sid, source: info.source, params: req.params, bars: b, ...(req.feeds && { feeds: req.feeds }), limits: this.limits }, transfer);\n } catch (e) {\n clearTimeout(timer);\n this.pending.delete(id);\n reject(e instanceof Error ? e : new Error(String(e)));\n }\n });\n return { promise, cancel: () => { this.post({ type: \"cancel\", id }); this.settle(id)?.reject(new CancelledError()); } };\n }\n\n /** Send one bar of a tick (append or revision) to the script instance. */\n sendBar(sid: number, index: number, bar: BarInput): void {\n if (!this.listeners.has(sid) || this.dead.has(sid)) return;\n this.arm(sid);\n this.post({ type: \"bar\", sid, index, bar });\n }\n\n /** Send one live bar of an outside series to the script instance; it answers with the chart's last bar's values, or `idle` when nothing it sees changed. */\n feedBar(def: StudyDef, key: string, bar: FeedBar): void {\n const info = this.infos.get(def);\n if (!info || !this.listeners.has(info.sid) || this.dead.has(info.sid)) return;\n this.arm(info.sid);\n this.post({ type: \"feed-bar\", sid: info.sid, key, bar });\n }\n\n private arm(sid: number): void {\n // a tick queued behind another script's batch is not slow because of its own script: no timer then\n if (!this.tickTimers.has(sid) && this.pending.size === 0) {\n this.tickTimers.set(sid, setTimeout(() => {\n this.tickTimers.delete(sid);\n this.terminateWorker(new ScriptError(`a tick took longer than ${this.limits.tickMs} ms; the script was terminated`, null, \"budget\"));\n }, this.limits.tickMs));\n }\n }\n\n private clearTick(sid: number): void {\n const t = this.tickTimers.get(sid);\n if (t !== undefined) clearTimeout(t);\n this.tickTimers.delete(sid);\n }\n\n private settle(id: number) {\n const p = this.pending.get(id);\n if (!p) return undefined;\n clearTimeout(p.timer);\n this.pending.delete(id);\n return p;\n }\n\n private onMessage(m: FromWorker): void {\n switch (m.type) {\n case \"result\": this.settle(m.id)?.resolve({ n: m.n, buffers: m.buffers }); return;\n case \"cancelled\": this.settle(m.id)?.reject(new CancelledError()); return;\n case \"error\": this.settle(m.id)?.reject(toError(m.error)); return;\n case \"values\": {\n this.clearTick(m.sid);\n this.listeners.get(m.sid)?.values(m.index, m.values);\n return;\n }\n case \"idle\": this.clearTick(m.sid); return;\n case \"tick-error\": this.clearTick(m.sid); this.listeners.get(m.sid)?.error(toError(m.error)); return;\n }\n }\n\n private timeout(id: number, message: string): void {\n const p = this.settle(id);\n if (!p) return;\n p.reject(new ScriptError(message, null, \"budget\"));\n this.terminateWorker(new ScriptError(message, null, \"budget\"));\n }\n\n /**\n * Kill the worker. Every instance lost its computed state with it: each one is told, and stops\n * sending bars until it is run again (a new batch, e.g. after an input change).\n */\n private terminateWorker(reason?: ScriptError): void {\n this.worker?.terminate();\n this.worker = null;\n const err = reason ?? new ScriptError(\"the script worker was terminated\", null, \"budget\");\n for (const id of [...this.pending.keys()]) this.settle(id)?.reject(err);\n for (const t of this.tickTimers.values()) clearTimeout(t);\n this.tickTimers.clear();\n for (const [sid, l] of this.listeners) {\n if (this.dead.has(sid)) continue;\n this.dead.add(sid);\n l.error(err);\n }\n }\n\n private fail(e: ScriptError): void {\n this.terminateWorker(e);\n }\n\n dispose(): void {\n this.terminateWorker();\n this.disposed = true;\n this.listeners.clear();\n }\n}\n","// runScript: a script on a chart, computed in the sandbox worker, as a handle\n// like addStudy's. Batch runs and ticks both execute in the worker; the main\n// thread only mirrors the columns and draws them through the indicators plugin.\n\nimport { addStudy, type Study, type StudyDef } from \"@alphacharts/indicators\";\nimport type { Chart, Series, SeriesType } from \"@alphacharts/core\";\nimport { compile, type CompileOk } from \"./compile.js\";\nimport { alignFor, feedsOf, type FeedRef } from \"./feeds.js\";\nimport { LineMap, ScriptError, type Diagnostic } from \"./diag.js\";\nimport { ScriptRunner } from \"./runner.js\";\nimport { withBridge } from \"./sandbox.js\";\nimport type { Limits } from \"./limits.js\";\nimport type { FeedBar, FeedBars, InputValue, WorkerLike } from \"@alphacharts/indicators\";\n\ntype SourceSeries = Series<\"candles\" | \"bars\" | \"line\" | \"area\" | \"histogram\">;\ntype VolumeSeries = Series<\"histogram\" | \"line\" | \"area\">;\n\nexport class ScriptDiagnosticsError extends Error {\n constructor(readonly diagnostics: Diagnostic[]) {\n super(diagnostics.filter((d) => d.severity === \"error\").map((d) => `${d.line}:${d.column}: ${d.message}`).join(\"\\n\"));\n this.name = \"ScriptDiagnosticsError\";\n }\n}\n\nexport interface RunScriptOptions {\n volume?: VolumeSeries;\n /** Share one runner (one worker) between scripts. Default: a private one that `remove()` disposes. */\n runner?: ScriptRunner;\n /** Creates the worker, from the host's bundler (`new Worker(new URL(\"@alphacharts/script/worker\", import.meta.url), { type: \"module\" })`). Required unless `runner` is given: the package never guesses where its worker lives. */\n workerFactory?: () => WorkerLike;\n limits?: Partial<Limits>;\n /**\n * Length of one bar of the source series, ms. Required when the script reads outside series (`compile().plan.dependencies`):\n * it decides whether each joins on exact time (same length) or on the bar that has finished (longer).\n */\n intervalMs?: number;\n id?: string;\n /** Called when the script fails at run time (budget, runtime error, worker failure). */\n onError?: (d: Diagnostic) => void;\n}\n\nexport interface ScriptHandle {\n readonly study: Study;\n readonly compiled: CompileOk;\n /** The outside series the script reads (what to load and pass to `setSeries`), empty for a script that reads none. */\n readonly feeds: readonly FeedRef[];\n /**\n * Give the script the bars of outside series `key` (one of `feeds[i].key`), in that series' own time (UTC ms, strictly\n * increasing), replacing what it had, and compute again. The script keeps its own copy.\n */\n setSeries(key: string, bars: FeedBars): void;\n /**\n * A live bar of outside series `key`: the same time as its last bar revises it, a later time appends. Only the chart's\n * last bar is evaluated again, and only when it sees a different bar of that series; otherwise nothing is computed or\n * redrawn. Does nothing until `setSeries` has given the series.\n */\n pushSeries(key: string, bar: FeedBar): void;\n /** Last run-time failure, if any. */\n error: Diagnostic | null;\n /**\n * Change inputs: those in `partial` take their value, the others keep theirs, and the keys in `reset` go back to the\n * script's defaults (colour inputs included). Outside series the script was given stay.\n */\n setInputs(partial: Readonly<Record<string, InputValue>>, reset?: readonly string[]): void;\n remove(): void;\n ready(): Promise<void>;\n toJSON(): SavedScript;\n}\n\nexport interface SavedScript {\n version: 1;\n source: string;\n inputs: Record<string, InputValue>;\n series: string;\n volume?: string;\n visible: boolean;\n}\n\nlet counter = 0;\n\nfunction toDiagnostic(source: string, e: unknown): Diagnostic {\n const lm = new LineMap(source);\n const se = e instanceof ScriptError ? e : null;\n const from = se?.span?.from ?? 0, to = se?.span?.to ?? 0;\n const a = lm.at(from), b = lm.at(to);\n return { severity: \"error\", message: e instanceof Error ? e.message : String(e), line: a.line, column: a.column, endLine: b.line, endColumn: b.column, from, to };\n}\n\nexport function runScript(chart: Chart, source: SourceSeries, text: string, inputs: Readonly<Record<string, InputValue>>, opts: RunScriptOptions): ScriptHandle {\n const r = compile(text);\n if (!r.ok) throw new ScriptDiagnosticsError(r.diagnostics);\n const ownRunner = !opts.runner;\n if (!opts.runner && !opts.workerFactory) throw new Error(\"runScript needs a workerFactory or a runner: the package does not guess where its worker lives\");\n const runner = opts.runner ?? new ScriptRunner(opts.workerFactory!, opts.limits);\n const colorKeys = new Set(r.colorInputs.map((c) => c.key));\n const schema: Record<string, InputValue> = {};\n const colors: Record<string, string> = {};\n for (const [k, v] of Object.entries(inputs)) {\n if (colorKeys.has(k)) colors[k] = String(v);\n else schema[k] = v;\n }\n const feeds = feedsOf(r.plan.dependencies);\n if (feeds.length > 0 && !(opts.intervalMs! > 0)) throw new TypeError(\"this script reads outside series: pass options.intervalMs, the length of one bar of the chart, in milliseconds\");\n const feedRef = new Map(feeds.map((f) => [f.key, f]));\n const loaded = new Set<string>();\n const id = opts.id ?? `script${++counter}`;\n let study: Study | null = null;\n let handleRef: { error: Diagnostic | null } = { error: null };\n const report = (e: unknown) => {\n const d = toDiagnostic(text, e);\n handleRef.error = d;\n opts.onError?.(d);\n };\n const base: StudyDef = { ...r.study, id: `script:${id}` };\n // the main-thread mirror: same columns as the worker's graph, nothing computed here\n let sid = 0;\n const mirror = withBridge(base, (i) => {\n const g = lastGraph!;\n runner.sendBar(sid, i, { time: g.time.v[i]!, open: g.open.v[i]!, high: g.high.v[i]!, low: g.low.v[i]!, close: g.close.v[i]!, volume: g.volume.v[i]! });\n }, true);\n let lastGraph: import(\"@alphacharts/indicators\").Graph | null = null;\n const def: StudyDef = { ...mirror, build: (g, p) => { lastGraph = g; return mirror.build(g, p); } };\n sid = runner.attach(def, text, {\n values(index, values) {\n if (!study || study.disposed) return;\n const cols = def.columns;\n const n = study.times().length;\n if (index >= n) return;\n cols.forEach((c, k) => { study!.column(c)[index] = values[k]!; });\n study.refresh(index === n - 1);\n },\n error: report,\n });\n const colorOf = (key: string, v: string) => {\n for (const plot of r.colorInputs.find((c) => c.key === key)!.plotKeys) study!.setStyle(plot, { color: v });\n };\n // This study uses this runner even when the chart's studies plugin was installed with another (or none).\n study = addStudy(chart, source, def, schema, {\n runner, id, persist: false, ...(opts.volume && { volume: opts.volume }),\n // however the study ends (remove(), its source series removed, a layout restored over it) the worker state goes too\n onDispose: () => { runner.detach(sid); if (ownRunner) runner.dispose(); },\n });\n for (const [k, v] of Object.entries(colors)) colorOf(k, v);\n study.ready().catch(report);\n const handle: ScriptHandle = {\n study,\n compiled: r,\n feeds,\n setSeries(key, bars) {\n const f = feedRef.get(key);\n if (!f) throw new RangeError(`this script reads no outside series \"${key}\" (it reads: ${feeds.map((x) => JSON.stringify(x.key)).join(\", \") || \"none\"})`);\n study!.setFeed(key, bars, alignFor(f.timeframe, opts.intervalMs!));\n loaded.add(key);\n study!.ready().catch(report);\n },\n pushSeries(key, bar) {\n if (!feedRef.has(key)) throw new RangeError(`this script reads no outside series \"${key}\"`);\n if (!loaded.has(key)) return;\n study!.pushFeedBar(key, bar);\n },\n get error() { return handleRef.error; },\n set error(v) { handleRef.error = v; },\n setInputs(partial, reset = []) {\n const rest: Record<string, InputValue> = {};\n for (const k of reset) {\n const c = r.colorInputs.find((x) => x.key === k);\n if (c) { colors[k] = c.default; colorOf(k, c.default); }\n }\n for (const [k, v] of Object.entries(partial)) {\n if (colorKeys.has(k)) { colors[k] = String(v); colorOf(k, String(v)); } else rest[k] = v;\n }\n const dropped = reset.filter((k) => !colorKeys.has(k));\n if (Object.keys(rest).length > 0 || dropped.length > 0) { handleRef.error = null; study!.setInputs(rest, dropped); study!.ready().catch(report); }\n },\n remove() {\n study!.remove();\n },\n ready: () => study!.ready(),\n toJSON() {\n return { version: 1, source: text, inputs: { ...(study!.inputs() as Record<string, InputValue>), ...colors }, series: source.options().id, ...(opts.volume && { volume: opts.volume.options().id }), visible: study!.visible };\n },\n };\n return handle;\n}\n\n/** Recreate a saved script (SavedScript from `toJSON`) on a chart that holds its series. */\nexport function restoreScript(chart: Chart, saved: SavedScript, opts: RunScriptOptions): ScriptHandle {\n if (saved?.version !== 1 || typeof saved.source !== \"string\") throw new TypeError(\"unrecognised saved script\");\n const byId = new Map(chart.series().map((s) => [s.options().id, s]));\n const src = byId.get(saved.series);\n if (!src) throw new Error(`the saved script needs series \"${saved.series}\"`);\n const vol = saved.volume ? byId.get(saved.volume) : undefined;\n const h = runScript(chart, src as SourceSeries, saved.source, saved.inputs, { ...opts, ...(vol && { volume: vol as VolumeSeries }) });\n if (!saved.visible) h.study.setVisible(false);\n return h;\n}\n\nexport type { SeriesType };\n","// The script runner for @alphacharts/ui's script panel: compile, attach to\n// the active chart, report diagnostics. Structural, so this package does not\n// depend on the UI (and the UI not on this package): the host passes\n// `createScriptRunAdapter()` as `scriptRunner` next to the editor adapter.\n\nimport type { Chart, Series } from \"@alphacharts/core\";\nimport type { Diagnostic } from \"./diag.js\";\nimport { runScript, ScriptDiagnosticsError, type RunScriptOptions } from \"./run.js\";\n\n/** Structural copy of `@alphacharts/ui`'s `ScriptRunAdapter` (the definition); apps/playground/src/adapter-contract.ts fails to compile if they drift apart. */\nexport interface ScriptRunAdapter {\n run(\n target: { chart: Chart; source: Series<\"candles\">; volume: Series<\"histogram\"> | null },\n code: string,\n onRuntimeError: (d: Diagnostic) => void,\n ): { diagnostics: readonly Diagnostic[]; remove(): void };\n}\n\n/**\n * Each run gets its own sandboxed worker (disposed with it), the script's\n * default inputs, and the volume series when the chart has one.\n */\nexport function createScriptRunAdapter(opts: Omit<RunScriptOptions, \"volume\" | \"onError\" | \"runner\" | \"workerFactory\"> & { workerFactory: NonNullable<RunScriptOptions[\"workerFactory\"]> }): ScriptRunAdapter {\n return {\n run(target, code, onRuntimeError) {\n try {\n const h = runScript(target.chart, target.source, code, {}, { ...opts, ...(target.volume ? { volume: target.volume } : {}), onError: onRuntimeError });\n return { diagnostics: [], remove: () => h.remove() };\n } catch (e) {\n // Compile errors are the user's to fix; anything else is a bug and is rethrown.\n if (e instanceof ScriptDiagnosticsError) return { diagnostics: e.diagnostics, remove: () => {} };\n throw e;\n }\n },\n };\n}\n"],"mappings":"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"}