oakscriptjs 0.1.5 → 0.1.6

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 (61) hide show
  1. package/dist/array/index.d.ts +57 -0
  2. package/dist/array/index.d.ts.map +1 -0
  3. package/dist/box/index.d.ts +29 -0
  4. package/dist/box/index.d.ts.map +1 -0
  5. package/dist/chartpoint/index.d.ts +8 -0
  6. package/dist/chartpoint/index.d.ts.map +1 -0
  7. package/dist/color/index.d.ts +28 -0
  8. package/dist/color/index.d.ts.map +1 -0
  9. package/dist/index.d.ts +54 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +6177 -0
  12. package/dist/index.mjs +6160 -0
  13. package/dist/indicator.d.ts +42 -0
  14. package/dist/indicator.d.ts.map +1 -0
  15. package/dist/input.d.ts +41 -0
  16. package/dist/input.d.ts.map +1 -0
  17. package/dist/label/index.d.ts +22 -0
  18. package/dist/label/index.d.ts.map +1 -0
  19. package/dist/line/index.d.ts +22 -0
  20. package/dist/line/index.d.ts.map +1 -0
  21. package/dist/linefill/index.d.ts +8 -0
  22. package/dist/linefill/index.d.ts.map +1 -0
  23. package/dist/math/index.d.ts +53 -0
  24. package/dist/math/index.d.ts.map +1 -0
  25. package/dist/matrix/index.d.ts +52 -0
  26. package/dist/matrix/index.d.ts.map +1 -0
  27. package/dist/plot.d.ts +20 -0
  28. package/dist/plot.d.ts.map +1 -0
  29. package/dist/polyline/index.d.ts +10 -0
  30. package/dist/polyline/index.d.ts.map +1 -0
  31. package/dist/runtime/adapters/LightweightChartsAdapter.d.ts +15 -0
  32. package/dist/runtime/adapters/LightweightChartsAdapter.d.ts.map +1 -0
  33. package/dist/runtime/adapters/SimpleInputAdapter.d.ts +16 -0
  34. package/dist/runtime/adapters/SimpleInputAdapter.d.ts.map +1 -0
  35. package/dist/runtime/index.d.ts +6 -0
  36. package/dist/runtime/index.d.ts.map +1 -0
  37. package/dist/runtime/index.js +556 -0
  38. package/dist/runtime/index.mjs +533 -0
  39. package/dist/runtime/inputs.d.ts +10 -0
  40. package/dist/runtime/inputs.d.ts.map +1 -0
  41. package/dist/runtime/runtime.d.ts +16 -0
  42. package/dist/runtime/runtime.d.ts.map +1 -0
  43. package/dist/runtime/series.d.ts +58 -0
  44. package/dist/runtime/series.d.ts.map +1 -0
  45. package/dist/runtime/types.d.ts +55 -0
  46. package/dist/runtime/types.d.ts.map +1 -0
  47. package/dist/str/index.d.ts +23 -0
  48. package/dist/str/index.d.ts.map +1 -0
  49. package/dist/ta/index.d.ts +63 -0
  50. package/dist/ta/index.d.ts.map +1 -0
  51. package/dist/ta-series.d.ts +61 -0
  52. package/dist/ta-series.d.ts.map +1 -0
  53. package/dist/time/index.d.ts +4 -0
  54. package/dist/time/index.d.ts.map +1 -0
  55. package/dist/types/index.d.ts +175 -0
  56. package/dist/types/index.d.ts.map +1 -0
  57. package/dist/types/metadata.d.ts +90 -0
  58. package/dist/types/metadata.d.ts.map +1 -0
  59. package/dist/utils/index.d.ts +21 -0
  60. package/dist/utils/index.d.ts.map +1 -0
  61. package/package.json +1 -1
