openalgo-script 0.2.0 → 0.4.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/CHANGELOG.md +269 -0
- package/README.md +65 -31
- package/dist/adapters/charts/surfaces.d.ts +17 -0
- package/dist/adapters/charts/surfaces.d.ts.map +1 -1
- package/dist/adapters/charts/tables.js +82 -0
- package/dist/adapters/charts/tables.js.map +1 -1
- package/dist/adapters/codemirror/commands.d.ts +14 -0
- package/dist/adapters/codemirror/commands.d.ts.map +1 -0
- package/dist/adapters/codemirror/commands.js +52 -0
- package/dist/adapters/codemirror/commands.js.map +1 -0
- package/dist/adapters/codemirror/completion.d.ts +15 -0
- package/dist/adapters/codemirror/completion.d.ts.map +1 -0
- package/dist/adapters/codemirror/completion.js +64 -0
- package/dist/adapters/codemirror/completion.js.map +1 -0
- package/dist/adapters/codemirror/contract.d.ts +156 -0
- package/dist/adapters/codemirror/contract.d.ts.map +1 -0
- package/dist/adapters/codemirror/contract.js +42 -0
- package/dist/adapters/codemirror/contract.js.map +1 -0
- package/dist/adapters/codemirror/index.d.ts +43 -0
- package/dist/adapters/codemirror/index.d.ts.map +1 -0
- package/dist/adapters/codemirror/index.js +8 -0
- package/dist/adapters/codemirror/index.js.map +1 -0
- package/dist/adapters/codemirror/lint.d.ts +17 -0
- package/dist/adapters/codemirror/lint.d.ts.map +1 -0
- package/dist/adapters/codemirror/lint.js +62 -0
- package/dist/adapters/codemirror/lint.js.map +1 -0
- package/dist/adapters/codemirror/positions.d.ts +16 -0
- package/dist/adapters/codemirror/positions.d.ts.map +1 -0
- package/dist/adapters/codemirror/positions.js +65 -0
- package/dist/adapters/codemirror/positions.js.map +1 -0
- package/dist/adapters/codemirror/stream.d.ts +23 -0
- package/dist/adapters/codemirror/stream.d.ts.map +1 -0
- package/dist/adapters/codemirror/stream.js +70 -0
- package/dist/adapters/codemirror/stream.js.map +1 -0
- package/dist/adapters/codemirror/tokens.d.ts +44 -0
- package/dist/adapters/codemirror/tokens.d.ts.map +1 -0
- package/dist/adapters/codemirror/tokens.js +34 -0
- package/dist/adapters/codemirror/tokens.js.map +1 -0
- package/dist/adapters/codemirror/tooltips.d.ts +35 -0
- package/dist/adapters/codemirror/tooltips.d.ts.map +1 -0
- package/dist/adapters/codemirror/tooltips.js +108 -0
- package/dist/adapters/codemirror/tooltips.js.map +1 -0
- package/dist/core/accounting/charges.d.ts +136 -0
- package/dist/core/accounting/charges.d.ts.map +1 -0
- package/dist/core/accounting/charges.js +362 -0
- package/dist/core/accounting/charges.js.map +1 -0
- package/dist/core/accounting/equity.d.ts +158 -0
- package/dist/core/accounting/equity.d.ts.map +1 -0
- package/dist/core/accounting/equity.js +155 -0
- package/dist/core/accounting/equity.js.map +1 -0
- package/dist/core/accounting/index.d.ts +44 -0
- package/dist/core/accounting/index.d.ts.map +1 -0
- package/dist/core/accounting/index.js +36 -0
- package/dist/core/accounting/index.js.map +1 -0
- package/dist/core/accounting/markers.d.ts +43 -0
- package/dist/core/accounting/markers.d.ts.map +1 -0
- package/dist/core/accounting/markers.js +64 -0
- package/dist/core/accounting/markers.js.map +1 -0
- package/dist/core/accounting/monthly.d.ts +52 -0
- package/dist/core/accounting/monthly.d.ts.map +1 -0
- package/dist/core/accounting/monthly.js +99 -0
- package/dist/core/accounting/monthly.js.map +1 -0
- package/dist/core/accounting/report.d.ts +38 -0
- package/dist/core/accounting/report.d.ts.map +1 -0
- package/dist/core/accounting/report.js +63 -0
- package/dist/core/accounting/report.js.map +1 -0
- package/dist/core/accounting/shapes.d.ts +70 -0
- package/dist/core/accounting/shapes.d.ts.map +1 -0
- package/dist/core/accounting/shapes.js +21 -0
- package/dist/core/accounting/shapes.js.map +1 -0
- package/dist/core/accounting/statistics.d.ts +75 -0
- package/dist/core/accounting/statistics.d.ts.map +1 -0
- package/dist/core/accounting/statistics.js +246 -0
- package/dist/core/accounting/statistics.js.map +1 -0
- package/dist/core/accounting/trades.d.ts +118 -0
- package/dist/core/accounting/trades.d.ts.map +1 -0
- package/dist/core/accounting/trades.js +186 -0
- package/dist/core/accounting/trades.js.map +1 -0
- package/dist/core/backtest/compare.d.ts +38 -0
- package/dist/core/backtest/compare.d.ts.map +1 -0
- package/dist/core/backtest/compare.js +189 -0
- package/dist/core/backtest/compare.js.map +1 -0
- package/dist/core/backtest/declaration.d.ts +52 -0
- package/dist/core/backtest/declaration.d.ts.map +1 -0
- package/dist/core/backtest/declaration.js +48 -0
- package/dist/core/backtest/declaration.js.map +1 -0
- package/dist/core/backtest/drive.d.ts +29 -0
- package/dist/core/backtest/drive.d.ts.map +1 -0
- package/dist/core/backtest/drive.js +262 -0
- package/dist/core/backtest/drive.js.map +1 -0
- package/dist/core/backtest/index.d.ts +46 -0
- package/dist/core/backtest/index.d.ts.map +1 -0
- package/dist/core/backtest/index.js +36 -0
- package/dist/core/backtest/index.js.map +1 -0
- package/dist/core/backtest/range.d.ts +84 -0
- package/dist/core/backtest/range.d.ts.map +1 -0
- package/dist/core/backtest/range.js +90 -0
- package/dist/core/backtest/range.js.map +1 -0
- package/dist/core/backtest/record.d.ts +238 -0
- package/dist/core/backtest/record.d.ts.map +1 -0
- package/dist/core/backtest/record.js +176 -0
- package/dist/core/backtest/record.js.map +1 -0
- package/dist/core/backtest/replay.d.ts +48 -0
- package/dist/core/backtest/replay.d.ts.map +1 -0
- package/dist/core/backtest/replay.js +127 -0
- package/dist/core/backtest/replay.js.map +1 -0
- package/dist/core/backtest/resting.d.ts +62 -0
- package/dist/core/backtest/resting.d.ts.map +1 -0
- package/dist/core/backtest/resting.js +59 -0
- package/dist/core/backtest/resting.js.map +1 -0
- package/dist/core/backtest/settings.d.ts +117 -0
- package/dist/core/backtest/settings.d.ts.map +1 -0
- package/dist/core/backtest/settings.js +207 -0
- package/dist/core/backtest/settings.js.map +1 -0
- package/dist/core/backtest/simulate.d.ts +146 -0
- package/dist/core/backtest/simulate.d.ts.map +1 -0
- package/dist/core/backtest/simulate.js +217 -0
- package/dist/core/backtest/simulate.js.map +1 -0
- package/dist/core/catalogue/catalogue.generated.d.ts +66 -0
- package/dist/core/catalogue/catalogue.generated.d.ts.map +1 -1
- package/dist/core/catalogue/catalogue.generated.js +6 -0
- package/dist/core/catalogue/catalogue.generated.js.map +1 -1
- package/dist/core/catalogue/values.generated.d.ts +24 -0
- package/dist/core/catalogue/values.generated.d.ts.map +1 -1
- package/dist/core/check/index.d.ts +2 -1
- package/dist/core/check/index.d.ts.map +1 -1
- package/dist/core/check/index.js +1 -1
- package/dist/core/check/index.js.map +1 -1
- package/dist/core/check/library-prose.generated.d.ts +16 -0
- package/dist/core/check/library-prose.generated.d.ts.map +1 -0
- package/dist/core/check/library-prose.generated.js +353 -0
- package/dist/core/check/library-prose.generated.js.map +1 -0
- package/dist/core/check/surface.d.ts +24 -0
- package/dist/core/check/surface.d.ts.map +1 -1
- package/dist/core/check/surface.js +29 -0
- package/dist/core/check/surface.js.map +1 -1
- package/dist/core/emit/defaults.d.ts +35 -16
- package/dist/core/emit/defaults.d.ts.map +1 -1
- package/dist/core/emit/defaults.js +66 -0
- package/dist/core/emit/defaults.js.map +1 -1
- package/dist/core/emit/index.d.ts +2 -0
- package/dist/core/emit/index.d.ts.map +1 -1
- package/dist/core/emit/index.js +2 -0
- package/dist/core/emit/index.js.map +1 -1
- package/dist/core/engine/index.d.ts +1 -1
- package/dist/core/engine/index.d.ts.map +1 -1
- package/dist/core/engine/index.js +1 -1
- package/dist/core/engine/index.js.map +1 -1
- package/dist/core/engine/load.d.ts +15 -1
- package/dist/core/engine/load.d.ts.map +1 -1
- package/dist/core/engine/load.js +1 -0
- package/dist/core/engine/load.js.map +1 -1
- package/dist/core/index.d.ts +37 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +17 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/version/version.generated.d.ts +1 -1
- package/dist/core/version/version.generated.js +1 -1
- package/dist/editor/complete.d.ts +40 -0
- package/dist/editor/complete.d.ts.map +1 -0
- package/dist/editor/complete.js +206 -0
- package/dist/editor/complete.js.map +1 -0
- package/dist/editor/diagnose.d.ts +18 -0
- package/dist/editor/diagnose.d.ts.map +1 -0
- package/dist/editor/diagnose.js +70 -0
- package/dist/editor/diagnose.js.map +1 -0
- package/dist/editor/format.d.ts +11 -0
- package/dist/editor/format.d.ts.map +1 -0
- package/dist/editor/format.js +50 -0
- package/dist/editor/format.js.map +1 -0
- package/dist/editor/highlight.d.ts +28 -0
- package/dist/editor/highlight.d.ts.map +1 -0
- package/dist/editor/highlight.js +65 -0
- package/dist/editor/highlight.js.map +1 -0
- package/dist/editor/hover.d.ts +40 -0
- package/dist/editor/hover.d.ts.map +1 -0
- package/dist/editor/hover.js +147 -0
- package/dist/editor/hover.js.map +1 -0
- package/dist/editor/index.d.ts +60 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +7 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/kinds.d.ts +27 -0
- package/dist/editor/kinds.d.ts.map +1 -0
- package/dist/editor/kinds.js +118 -0
- package/dist/editor/kinds.js.map +1 -0
- package/dist/editor/layout.d.ts +47 -0
- package/dist/editor/layout.d.ts.map +1 -0
- package/dist/editor/layout.js +135 -0
- package/dist/editor/layout.js.map +1 -0
- package/dist/editor/manifest.d.ts +47 -0
- package/dist/editor/manifest.d.ts.map +1 -0
- package/dist/editor/manifest.js +93 -0
- package/dist/editor/manifest.js.map +1 -0
- package/dist/editor/reading.d.ts +41 -0
- package/dist/editor/reading.d.ts.map +1 -0
- package/dist/editor/reading.js +51 -0
- package/dist/editor/reading.js.map +1 -0
- package/dist/editor/scan.d.ts +26 -0
- package/dist/editor/scan.d.ts.map +1 -0
- package/dist/editor/scan.js +139 -0
- package/dist/editor/scan.js.map +1 -0
- package/dist/editor/scope.d.ts +19 -0
- package/dist/editor/scope.d.ts.map +1 -0
- package/dist/editor/scope.js +99 -0
- package/dist/editor/scope.js.map +1 -0
- package/dist/editor/signature.d.ts +38 -0
- package/dist/editor/signature.d.ts.map +1 -0
- package/dist/editor/signature.js +112 -0
- package/dist/editor/signature.js.map +1 -0
- package/dist/editor/site.d.ts +46 -0
- package/dist/editor/site.d.ts.map +1 -0
- package/dist/editor/site.js +184 -0
- package/dist/editor/site.js.map +1 -0
- package/dist/editor/spacing.d.ts +29 -0
- package/dist/editor/spacing.d.ts.map +1 -0
- package/dist/editor/spacing.js +116 -0
- package/dist/editor/spacing.js.map +1 -0
- package/package.json +30 -3
- package/spec/errors.json +140 -0
- package/src/adapters/charts/surfaces.ts +17 -0
- package/src/adapters/charts/tables.ts +88 -0
- package/src/adapters/codemirror/commands.ts +53 -0
- package/src/adapters/codemirror/completion.ts +74 -0
- package/src/adapters/codemirror/contract.ts +156 -0
- package/src/adapters/codemirror/index.ts +66 -0
- package/src/adapters/codemirror/lint.ts +66 -0
- package/src/adapters/codemirror/positions.ts +79 -0
- package/src/adapters/codemirror/stream.ts +87 -0
- package/src/adapters/codemirror/tokens.ts +64 -0
- package/src/adapters/codemirror/tooltips.ts +113 -0
- package/src/core/accounting/charges.ts +452 -0
- package/src/core/accounting/equity.ts +276 -0
- package/src/core/accounting/index.ts +49 -0
- package/src/core/accounting/markers.ts +95 -0
- package/src/core/accounting/monthly.ts +137 -0
- package/src/core/accounting/report.ts +89 -0
- package/src/core/accounting/shapes.ts +73 -0
- package/src/core/accounting/statistics.ts +350 -0
- package/src/core/accounting/trades.ts +313 -0
- package/src/core/backtest/compare.ts +244 -0
- package/src/core/backtest/declaration.ts +97 -0
- package/src/core/backtest/drive.ts +364 -0
- package/src/core/backtest/index.ts +52 -0
- package/src/core/backtest/range.ts +137 -0
- package/src/core/backtest/record.ts +341 -0
- package/src/core/backtest/replay.ts +158 -0
- package/src/core/backtest/resting.ts +125 -0
- package/src/core/backtest/settings.ts +280 -0
- package/src/core/backtest/simulate.ts +304 -0
- package/src/core/catalogue/catalogue.generated.ts +6 -0
- package/src/core/catalogue/values.generated.ts +6 -0
- package/src/core/check/index.ts +3 -0
- package/src/core/check/library-prose.generated.ts +367 -0
- package/src/core/check/surface.ts +34 -0
- package/src/core/emit/defaults.ts +70 -0
- package/src/core/emit/index.ts +2 -0
- package/src/core/engine/index.ts +1 -1
- package/src/core/engine/load.ts +16 -2
- package/src/core/index.ts +85 -1
- package/src/core/version/version.generated.ts +1 -1
- package/src/editor/complete.ts +266 -0
- package/src/editor/diagnose.ts +71 -0
- package/src/editor/format.ts +85 -0
- package/src/editor/highlight.ts +110 -0
- package/src/editor/hover.ts +199 -0
- package/src/editor/index.ts +65 -0
- package/src/editor/kinds.ts +157 -0
- package/src/editor/layout.ts +189 -0
- package/src/editor/manifest.ts +119 -0
- package/src/editor/reading.ts +69 -0
- package/src/editor/scan.ts +162 -0
- package/src/editor/scope.ts +122 -0
- package/src/editor/signature.ts +150 -0
- package/src/editor/site.ts +233 -0
- package/src/editor/spacing.ts +132 -0
package/spec/errors.json
CHANGED
|
@@ -2605,6 +2605,99 @@
|
|
|
2605
2605
|
"refines": null,
|
|
2606
2606
|
"test": "tests/engine/verify.test.ts"
|
|
2607
2607
|
},
|
|
2608
|
+
{
|
|
2609
|
+
"code": "OS6020",
|
|
2610
|
+
"title": "The report window holds no bars",
|
|
2611
|
+
"severity": "error",
|
|
2612
|
+
"stage": "host",
|
|
2613
|
+
"since": 1,
|
|
2614
|
+
"message": "The window from {from} to {to} holds none of the {count} bars supplied.",
|
|
2615
|
+
"placeholders": {
|
|
2616
|
+
"from": "the first moment the window covers, or the first bar supplied where the host named none",
|
|
2617
|
+
"to": "the last moment it covers",
|
|
2618
|
+
"count": "how many bars were supplied"
|
|
2619
|
+
},
|
|
2620
|
+
"cause": "A report is about the bars inside the window the host chose, and a window holding none of them has nothing to report: no equity point, no trade and no summary. The bars outside it are warmup, which execute and whose orders are real, so an empty window is not an empty run, and reporting one as a flat curve would tell a reader that nothing happened when something did.",
|
|
2621
|
+
"fix": "Widen the window until it covers bars, or supply the bars it covers. Both bounds are inclusive and are compared against the times of the bars supplied rather than against a calendar, so a window that falls inside a gap in the data is empty however wide it looks.",
|
|
2622
|
+
"autofix": false,
|
|
2623
|
+
"example": {
|
|
2624
|
+
"kind": "transcript",
|
|
2625
|
+
"before": "bars supplied: 1240, first day 1, last day 1240\nreport window: day 1300 to day 1400, bars inside 0",
|
|
2626
|
+
"after": "bars supplied: 1240, first day 1, last day 1240\nreport window: day 1100 to day 1240, bars inside 141"
|
|
2627
|
+
},
|
|
2628
|
+
"spec": "language.md 7.1",
|
|
2629
|
+
"refines": null,
|
|
2630
|
+
"test": "tests/backtest/range.test.ts"
|
|
2631
|
+
},
|
|
2632
|
+
{
|
|
2633
|
+
"code": "OS6021",
|
|
2634
|
+
"title": "A run setting cannot be applied as stated",
|
|
2635
|
+
"severity": "error",
|
|
2636
|
+
"stage": "host",
|
|
2637
|
+
"since": 1,
|
|
2638
|
+
"message": "{setting} cannot be applied: {problem}.",
|
|
2639
|
+
"placeholders": {
|
|
2640
|
+
"setting": "the setting that cannot be applied, such as the charge schedule or the comparison tolerance",
|
|
2641
|
+
"problem": "what makes it unusable, such as a charge line levied on a line declared after it"
|
|
2642
|
+
},
|
|
2643
|
+
"cause": "A run states the settings it is carried out under before its first bar, and a setting that cannot be carried out is refused there rather than quietly producing a figure. A charge line levied on lines not declared before it has no single evaluation order, so two engines would charge two different amounts and both would be defensible. A slippage stated in ticks with no tick size to measure a tick in would charge nothing at all, which is a backtest that lies in the strategy's favour. A comparison tolerance carrying a bound and no reason is a failed comparison somebody switched off.",
|
|
2644
|
+
"fix": "State the setting so it can be carried out: declare a charge line after every line it is levied on, supply the tick size a slippage in ticks is measured in, or write down the reason a tolerance needs a bound. Nothing has been computed at the point this is refused, so correcting the setting and running again costs one run.",
|
|
2645
|
+
"autofix": false,
|
|
2646
|
+
"example": {
|
|
2647
|
+
"kind": "transcript",
|
|
2648
|
+
"before": "charge lines: tax on levy, levy\nslippage: 2 ticks, tick size not supplied",
|
|
2649
|
+
"after": "charge lines: levy, tax on levy\nslippage: 2 ticks, tick size 0.05"
|
|
2650
|
+
},
|
|
2651
|
+
"spec": "stdlib.md 17.1",
|
|
2652
|
+
"refines": null,
|
|
2653
|
+
"test": "tests/accounting/schedules.test.ts"
|
|
2654
|
+
},
|
|
2655
|
+
{
|
|
2656
|
+
"code": "OS6022",
|
|
2657
|
+
"title": "The bars are not the bars the record was made from",
|
|
2658
|
+
"severity": "error",
|
|
2659
|
+
"stage": "host",
|
|
2660
|
+
"since": 1,
|
|
2661
|
+
"message": "The bars supplied hash to {found}, and the record was made from {expected}.",
|
|
2662
|
+
"placeholders": {
|
|
2663
|
+
"found": "the hash of the bars supplied now",
|
|
2664
|
+
"expected": "the hash the record names"
|
|
2665
|
+
},
|
|
2666
|
+
"cause": "A record names the bars it was made from by a hash over their canonical form, so a replay can prove it is replaying the same run rather than producing a different study under the same name. Bars are revised: a feed corrects a print, a session is extended, a split is applied to history. A replay over revised bars that reported the original figures would be the most convincing wrong answer this system can produce.",
|
|
2667
|
+
"fix": "Replay against the bars the record names. Where the revision is the point, make a second record over the revised bars and compare the two runs, rather than overwriting one run with the other under one name.",
|
|
2668
|
+
"autofix": false,
|
|
2669
|
+
"example": {
|
|
2670
|
+
"kind": "transcript",
|
|
2671
|
+
"before": "record: bars 1240, hash 9f2c4e...\nsupplied: bars 1240, hash 4ab70d...",
|
|
2672
|
+
"after": "record: bars 1240, hash 9f2c4e...\nsupplied: bars 1240, hash 9f2c4e..."
|
|
2673
|
+
},
|
|
2674
|
+
"spec": "conformance.md 3",
|
|
2675
|
+
"refines": null,
|
|
2676
|
+
"test": "tests/backtest/record.test.ts"
|
|
2677
|
+
},
|
|
2678
|
+
{
|
|
2679
|
+
"code": "OS6023",
|
|
2680
|
+
"title": "Two cost models are stated at once",
|
|
2681
|
+
"severity": "error",
|
|
2682
|
+
"stage": "host",
|
|
2683
|
+
"since": 1,
|
|
2684
|
+
"message": "A charge schedule was supplied, and the declaration states a commission of {commission} in {commissionType}.",
|
|
2685
|
+
"placeholders": {
|
|
2686
|
+
"commission": "the commission the declaration states",
|
|
2687
|
+
"commissionType": "the unit that commission is stated in"
|
|
2688
|
+
},
|
|
2689
|
+
"cause": "The declaration's commission is the script's own statement of what trading costs and a supplied schedule is the platform's, and the two describe the same money. Applied together they charge it twice; applied one at a time they charge whichever an engine happened to prefer, which is a rule nobody wrote down and a figure nobody can explain afterwards. So exactly one of the two is stated for a run, and stating both is refused before the first bar rather than reconciled behind the reader.",
|
|
2690
|
+
"fix": "Supply the schedule and leave the declaration's commission at its default of zero, or state the commission in the declaration and supply no schedule. A schedule is the one of the two that can carry a floor, a cap, a charge levied on a charge, and a cost that falls on one side of the trade only.",
|
|
2691
|
+
"autofix": false,
|
|
2692
|
+
"example": {
|
|
2693
|
+
"kind": "transcript",
|
|
2694
|
+
"before": "declaration: commission 20, per trade\nhost: charge schedule supplied, 4 lines",
|
|
2695
|
+
"after": "declaration: commission 0, per trade\nhost: charge schedule supplied, 4 lines"
|
|
2696
|
+
},
|
|
2697
|
+
"spec": "language.md 13.3; stdlib.md 17.1",
|
|
2698
|
+
"refines": null,
|
|
2699
|
+
"test": "tests/backtest/settings.test.ts"
|
|
2700
|
+
},
|
|
2608
2701
|
{
|
|
2609
2702
|
"code": "OS7001",
|
|
2610
2703
|
"title": "Only a strategy can do that",
|
|
@@ -2984,6 +3077,53 @@
|
|
|
2984
3077
|
"refines": null,
|
|
2985
3078
|
"test": "tests/engine/closing.test.ts"
|
|
2986
3079
|
},
|
|
3080
|
+
{
|
|
3081
|
+
"code": "OS7018",
|
|
3082
|
+
"title": "A frame names an order this strategy did not place",
|
|
3083
|
+
"severity": "error",
|
|
3084
|
+
"stage": "host",
|
|
3085
|
+
"since": 1,
|
|
3086
|
+
"message": "The frame names intent {intent}, and this strategy holds no such order.",
|
|
3087
|
+
"placeholders": {
|
|
3088
|
+
"intent": "the intent id the frame named"
|
|
3089
|
+
},
|
|
3090
|
+
"cause": "Step 1 of the fold locates the row a frame is about, and a frame naming no row cannot be folded into anything. It is a fact about the host rather than about the strategy: a destination answering for an order another strategy placed, or answering for a run that has already ended. The frame changes nothing and is reported, because a fold that passed over it in silence would leave a host's mistake invisible to the only party who can correct it.",
|
|
3091
|
+
"fix": "Answer with the intent id the engine sent. A destination's own reference is carried in the frame's reference field, where the engine records it and never parses it, and it is not what an answer is addressed by.",
|
|
3092
|
+
"autofix": false,
|
|
3093
|
+
"example": {
|
|
3094
|
+
"kind": "transcript",
|
|
3095
|
+
"before": "engine sent: intent 7, intent 8\nframe: intent 11, status filled, filled qty 1",
|
|
3096
|
+
"after": "engine sent: intent 7, intent 8\nframe: intent 8, status filled, filled qty 1"
|
|
3097
|
+
},
|
|
3098
|
+
"spec": "stdlib.md 17.8, 17.14",
|
|
3099
|
+
"refines": null,
|
|
3100
|
+
"test": null,
|
|
3101
|
+
"deferred": "Nothing raises this yet. The fold refuses the frame and records the refusal as a word on the outcome it hands back, and a word is not a catalogue code, so nothing reports it against the run and a host answering for orders it was never handed stays invisible. Raised when the outcome of a fold carries a code and a bar carries a channel for a diagnostic that does not stop it, stdlib.md 17.8."
|
|
3102
|
+
},
|
|
3103
|
+
{
|
|
3104
|
+
"code": "OS7019",
|
|
3105
|
+
"title": "A fill was reported with no price",
|
|
3106
|
+
"severity": "error",
|
|
3107
|
+
"stage": "host",
|
|
3108
|
+
"since": 1,
|
|
3109
|
+
"message": "The frame reports {qty} filled for intent {intent}, and no average fill price.",
|
|
3110
|
+
"placeholders": {
|
|
3111
|
+
"qty": "the cumulative filled quantity the frame reports",
|
|
3112
|
+
"intent": "the intent id the frame named"
|
|
3113
|
+
},
|
|
3114
|
+
"cause": "Step 3 of the fold takes the destination's own average over the cumulative quantity, because the engine never averages two averages of its own. A frame reporting more filled than the row holds and no price to take is a fill that can be marked against nothing: no position average, no realised profit, no equity point. It is refused whole rather than folded for its quantity alone, because a position holding a size and no price is worse than no position at all.",
|
|
3115
|
+
"fix": "Report the average fill price the destination computed over the cumulative quantity, on every frame that reports a quantity greater than the last one. A frame carrying no new quantity needs no price.",
|
|
3116
|
+
"autofix": false,
|
|
3117
|
+
"example": {
|
|
3118
|
+
"kind": "transcript",
|
|
3119
|
+
"before": "frame: intent 8, status filled, filled qty 3, average fill price absent",
|
|
3120
|
+
"after": "frame: intent 8, status filled, filled qty 3, average fill price 104.25"
|
|
3121
|
+
},
|
|
3122
|
+
"spec": "stdlib.md 17.8, 17.14",
|
|
3123
|
+
"refines": null,
|
|
3124
|
+
"test": null,
|
|
3125
|
+
"deferred": "Nothing raises this yet. The fold refuses the frame and records the refusal as a word on the outcome it hands back, and a word is not a catalogue code, so a destination reporting a fill that can be marked against nothing is refused in silence. Raised when the outcome of a fold carries a code and a bar carries a channel for a diagnostic that does not stop it, stdlib.md 17.8."
|
|
3126
|
+
},
|
|
2987
3127
|
{
|
|
2988
3128
|
"code": "OS8001",
|
|
2989
3129
|
"title": "A stateful call inside a branch",
|
|
@@ -100,6 +100,23 @@ export interface ChartTableOptions {
|
|
|
100
100
|
readonly borderWidth: number;
|
|
101
101
|
/** The backdrop behind the whole grid, which is the grid's own `bgColor`. */
|
|
102
102
|
readonly background?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Column widths in media pixels, one per column.
|
|
105
|
+
*
|
|
106
|
+
* The chart's own default is one flat width for every column, which is a
|
|
107
|
+
* width chosen without seeing the text. A grid whose first column says
|
|
108
|
+
* "Moving averages" and whose second says "RSI: 27.22" has two columns that
|
|
109
|
+
* want different room, and one number cannot give it to both.
|
|
110
|
+
*/
|
|
111
|
+
readonly cellWidth?: readonly number[];
|
|
112
|
+
/**
|
|
113
|
+
* `'auto'` to shrink a cell's type until its text fits the cell it is in.
|
|
114
|
+
*
|
|
115
|
+
* The chart measures the text it is about to draw, which nothing upstream of
|
|
116
|
+
* it can do, so this is what makes a column width that is slightly wrong
|
|
117
|
+
* merely slightly loose instead of two cells written over each other.
|
|
118
|
+
*/
|
|
119
|
+
readonly fontSize?: number | 'auto';
|
|
103
120
|
}
|
|
104
121
|
|
|
105
122
|
/** A grid of cells pinned to a corner, and the options it is drawn with. */
|
|
@@ -118,10 +118,98 @@ function oneTable(
|
|
|
118
118
|
position: CORNERS[position] ?? 'top-right',
|
|
119
119
|
borderWidth: numberField(declared.options.borderWidth, lookup, 0),
|
|
120
120
|
...(bgColour === undefined ? {} : { background: cssColour(bgColour) }),
|
|
121
|
+
...(cols > 0 ? { cellWidth: columnWidths(grid, cols) } : {}),
|
|
122
|
+
// The chart measures the text it is about to draw and shrinks it to fit,
|
|
123
|
+
// which is the half of this that cannot be done from here.
|
|
124
|
+
fontSize: 'auto',
|
|
121
125
|
},
|
|
122
126
|
};
|
|
123
127
|
}
|
|
124
128
|
|
|
129
|
+
/**
|
|
130
|
+
* How wide each column has to be, in media pixels.
|
|
131
|
+
*
|
|
132
|
+
* The chart's default is one width for every column, chosen without seeing the
|
|
133
|
+
* text, and a grid whose header says "Moving averages" over cells saying
|
|
134
|
+
* "RSI: 27.22" has one column bleeding into the next. Nothing downstream can
|
|
135
|
+
* choose better, because by the time the chart has the grid it has lost which
|
|
136
|
+
* cells belong together; and nothing upstream can, because the script declares
|
|
137
|
+
* a size and writes text, not a layout.
|
|
138
|
+
*
|
|
139
|
+
* **This is an estimate, and it is allowed to be.** A real width needs the font
|
|
140
|
+
* the chart will draw with, and only the chart has it. So the width is counted
|
|
141
|
+
* off the characters and the chart's own `fontSize: 'auto'` corrects whatever
|
|
142
|
+
* this gets wrong: too narrow and the type shrinks a little, too wide and the
|
|
143
|
+
* column is a little loose. Either is a table that reads. The failure this
|
|
144
|
+
* replaces was neither.
|
|
145
|
+
*
|
|
146
|
+
* Delete it when the chart can size a column from its own measurements. It
|
|
147
|
+
* exists because that is not a thing it can be asked to do yet.
|
|
148
|
+
*/
|
|
149
|
+
function columnWidths(grid: readonly (readonly ChartCell[])[], cols: number): number[] {
|
|
150
|
+
const widths: number[] = [];
|
|
151
|
+
for (let col = 0; col < cols; col += 1) {
|
|
152
|
+
let widest = 0;
|
|
153
|
+
for (const row of grid) {
|
|
154
|
+
const text = row[col]?.text ?? '';
|
|
155
|
+
if (text.length > 0) widest = Math.max(widest, textWidth(text));
|
|
156
|
+
}
|
|
157
|
+
widths.push(Math.min(MAX_COLUMN, Math.max(MIN_COLUMN, Math.ceil(widest) + CELL_PADDING * 2)));
|
|
158
|
+
}
|
|
159
|
+
return widths;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Roughly how wide a string is at the type size the chart starts from.
|
|
164
|
+
*
|
|
165
|
+
* Counted rather than measured, and counted in two weights rather than one: a
|
|
166
|
+
* column of "Histogram: -7.01" is half punctuation and narrow digits, and
|
|
167
|
+
* treating every character as an em-and-a-bit makes that column half again as
|
|
168
|
+
* wide as it needs to be while "Moving averages" stays too narrow. Two weights
|
|
169
|
+
* is not typography, but it is enough to tell those two apart.
|
|
170
|
+
*/
|
|
171
|
+
function textWidth(text: string): number {
|
|
172
|
+
let width = 0;
|
|
173
|
+
for (const character of text) {
|
|
174
|
+
width += NARROW.has(character) ? BASE_SIZE * NARROW_EM : BASE_SIZE * WIDE_EM;
|
|
175
|
+
}
|
|
176
|
+
return width;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** The characters that take noticeably less than an average advance. */
|
|
180
|
+
const NARROW = new Set([...' .,:;!|ijlt1IJfr()[]{}-']);
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The type size the widths are counted at.
|
|
184
|
+
*
|
|
185
|
+
* The chart's own default row is 18 media pixels and it draws at 62% of the
|
|
186
|
+
* row, so this is the size a cell gets before anything shrinks it. Counting at
|
|
187
|
+
* a larger size would reserve room the text never uses.
|
|
188
|
+
*/
|
|
189
|
+
const BASE_SIZE = 11;
|
|
190
|
+
const NARROW_EM = 0.32;
|
|
191
|
+
const WIDE_EM = 0.56;
|
|
192
|
+
|
|
193
|
+
/** What the chart insets a cell's text by, on each side. */
|
|
194
|
+
const CELL_PADDING = 4;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* The narrowest a column is drawn.
|
|
198
|
+
*
|
|
199
|
+
* A column of one-character cells sized to its content is a sliver, and a grid
|
|
200
|
+
* of slivers reads as a rendering fault rather than as a narrow column.
|
|
201
|
+
*/
|
|
202
|
+
const MIN_COLUMN = 56;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* The widest a column is drawn.
|
|
206
|
+
*
|
|
207
|
+
* A cell holding a sentence would otherwise push the grid past the pane it is
|
|
208
|
+
* pinned inside, taking the chart with it. Past this the type shrinks instead,
|
|
209
|
+
* which is the chart's job and it is better at it.
|
|
210
|
+
*/
|
|
211
|
+
const MAX_COLUMN = 220;
|
|
212
|
+
|
|
125
213
|
/**
|
|
126
214
|
* One written cell, or none.
|
|
127
215
|
*
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Laying a script out again, as an editor command.
|
|
3
|
+
*
|
|
4
|
+
* `format` is the tier's, and the guarantee it carries is the one that makes a
|
|
5
|
+
* format button safe to put in front of somebody holding a position: laying a
|
|
6
|
+
* script out again cannot change what it computes. Every example and every gate
|
|
7
|
+
* script in the repository is formatted, both texts compiled, and the compiled
|
|
8
|
+
* programs compared field for field; and every call checks itself against the
|
|
9
|
+
* lexer, so a rule that is wrong returns the source untouched rather than a
|
|
10
|
+
* changed program.
|
|
11
|
+
*
|
|
12
|
+
* The whole document is replaced rather than a minimal edit computed. It is the
|
|
13
|
+
* honest version: a diff would have to be trusted to be equivalent to the
|
|
14
|
+
* replacement, and a formatter that moved a line somewhere unintended would do
|
|
15
|
+
* it silently. The cursor is kept where it was in the new text, clamped, because
|
|
16
|
+
* a format that sends the caret to the top of the file is a format nobody
|
|
17
|
+
* presses twice.
|
|
18
|
+
*
|
|
19
|
+
* **A document with two character line endings comes back with one character
|
|
20
|
+
* ones**, because that is what `language.md` 3.1 normalises a file to before
|
|
21
|
+
* anything reads it and what every offset in this tier indexes. It is the one
|
|
22
|
+
* change to a file's bytes that formatting makes without being asked, and it is
|
|
23
|
+
* recorded in `spec/editor-narrowings.json`.
|
|
24
|
+
*/
|
|
25
|
+
import { format } from '../../editor/index.js';
|
|
26
|
+
import type { EditorView } from './contract.js';
|
|
27
|
+
import { documentOf, normalisedOffset } from './positions.js';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Lays the document out again, and says whether anything changed.
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* keymap.of([{ key: "Shift-Alt-f", run: formatDocument }])
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* False where the document is already laid out, which is what an editor command
|
|
37
|
+
* returns when it has nothing to do: the key press then falls through to
|
|
38
|
+
* whatever else is bound to it rather than being swallowed.
|
|
39
|
+
*/
|
|
40
|
+
export function formatDocument(view: EditorView): boolean {
|
|
41
|
+
const raw = view.state.doc.toString();
|
|
42
|
+
const held = documentOf(raw);
|
|
43
|
+
const laid = format(held.text);
|
|
44
|
+
if (laid === raw) return false;
|
|
45
|
+
|
|
46
|
+
const at = normalisedOffset(held, view.state.selection.main.head);
|
|
47
|
+
view.dispatch({
|
|
48
|
+
changes: { from: 0, to: view.state.doc.length, insert: laid },
|
|
49
|
+
selection: { anchor: Math.min(at, laid.length) },
|
|
50
|
+
scrollIntoView: true,
|
|
51
|
+
});
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Completions, as the editor's completion source.
|
|
3
|
+
*
|
|
4
|
+
* The whole of the work is done by `complete`, which reads the standard library
|
|
5
|
+
* manifest, the checker's bindings and the error catalogue. What is here is the
|
|
6
|
+
* translation: the editor wants a range to replace, a list of rows, and a note
|
|
7
|
+
* about whether the list is already filtered.
|
|
8
|
+
*
|
|
9
|
+
* **The list is already filtered**, by the word the writer has typed, compared
|
|
10
|
+
* exactly, because the language's names are case sensitive. So `filter` is false
|
|
11
|
+
* and the editor is told not to filter it again: its own matcher is fuzzy and
|
|
12
|
+
* case insensitive, and running it over a list that has already answered the
|
|
13
|
+
* question would put `EMA` in front of somebody as though it compiled.
|
|
14
|
+
*
|
|
15
|
+
* **A planned call is shown and marked.** `complete` carries the catalogue's own
|
|
16
|
+
* OS2020 sentence on a planned row, so that is what goes in the row's expanded
|
|
17
|
+
* note, and the row is pushed to the bottom of the list with the editor's own
|
|
18
|
+
* boost. A host that would rather not show them at all drops them with one
|
|
19
|
+
* field, which is why they are marked rather than filtered here.
|
|
20
|
+
*/
|
|
21
|
+
import { complete } from '../../editor/index.js';
|
|
22
|
+
import type { Completion } from '../../editor/index.js';
|
|
23
|
+
import type {
|
|
24
|
+
EditorCompletion,
|
|
25
|
+
EditorCompletionContext,
|
|
26
|
+
EditorCompletionResult,
|
|
27
|
+
} from './contract.js';
|
|
28
|
+
import { COMPLETION_TYPES } from './tokens.js';
|
|
29
|
+
|
|
30
|
+
/** As far down the list as the editor will move a row. */
|
|
31
|
+
const PLANNED_BOOST = -99;
|
|
32
|
+
|
|
33
|
+
function rowOf(one: Completion): EditorCompletion {
|
|
34
|
+
const info = one.refusal ?? one.summary;
|
|
35
|
+
const type = COMPLETION_TYPES[one.kind];
|
|
36
|
+
return {
|
|
37
|
+
label: one.label,
|
|
38
|
+
...(type === undefined ? {} : { type }),
|
|
39
|
+
detail: one.detail,
|
|
40
|
+
...(info === undefined ? {} : { info }),
|
|
41
|
+
...(one.insert === one.label ? {} : { apply: one.insert }),
|
|
42
|
+
...(one.planned ? { boost: PLANNED_BOOST } : {}),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Every completion for the position the editor is asking about.
|
|
48
|
+
*
|
|
49
|
+
* ```ts
|
|
50
|
+
* autocompletion({ override: [openscriptCompletion] })
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* Nothing comes back for an empty list rather than an empty list, because the
|
|
54
|
+
* editor reads the two differently: an empty result closes the panel and null
|
|
55
|
+
* lets another source answer, and a host with a snippet source of its own should
|
|
56
|
+
* keep it.
|
|
57
|
+
*/
|
|
58
|
+
export function openscriptCompletion(
|
|
59
|
+
context: EditorCompletionContext,
|
|
60
|
+
): EditorCompletionResult | null {
|
|
61
|
+
const rows = complete(context.state.doc.toString(), context.pos);
|
|
62
|
+
// The first row carries the range every row replaces, so an empty list and a
|
|
63
|
+
// list whose first row is missing are one answer: nothing. Two guards for that
|
|
64
|
+
// would be one guard and a line no test can reach.
|
|
65
|
+
const first = rows[0];
|
|
66
|
+
if (first === undefined) return null;
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
from: first.replace.offset,
|
|
70
|
+
to: first.replace.offset + first.replace.length,
|
|
71
|
+
options: rows.map(rowOf),
|
|
72
|
+
filter: false,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editor component's own shapes, as this adapter targets them.
|
|
3
|
+
*
|
|
4
|
+
* **Why they are declared here rather than imported.** The editor component is a
|
|
5
|
+
* peer dependency: a host that wants a text area installs it, and a host that
|
|
6
|
+
* wants only the language must not be made to. This repository therefore does
|
|
7
|
+
* not install it, cannot type check against it, and would fail its own layering
|
|
8
|
+
* check the moment a file here imported it. It is the same decision the chart
|
|
9
|
+
* adapter took, for the same reason, and `src/adapters/charts/contract.ts` says
|
|
10
|
+
* it at length.
|
|
11
|
+
*
|
|
12
|
+
* So the shapes this produces values for are declared below and the host's own
|
|
13
|
+
* build is where the two meet. Each one is a one line check that costs a host
|
|
14
|
+
* nothing and fails to compile if this file has drifted:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* import type { StreamParser } from "<the editor's language package>";
|
|
18
|
+
* import type { CompletionSource } from "<the editor's completion package>";
|
|
19
|
+
* import type { Diagnostic } from "<the editor's lint package>";
|
|
20
|
+
*
|
|
21
|
+
* const parser: StreamParser<unknown> = openscriptStream;
|
|
22
|
+
* const source: CompletionSource = openscriptCompletion;
|
|
23
|
+
* const linter: (view: EditorView) => Diagnostic[] = openscriptLint;
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* **That line catches a value of the wrong shape and not an argument of the
|
|
27
|
+
* wrong shape.** A method's parameters are compared in both directions, so a
|
|
28
|
+
* hook declared here as taking something the editor never passes still assigns.
|
|
29
|
+
* That is the failure the chart adapter has actually made, so every member below
|
|
30
|
+
* takes the editor's own argument, spelled as the editor spells it, and every
|
|
31
|
+
* test drives each one with the argument the editor passes rather than with one
|
|
32
|
+
* of its own.
|
|
33
|
+
*
|
|
34
|
+
* **A style name is not checked by any of those lines.** The names this adapter
|
|
35
|
+
* returns from `token` are looked up by the editor in its own table of
|
|
36
|
+
* highlighting tags at run time, and an unknown one is a warning on a console
|
|
37
|
+
* rather than a compile error. That is why the whole mapping is one exported
|
|
38
|
+
* record a host can replace in a line, and why it is recorded in
|
|
39
|
+
* `spec/editor-narrowings.json` as the one thing here a type cannot hold.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* One line of the document, as the editor's tokenizer sees it.
|
|
44
|
+
*
|
|
45
|
+
* The editor hands a tokenizer a line at a time and expects `pos` to have moved
|
|
46
|
+
* forward when `token` returns. Only the members this adapter reads are
|
|
47
|
+
* declared: a narrower shape is still assignable from the editor's wider one.
|
|
48
|
+
*/
|
|
49
|
+
export interface EditorStringStream {
|
|
50
|
+
/** The line's text, without its line ending. */
|
|
51
|
+
readonly string: string;
|
|
52
|
+
/** Where the tokenizer has got to, which this adapter moves. */
|
|
53
|
+
pos: number;
|
|
54
|
+
/** Where the current token began. */
|
|
55
|
+
readonly start: number;
|
|
56
|
+
/** Whether `pos` is at the end of the line. */
|
|
57
|
+
eol(): boolean;
|
|
58
|
+
/** Whether `pos` is at the start of the line. */
|
|
59
|
+
sol(): boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A tokenizer the editor drives one line at a time.
|
|
64
|
+
*
|
|
65
|
+
* `token` returns a style name, or null for text with no style of its own. The
|
|
66
|
+
* state is the tokenizer's to define, and the editor copies it at line
|
|
67
|
+
* boundaries so that it can restart mid document, which is why `copyState` is
|
|
68
|
+
* here.
|
|
69
|
+
*/
|
|
70
|
+
export interface EditorStreamParser<State> {
|
|
71
|
+
readonly name?: string;
|
|
72
|
+
startState?(indentUnit: number): State;
|
|
73
|
+
token(stream: EditorStringStream, state: State): string | null;
|
|
74
|
+
copyState?(state: State): State;
|
|
75
|
+
blankLine?(state: State, indentUnit: number): void;
|
|
76
|
+
readonly languageData?: Readonly<Record<string, unknown>>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The document, which the editor holds as a rope rather than as a string. */
|
|
80
|
+
export interface EditorText {
|
|
81
|
+
readonly length: number;
|
|
82
|
+
toString(): string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The part of the editor's state this adapter reads. */
|
|
86
|
+
export interface EditorState {
|
|
87
|
+
readonly doc: EditorText;
|
|
88
|
+
readonly selection: {
|
|
89
|
+
readonly main: { readonly head: number; readonly from: number; readonly to: number };
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** The part of the editor's view this adapter reads and dispatches to. */
|
|
94
|
+
export interface EditorView {
|
|
95
|
+
readonly state: EditorState;
|
|
96
|
+
dispatch(transaction: {
|
|
97
|
+
readonly changes: { readonly from: number; readonly to: number; readonly insert: string };
|
|
98
|
+
readonly selection?: { readonly anchor: number };
|
|
99
|
+
readonly scrollIntoView?: boolean;
|
|
100
|
+
}): void;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** What the editor hands a completion source. */
|
|
104
|
+
export interface EditorCompletionContext {
|
|
105
|
+
readonly state: EditorState;
|
|
106
|
+
readonly pos: number;
|
|
107
|
+
/** Whether the writer asked for completions rather than merely typing. */
|
|
108
|
+
readonly explicit: boolean;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** One row of the editor's completion list. */
|
|
112
|
+
export interface EditorCompletion {
|
|
113
|
+
readonly label: string;
|
|
114
|
+
/** The editor's own name for the icon beside a row. */
|
|
115
|
+
readonly type?: string;
|
|
116
|
+
readonly detail?: string;
|
|
117
|
+
readonly info?: string;
|
|
118
|
+
/** The text to insert, where it differs from the label. */
|
|
119
|
+
readonly apply?: string;
|
|
120
|
+
/** Moves a row up or down the list, from -99 to 99. */
|
|
121
|
+
readonly boost?: number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface EditorCompletionResult {
|
|
125
|
+
readonly from: number;
|
|
126
|
+
readonly to?: number;
|
|
127
|
+
readonly options: readonly EditorCompletion[];
|
|
128
|
+
/** False when the list is already filtered, which this adapter's is. */
|
|
129
|
+
readonly filter?: boolean;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** One squiggle in the editor's lint panel and gutter. */
|
|
133
|
+
export interface EditorDiagnostic {
|
|
134
|
+
readonly from: number;
|
|
135
|
+
readonly to: number;
|
|
136
|
+
readonly severity: 'hint' | 'info' | 'warning' | 'error';
|
|
137
|
+
readonly message: string;
|
|
138
|
+
/** Where the diagnostic came from, shown beside the message. */
|
|
139
|
+
readonly source?: string;
|
|
140
|
+
readonly actions?: readonly {
|
|
141
|
+
readonly name: string;
|
|
142
|
+
apply(view: EditorView, from: number, to: number): void;
|
|
143
|
+
}[];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** What the editor shows over the text, and the element it shows. */
|
|
147
|
+
export interface EditorTooltipView {
|
|
148
|
+
readonly dom: unknown;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface EditorTooltip {
|
|
152
|
+
readonly pos: number;
|
|
153
|
+
readonly end?: number;
|
|
154
|
+
readonly above?: boolean;
|
|
155
|
+
create(view: EditorView): EditorTooltipView;
|
|
156
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editor adapter: the language intelligence, wired into a text component.
|
|
3
|
+
*
|
|
4
|
+
* This and the chart adapter are the only modules in the repository allowed to
|
|
5
|
+
* know two worlds at once, and it is the piece a platform with its own editor
|
|
6
|
+
* replaces rather than the piece it patches. Everything under `src/editor` stays
|
|
7
|
+
* ignorant of any component, and the layering check is what keeps it that way.
|
|
8
|
+
*
|
|
9
|
+
* **The editor component is a peer dependency, and nothing here imports it.** A
|
|
10
|
+
* package that pulled a text component into everyone's install would defeat the
|
|
11
|
+
* point of a language a platform can take on its own, so the shapes this
|
|
12
|
+
* produces are declared in `contract.ts` and the host's own build is where the
|
|
13
|
+
* two are compared, in one line per piece. See that file for the lines. The
|
|
14
|
+
* entry point resolves and every function here runs in an install that holds no
|
|
15
|
+
* editor at all, which `scripts/check-entry-points.mjs` proves on every build.
|
|
16
|
+
*
|
|
17
|
+
* Six functions in, five pieces out:
|
|
18
|
+
*
|
|
19
|
+
* openscriptStream highlighting, a line at a time
|
|
20
|
+
* openscriptCompletion the completion list
|
|
21
|
+
* openscriptLint errors as you type, with their fixes
|
|
22
|
+
* openscriptHoverTooltip what the thing under the pointer is
|
|
23
|
+
* openscriptSignatureTooltip the call being written
|
|
24
|
+
* formatDocument lay the script out again
|
|
25
|
+
*
|
|
26
|
+
* The two tooltips take the markup as a parameter and have no default for it, so
|
|
27
|
+
* nothing in this package names a browser global at any tier. A host that wants
|
|
28
|
+
* none of this calls the six functions itself and draws its own. That is not the fallback, it is the supported path: what a host gives up
|
|
29
|
+
* by taking these instead is recorded in `spec/editor-narrowings.json`, which is
|
|
30
|
+
* three lines long and worth reading before choosing.
|
|
31
|
+
*/
|
|
32
|
+
export type {
|
|
33
|
+
EditorCompletion,
|
|
34
|
+
EditorCompletionContext,
|
|
35
|
+
EditorCompletionResult,
|
|
36
|
+
EditorDiagnostic,
|
|
37
|
+
EditorState,
|
|
38
|
+
EditorStreamParser,
|
|
39
|
+
EditorStringStream,
|
|
40
|
+
EditorText,
|
|
41
|
+
EditorTooltip,
|
|
42
|
+
EditorTooltipView,
|
|
43
|
+
EditorView,
|
|
44
|
+
} from './contract.js';
|
|
45
|
+
|
|
46
|
+
export { COMPLETION_TYPES, HIGHLIGHT_TOKENS } from './tokens.js';
|
|
47
|
+
|
|
48
|
+
export type { StreamState } from './stream.js';
|
|
49
|
+
export { openscriptStream } from './stream.js';
|
|
50
|
+
|
|
51
|
+
export { openscriptCompletion } from './completion.js';
|
|
52
|
+
|
|
53
|
+
export { diagnosticsFor, openscriptLint } from './lint.js';
|
|
54
|
+
|
|
55
|
+
export type { Renderer } from './tooltips.js';
|
|
56
|
+
export {
|
|
57
|
+
hoverLines,
|
|
58
|
+
openscriptHoverTooltip,
|
|
59
|
+
openscriptSignatureTooltip,
|
|
60
|
+
signatureLines,
|
|
61
|
+
} from './tooltips.js';
|
|
62
|
+
|
|
63
|
+
export { formatDocument } from './commands.js';
|
|
64
|
+
|
|
65
|
+
export type { Document } from './positions.js';
|
|
66
|
+
export { documentOf, normalisedOffset } from './positions.js';
|