@@ -0,0 +1,556 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/runtime/index.ts
21
+ var runtime_exports = {};
22
+ __export(runtime_exports, {
23
+ LightweightChartsAdapter: () => LightweightChartsAdapter,
24
+ SimpleInputAdapter: () => SimpleInputAdapter,
25
+ clearContext: () => clearContext,
26
+ clearPlots: () => clearPlots,
27
+ disableAutoRecalculate: () => disableAutoRecalculate,
28
+ enableAutoRecalculate: () => enableAutoRecalculate,
29
+ getActivePlots: () => getActivePlots,
30
+ getContext: () => getContext,
31
+ hline: () => hline,
32
+ input_bool: () => input_bool,
33
+ input_float: () => input_float,
34
+ input_int: () => input_int,
35
+ input_source: () => input_source,
36
+ input_string: () => input_string,
37
+ plot: () => plot,
38
+ recalculate: () => recalculate,
39
+ registerCalculate: () => registerCalculate,
40
+ resetInputs: () => resetInputs,
41
+ setContext: () => setContext
42
+ });
43
+ module.exports = __toCommonJS(runtime_exports);
44
+
45
+ // src/runtime/runtime.ts
46
+ var context = null;
47
+ var calculateFn = null;
48
+ var activePlots = [];
49
+ var plotCounter = 0;
50
+ function setContext(ctx) {
51
+ context = ctx;
52
+ plotCounter = 0;
53
+ clearPlots();
54
+ }
55
+ function clearContext() {
56
+ clearPlots();
57
+ context = null;
58
+ calculateFn = null;
59
+ plotCounter = 0;
60
+ }
61
+ function getContext() {
62
+ return context;
63
+ }
64
+ function registerCalculate(fn) {
65
+ calculateFn = fn;
66
+ }
67
+ function recalculate() {
68
+ if (calculateFn) {
69
+ clearPlots();
70
+ plotCounter = 0;
71
+ calculateFn();
72
+ }
73
+ }
74
+ function clearPlots() {
75
+ if (context) {
76
+ for (const plot2 of activePlots) {
77
+ try {
78
+ context.chart.removeSeries(plot2.series);
79
+ } catch {
80
+ }
81
+ }
82
+ }
83
+ activePlots.length = 0;
84
+ }
85
+ function getSeriesType(style) {
86
+ switch (style) {
87
+ case "histogram":
88
+ case "columns":
89
+ return "histogram";
90
+ case "area":
91
+ case "areabr":
92
+ return "area";
93
+ case "circles":
94
+ case "cross":
95
+ return "line";
96
+ default:
97
+ return "line";
98
+ }
99
+ }
100
+ function getLineStyle(style) {
101
+ switch (style) {
102
+ case "dotted":
103
+ return 1;
104
+ case "dashed":
105
+ return 2;
106
+ case "solid":
107
+ default:
108
+ return 0;
109
+ }
110
+ }
111
+ function plot(series, title, color, linewidth, style) {
112
+ if (!context) {
113
+ throw new Error("OakScript context not set. Call setContext() before plotting.");
114
+ }
115
+ const plotId = `plot_${plotCounter++}${title ? "_" + title.replace(/\s+/g, "_") : ""}`;
116
+ const seriesType = getSeriesType(style);
117
+ const options = {
118
+ color,
119
+ lineWidth: linewidth,
120
+ lineStyle: getLineStyle(style)
121
+ };
122
+ const seriesHandle = context.chart.addSeries(seriesType, options);
123
+ const data = [];
124
+ for (let index = 0; index < series.length; index++) {
125
+ const value = series[index];
126
+ const time = context.ohlcv.time[index];
127
+ if (time !== void 0 && value !== void 0 && !Number.isNaN(value)) {
128
+ data.push({ time, value });
129
+ }
130
+ }
131
+ seriesHandle.setData(data);
132
+ activePlots.push({ id: plotId, series: seriesHandle });
133
+ return plotId;
134
+ }
135
+ function hline(price, title, color, linestyle, linewidth) {
136
+ if (!context) {
137
+ throw new Error("OakScript context not set. Call setContext() before creating hlines.");
138
+ }
139
+ const hlineId = `hline_${plotCounter++}${title ? "_" + title.replace(/\s+/g, "_") : ""}`;
140
+ const options = {
141
+ color,
142
+ lineWidth: linewidth,
143
+ lineStyle: getLineStyle(linestyle)
144
+ };
145
+ const seriesHandle = context.chart.addSeries("line", options);
146
+ const data = context.ohlcv.time.map((time) => ({
147
+ time,
148
+ value: price
149
+ }));
150
+ seriesHandle.setData(data);
151
+ activePlots.push({ id: hlineId, series: seriesHandle });
152
+ return hlineId;
153
+ }
154
+ function getActivePlots() {
155
+ return activePlots;
156
+ }
157
+
158
+ // src/runtime/inputs.ts
159
+ var registeredInputs = /* @__PURE__ */ new Map();
160
+ var autoRecalculateEnabled = false;
161
+ function enableAutoRecalculate() {
162
+ autoRecalculateEnabled = true;
163
+ }
164
+ function disableAutoRecalculate() {
165
+ autoRecalculateEnabled = false;
166
+ }
167
+ function resetInputs() {
168
+ registeredInputs.clear();
169
+ inputCounter = 0;
170
+ }
171
+ var inputCounter = 0;
172
+ function generateInputId(title, defval, type) {
173
+ if (title) {
174
+ return title.replace(/\s+/g, "_");
175
+ }
176
+ return `${type}_${inputCounter++}_${String(defval)}`;
177
+ }
178
+ function input_int(defval, title, options) {
179
+ const context2 = getContext();
180
+ if (!context2) {
181
+ return Math.floor(defval);
182
+ }
183
+ const id = generateInputId(title, defval, "int");
184
+ const config = {
185
+ id,
186
+ type: "int",
187
+ defval: Math.floor(defval),
188
+ title,
189
+ min: options?.min,
190
+ max: options?.max,
191
+ step: options?.step ?? 1
192
+ };
193
+ if (!registeredInputs.has(id)) {
194
+ context2.inputs.registerInput(config);
195
+ registeredInputs.set(id, true);
196
+ if (autoRecalculateEnabled) {
197
+ context2.inputs.onInputChange((changedId) => {
198
+ if (changedId === id) {
199
+ recalculate();
200
+ }
201
+ });
202
+ }
203
+ }
204
+ const value = context2.inputs.getValue(id);
205
+ return typeof value === "number" ? Math.floor(value) : Math.floor(defval);
206
+ }
207
+ function input_float(defval, title, options) {
208
+ const context2 = getContext();
209
+ if (!context2) {
210
+ return defval;
211
+ }
212
+ const id = generateInputId(title, defval, "float");
213
+ const config = {
214
+ id,
215
+ type: "float",
216
+ defval,
217
+ title,
218
+ min: options?.min,
219
+ max: options?.max,
220
+ step: options?.step ?? 0.1
221
+ };
222
+ if (!registeredInputs.has(id)) {
223
+ context2.inputs.registerInput(config);
224
+ registeredInputs.set(id, true);
225
+ if (autoRecalculateEnabled) {
226
+ context2.inputs.onInputChange((changedId) => {
227
+ if (changedId === id) {
228
+ recalculate();
229
+ }
230
+ });
231
+ }
232
+ }
233
+ const value = context2.inputs.getValue(id);
234
+ return typeof value === "number" ? value : defval;
235
+ }
236
+ function input_bool(defval, title) {
237
+ const context2 = getContext();
238
+ if (!context2) {
239
+ return defval;
240
+ }
241
+ const id = generateInputId(title, defval, "bool");
242
+ const config = {
243
+ id,
244
+ type: "bool",
245
+ defval,
246
+ title
247
+ };
248
+ if (!registeredInputs.has(id)) {
249
+ context2.inputs.registerInput(config);
250
+ registeredInputs.set(id, true);
251
+ if (autoRecalculateEnabled) {
252
+ context2.inputs.onInputChange((changedId) => {
253
+ if (changedId === id) {
254
+ recalculate();
255
+ }
256
+ });
257
+ }
258
+ }
259
+ const value = context2.inputs.getValue(id);
260
+ return typeof value === "boolean" ? value : defval;
261
+ }
262
+ function input_string(defval, title, options) {
263
+ const context2 = getContext();
264
+ if (!context2) {
265
+ return defval;
266
+ }
267
+ const id = generateInputId(title, defval, "string");
268
+ const config = {
269
+ id,
270
+ type: "string",
271
+ defval,
272
+ title,
273
+ options
274
+ };
275
+ if (!registeredInputs.has(id)) {
276
+ context2.inputs.registerInput(config);
277
+ registeredInputs.set(id, true);
278
+ if (autoRecalculateEnabled) {
279
+ context2.inputs.onInputChange((changedId) => {
280
+ if (changedId === id) {
281
+ recalculate();
282
+ }
283
+ });
284
+ }
285
+ }
286
+ const value = context2.inputs.getValue(id);
287
+ return typeof value === "string" ? value : defval;
288
+ }
289
+ function input_source(defval, title) {
290
+ const context2 = getContext();
291
+ if (!context2) {
292
+ return [];
293
+ }
294
+ const id = generateInputId(title, defval, "source");
295
+ const config = {
296
+ id,
297
+ type: "source",
298
+ defval,
299
+ title,
300
+ options: ["open", "high", "low", "close", "volume", "hl2", "hlc3", "ohlc4"]
301
+ };
302
+ if (!registeredInputs.has(id)) {
303
+ context2.inputs.registerInput(config);
304
+ registeredInputs.set(id, true);
305
+ if (autoRecalculateEnabled) {
306
+ context2.inputs.onInputChange((changedId) => {
307
+ if (changedId === id) {
308
+ recalculate();
309
+ }
310
+ });
311
+ }
312
+ }
313
+ const sourceName = context2.inputs.getValue(id) ?? defval;
314
+ return getSourceData(context2.ohlcv, sourceName);
315
+ }
316
+ function getSourceData(ohlcv, sourceName) {
317
+ switch (sourceName) {
318
+ case "open":
319
+ return ohlcv.open;
320
+ case "high":
321
+ return ohlcv.high;
322
+ case "low":
323
+ return ohlcv.low;
324
+ case "close":
325
+ return ohlcv.close;
326
+ case "volume":
327
+ return ohlcv.volume;
328
+ case "hl2":
329
+ return ohlcv.high.map((h, i) => {
330
+ const l = ohlcv.low[i];
331
+ return l !== void 0 ? (h + l) / 2 : NaN;
332
+ });
333
+ case "hlc3":
334
+ return ohlcv.high.map((h, i) => {
335
+ const l = ohlcv.low[i];
336
+ const c = ohlcv.close[i];
337
+ return l !== void 0 && c !== void 0 ? (h + l + c) / 3 : NaN;
338
+ });
339
+ case "ohlc4":
340
+ return ohlcv.open.map((o, i) => {
341
+ const h = ohlcv.high[i];
342
+ const l = ohlcv.low[i];
343
+ const c = ohlcv.close[i];
344
+ return h !== void 0 && l !== void 0 && c !== void 0 ? (o + h + l + c) / 4 : NaN;
345
+ });
346
+ default:
347
+ return ohlcv.close;
348
+ }
349
+ }
350
+
351
+ // src/runtime/adapters/LightweightChartsAdapter.ts
352
+ var LightweightChartsAdapter = class {
353
+ chart;
354
+ mainSeries;
355
+ paneCount = 0;
356
+ /**
357
+ * Create a new LightweightChartsAdapter
358
+ * @param chart - The lightweight-charts chart instance
359
+ * @param mainSeries - Optional main price series (candlestick/line series)
360
+ */
361
+ constructor(chart, mainSeries) {
362
+ this.chart = chart;
363
+ if (mainSeries) {
364
+ this.mainSeries = this.wrapSeries(mainSeries);
365
+ }
366
+ }
367
+ /**
368
+ * Wrap a lightweight-charts series to implement SeriesHandle
369
+ * @param lwcSeries - The lightweight-charts series
370
+ * @returns SeriesHandle wrapper
371
+ */
372
+ wrapSeries(lwcSeries) {
373
+ return {
374
+ setData: (data) => {
375
+ lwcSeries.setData(data);
376
+ },
377
+ // Store reference for removal
378
+ _lwcSeries: lwcSeries
379
+ };
380
+ }
381
+ /**
382
+ * Map series type string to lightweight-charts series definition
383
+ * @param type - Series type ('line', 'histogram', 'area')
384
+ * @returns Lightweight-charts series definition object
385
+ */
386
+ getSeriesDefinition(type) {
387
+ switch (type) {
388
+ case "histogram":
389
+ return { type: "Histogram" };
390
+ case "area":
391
+ return { type: "Area" };
392
+ case "baseline":
393
+ return { type: "Baseline" };
394
+ case "bar":
395
+ return { type: "Bar" };
396
+ case "line":
397
+ default:
398
+ return { type: "Line" };
399
+ }
400
+ }
401
+ /**
402
+ * Convert OakScriptJS series options to lightweight-charts options
403
+ * @param options - OakScriptJS series options
404
+ * @returns Lightweight-charts compatible options
405
+ */
406
+ convertOptions(options) {
407
+ if (!options) {
408
+ return {};
409
+ }
410
+ const lwcOptions = {};
411
+ if (options.color) {
412
+ lwcOptions.color = options.color;
413
+ }
414
+ if (options.lineWidth !== void 0) {
415
+ lwcOptions.lineWidth = options.lineWidth;
416
+ }
417
+ if (options.lineStyle !== void 0) {
418
+ lwcOptions.lineStyle = options.lineStyle;
419
+ }
420
+ if (options.priceScaleId) {
421
+ lwcOptions.priceScaleId = options.priceScaleId;
422
+ }
423
+ return lwcOptions;
424
+ }
425
+ /**
426
+ * Add a new series to the chart
427
+ * @param type - Series type ('line', 'histogram', 'area')
428
+ * @param options - Series options
429
+ * @returns SeriesHandle for the new series
430
+ */
431
+ addSeries(type, options) {
432
+ const seriesDefinition = this.getSeriesDefinition(type);
433
+ const lwcOptions = this.convertOptions(options);
434
+ const lwcSeries = this.chart.addSeries(seriesDefinition, lwcOptions);
435
+ return this.wrapSeries(lwcSeries);
436
+ }
437
+ /**
438
+ * Remove a series from the chart
439
+ * @param series - SeriesHandle to remove
440
+ */
441
+ removeSeries(series) {
442
+ const wrappedSeries = series;
443
+ if (wrappedSeries._lwcSeries) {
444
+ this.chart.removeSeries(wrappedSeries._lwcSeries);
445
+ }
446
+ }
447
+ /**
448
+ * Get the main price series
449
+ * @returns Main series handle or undefined
450
+ */
451
+ getMainSeries() {
452
+ return this.mainSeries;
453
+ }
454
+ /**
455
+ * Create a new pane (if supported by the chart configuration)
456
+ * @returns Index of the new pane
457
+ */
458
+ createPane() {
459
+ return ++this.paneCount;
460
+ }
461
+ };
462
+
463
+ // src/runtime/adapters/SimpleInputAdapter.ts
464
+ var SimpleInputAdapter = class {
465
+ inputs = /* @__PURE__ */ new Map();
466
+ changeCallbacks = [];
467
+ /**
468
+ * Register an input configuration
469
+ * If already registered, returns current value without modifying config
470
+ * @param config - Input configuration
471
+ * @returns Current value (defval on first registration)
472
+ */
473
+ registerInput(config) {
474
+ if (!this.inputs.has(config.id)) {
475
+ this.inputs.set(config.id, { config, value: config.defval });
476
+ }
477
+ return this.inputs.get(config.id).value;
478
+ }
479
+ /**
480
+ * Get current value of an input
481
+ * @param id - Input identifier
482
+ * @returns Current value or undefined if not registered
483
+ */
484
+ getValue(id) {
485
+ return this.inputs.get(id)?.value;
486
+ }
487
+ /**
488
+ * Set value of an input with validation
489
+ * Validates against config constraints (min/max/step for numerics, options for strings)
490
+ * @param id - Input identifier
491
+ * @param value - New value
492
+ */
493
+ setValue(id, value) {
494
+ const input = this.inputs.get(id);
495
+ if (!input) {
496
+ return;
497
+ }
498
+ const { config } = input;
499
+ let validatedValue = value;
500
+ if ((config.type === "int" || config.type === "float") && typeof value === "number") {
501
+ if (config.min !== void 0 && value < config.min) {
502
+ validatedValue = config.min;
503
+ }
504
+ if (config.max !== void 0 && value > config.max) {
505
+ validatedValue = config.max;
506
+ }
507
+ if (config.type === "int") {
508
+ validatedValue = Math.floor(validatedValue);
509
+ }
510
+ }
511
+ if (config.type === "string" && config.options && typeof value === "string") {
512
+ if (!config.options.includes(value)) {
513
+ return;
514
+ }
515
+ }
516
+ if (config.type === "source" && config.options && typeof value === "string") {
517
+ if (!config.options.includes(value)) {
518
+ return;
519
+ }
520
+ }
521
+ input.value = validatedValue;
522
+ this.changeCallbacks.forEach((cb) => cb(id, validatedValue));
523
+ }
524
+ /**
525
+ * Register a callback for input value changes
526
+ * @param callback - Function to call when any input value changes
527
+ */
528
+ onInputChange(callback) {
529
+ this.changeCallbacks.push(callback);
530
+ }
531
+ /**
532
+ * Get all registered inputs (for UI rendering)
533
+ * @returns Map of input IDs to their configs and values
534
+ */
535
+ getAllInputs() {
536
+ return new Map(this.inputs);
537
+ }
538
+ /**
539
+ * Clear all registered inputs
540
+ * Useful for testing or resetting state
541
+ */
542
+ clear() {
543
+ this.inputs.clear();
544
+ this.changeCallbacks = [];
545
+ }
546
+ /**
547
+ * Remove a specific change callback
548
+ * @param callback - The callback to remove
549
+ */
550
+ removeChangeCallback(callback) {
551
+ const index = this.changeCallbacks.indexOf(callback);
552
+ if (index !== -1) {
553
+ this.changeCallbacks.splice(index, 1);
554
+ }
555
+ }
556
+ };