@promptctl/rich-js 0.7.0 → 0.9.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/README.md +99 -31
- package/dist/core/box.d.ts +96 -42
- package/dist/core/box.d.ts.map +1 -1
- package/dist/core/box.js +348 -490
- package/dist/core/box.js.map +1 -1
- package/dist/core/cells.d.ts +46 -1
- package/dist/core/cells.d.ts.map +1 -1
- package/dist/core/cells.js +55 -14
- package/dist/core/cells.js.map +1 -1
- package/dist/core/color.d.ts.map +1 -1
- package/dist/core/color.js +22 -8
- package/dist/core/color.js.map +1 -1
- package/dist/core/console.d.ts +30 -14
- package/dist/core/console.d.ts.map +1 -1
- package/dist/core/console.js +176 -104
- package/dist/core/console.js.map +1 -1
- package/dist/core/highlighter.d.ts +2 -1
- package/dist/core/highlighter.d.ts.map +1 -1
- package/dist/core/highlighter.js +28 -6
- package/dist/core/highlighter.js.map +1 -1
- package/dist/{renderables → core}/json.d.ts +8 -3
- package/dist/core/json.d.ts.map +1 -0
- package/dist/{renderables → core}/json.js +7 -2
- package/dist/core/json.js.map +1 -0
- package/dist/core/markup.d.ts +6 -9
- package/dist/core/markup.d.ts.map +1 -1
- package/dist/core/markup.js +153 -47
- package/dist/core/markup.js.map +1 -1
- package/dist/core/measure.d.ts +11 -0
- package/dist/core/measure.d.ts.map +1 -1
- package/dist/core/measure.js +15 -3
- package/dist/core/measure.js.map +1 -1
- package/dist/core/oklch.d.ts +22 -0
- package/dist/core/oklch.d.ts.map +1 -1
- package/dist/core/oklch.js +62 -18
- package/dist/core/oklch.js.map +1 -1
- package/dist/core/pretty.d.ts +122 -0
- package/dist/core/pretty.d.ts.map +1 -0
- package/dist/core/pretty.js +398 -0
- package/dist/core/pretty.js.map +1 -0
- package/dist/core/protocol.d.ts +80 -0
- package/dist/core/protocol.d.ts.map +1 -1
- package/dist/core/protocol.js +85 -0
- package/dist/core/protocol.js.map +1 -1
- package/dist/core/segment.d.ts +26 -0
- package/dist/core/segment.d.ts.map +1 -1
- package/dist/core/segment.js +45 -0
- package/dist/core/segment.js.map +1 -1
- package/dist/core/strip.d.ts +9 -5
- package/dist/core/strip.d.ts.map +1 -1
- package/dist/core/strip.js +39 -41
- package/dist/core/strip.js.map +1 -1
- package/dist/core/style.d.ts +19 -0
- package/dist/core/style.d.ts.map +1 -1
- package/dist/core/style.js +46 -38
- package/dist/core/style.js.map +1 -1
- package/dist/core/subscription.d.ts +13 -0
- package/dist/core/subscription.d.ts.map +1 -0
- package/dist/core/subscription.js +13 -0
- package/dist/core/subscription.js.map +1 -0
- package/dist/core/text.d.ts +102 -4
- package/dist/core/text.d.ts.map +1 -1
- package/dist/core/text.js +332 -162
- package/dist/core/text.js.map +1 -1
- package/dist/core/wrap.d.ts +42 -0
- package/dist/core/wrap.d.ts.map +1 -0
- package/dist/core/wrap.js +128 -0
- package/dist/core/wrap.js.map +1 -0
- package/dist/host/host-stream.d.ts.map +1 -0
- package/dist/host/host-stream.js.map +1 -0
- package/dist/host/index.d.ts +4 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +3 -0
- package/dist/host/index.js.map +1 -0
- package/dist/{widgets → host}/terminal-host.d.ts +20 -64
- package/dist/host/terminal-host.d.ts.map +1 -0
- package/dist/host/terminal-host.js +133 -0
- package/dist/host/terminal-host.js.map +1 -0
- package/dist/index.d.ts +13 -36
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -22
- package/dist/index.js.map +1 -1
- package/dist/node/terminal-host.d.ts +85 -0
- package/dist/node/terminal-host.d.ts.map +1 -0
- package/dist/node/terminal-host.js +161 -0
- package/dist/node/terminal-host.js.map +1 -0
- package/dist/node/traceback.d.ts +28 -0
- package/dist/node/traceback.d.ts.map +1 -0
- package/dist/node/traceback.js +113 -0
- package/dist/node/traceback.js.map +1 -0
- package/dist/renderables/columns.d.ts +24 -2
- package/dist/renderables/columns.d.ts.map +1 -1
- package/dist/renderables/columns.js +91 -32
- package/dist/renderables/columns.js.map +1 -1
- package/dist/renderables/layout.d.ts +61 -5
- package/dist/renderables/layout.d.ts.map +1 -1
- package/dist/renderables/layout.js +191 -19
- package/dist/renderables/layout.js.map +1 -1
- package/dist/renderables/markdown.d.ts +1 -1
- package/dist/renderables/markdown.d.ts.map +1 -1
- package/dist/renderables/markdown.js +7 -14
- package/dist/renderables/markdown.js.map +1 -1
- package/dist/renderables/padding.d.ts +16 -3
- package/dist/renderables/padding.d.ts.map +1 -1
- package/dist/renderables/padding.js +96 -47
- package/dist/renderables/padding.js.map +1 -1
- package/dist/renderables/panel.d.ts +48 -7
- package/dist/renderables/panel.d.ts.map +1 -1
- package/dist/renderables/panel.js +175 -106
- package/dist/renderables/panel.js.map +1 -1
- package/dist/renderables/progress.d.ts +3 -3
- package/dist/renderables/progress.d.ts.map +1 -1
- package/dist/renderables/progress.js +11 -9
- package/dist/renderables/progress.js.map +1 -1
- package/dist/renderables/progressBar.d.ts +3 -3
- package/dist/renderables/progressBar.d.ts.map +1 -1
- package/dist/renderables/progressBar.js +9 -15
- package/dist/renderables/progressBar.js.map +1 -1
- package/dist/renderables/prompt.js +1 -1
- package/dist/renderables/prompt.js.map +1 -1
- package/dist/renderables/rule.d.ts +1 -1
- package/dist/renderables/rule.d.ts.map +1 -1
- package/dist/renderables/rule.js +5 -10
- package/dist/renderables/rule.js.map +1 -1
- package/dist/renderables/spinner.d.ts +2 -2
- package/dist/renderables/spinner.d.ts.map +1 -1
- package/dist/renderables/spinner.js +6 -11
- package/dist/renderables/spinner.js.map +1 -1
- package/dist/renderables/status.d.ts.map +1 -1
- package/dist/renderables/status.js +5 -11
- package/dist/renderables/status.js.map +1 -1
- package/dist/renderables/table.d.ts +90 -16
- package/dist/renderables/table.d.ts.map +1 -1
- package/dist/renderables/table.js +481 -223
- package/dist/renderables/table.js.map +1 -1
- package/dist/renderables/traceback.d.ts +7 -3
- package/dist/renderables/traceback.d.ts.map +1 -1
- package/dist/renderables/traceback.js +15 -18
- package/dist/renderables/traceback.js.map +1 -1
- package/dist/renderables/tree.d.ts +29 -4
- package/dist/renderables/tree.d.ts.map +1 -1
- package/dist/renderables/tree.js +86 -33
- package/dist/renderables/tree.js.map +1 -1
- package/dist/template-bindings/color-funcs.d.ts +3 -3
- package/dist/template-bindings/color-funcs.js +3 -3
- package/dist/template-bindings/helpers.d.ts.map +1 -1
- package/dist/template-bindings/helpers.js +19 -1
- package/dist/template-bindings/helpers.js.map +1 -1
- package/dist/template-bindings/index.d.ts +6 -7
- package/dist/template-bindings/index.d.ts.map +1 -1
- package/dist/template-bindings/index.js +6 -7
- package/dist/template-bindings/index.js.map +1 -1
- package/dist/template-bindings/palette-funcs.d.ts +17 -5
- package/dist/template-bindings/palette-funcs.d.ts.map +1 -1
- package/dist/template-bindings/palette-funcs.js +69 -6
- package/dist/template-bindings/palette-funcs.js.map +1 -1
- package/dist/template-bindings/style-funcs.d.ts +1 -1
- package/dist/template-bindings/style-funcs.js +1 -1
- package/dist/themes/ramp.d.ts +84 -0
- package/dist/themes/ramp.d.ts.map +1 -0
- package/dist/themes/ramp.js +123 -0
- package/dist/themes/ramp.js.map +1 -0
- package/dist/widgets/dropdown.d.ts +1 -1
- package/dist/widgets/dropdown.js +1 -1
- package/dist/widgets/event-router.d.ts +3 -2
- package/dist/widgets/event-router.d.ts.map +1 -1
- package/dist/widgets/focus-manager.d.ts +2 -1
- package/dist/widgets/focus-manager.d.ts.map +1 -1
- package/dist/widgets/index.d.ts +3 -6
- package/dist/widgets/index.d.ts.map +1 -1
- package/dist/widgets/index.js +4 -3
- package/dist/widgets/index.js.map +1 -1
- package/dist/widgets/screen.d.ts +1 -1
- package/dist/widgets/screen.d.ts.map +1 -1
- package/dist/widgets/text-input.d.ts +2 -3
- package/dist/widgets/text-input.d.ts.map +1 -1
- package/dist/widgets/text-input.js +4 -12
- package/dist/widgets/text-input.js.map +1 -1
- package/dist/widgets/types.d.ts +1 -1
- package/dist/widgets/types.d.ts.map +1 -1
- package/dist/widgets/types.js.map +1 -1
- package/dist/widgets/widget-base.d.ts +2 -1
- package/dist/widgets/widget-base.d.ts.map +1 -1
- package/package.json +38 -6
- package/dist/renderables/json.d.ts.map +0 -1
- package/dist/renderables/json.js.map +0 -1
- package/dist/renderables/pretty.d.ts +0 -29
- package/dist/renderables/pretty.d.ts.map +0 -1
- package/dist/renderables/pretty.js +0 -141
- package/dist/renderables/pretty.js.map +0 -1
- package/dist/themes/paletteResolver.d.ts +0 -35
- package/dist/themes/paletteResolver.d.ts.map +0 -1
- package/dist/themes/paletteResolver.js +0 -88
- package/dist/themes/paletteResolver.js.map +0 -1
- package/dist/widgets/host-stream.d.ts.map +0 -1
- package/dist/widgets/host-stream.js.map +0 -1
- package/dist/widgets/terminal-host.d.ts.map +0 -1
- package/dist/widgets/terminal-host.js +0 -258
- package/dist/widgets/terminal-host.js.map +0 -1
- /package/dist/{widgets → host}/host-stream.d.ts +0 -0
- /package/dist/{widgets → host}/host-stream.js +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* node:traceback — install `Traceback` as the process-wide crash renderer.
|
|
3
|
+
*
|
|
4
|
+
* [LAW:locality-or-seam] `process.on` / `process.exit` live only here, on the
|
|
5
|
+
* node side of the API boundary. The `Traceback` renderable itself is pure
|
|
6
|
+
* rendering and stays in the browser-safe barrel; installing it as a global
|
|
7
|
+
* handler is a node capability, so it is a node subpath:
|
|
8
|
+
*
|
|
9
|
+
* import { installTraceback } from "@promptctl/rich-js/node/traceback";
|
|
10
|
+
* installTraceback({ suppress: ["node_modules"] });
|
|
11
|
+
*
|
|
12
|
+
* [LAW:dataflow-not-control-flow] Both crash channels register the same
|
|
13
|
+
* `report` function, unadapted. Neither payload is trusted to be an `Error`:
|
|
14
|
+
* `@types/node` annotates `uncaughtException` with `Error`, but `throw "boom"`
|
|
15
|
+
* delivers the raw string, so the annotation is a claim about the common case
|
|
16
|
+
* rather than a guarantee. `report` takes `unknown` and both channels are
|
|
17
|
+
* literally one code path.
|
|
18
|
+
*/
|
|
19
|
+
import { inspect, types } from "node:util";
|
|
20
|
+
import { Console } from "../core/console.js";
|
|
21
|
+
import { Traceback } from "../renderables/traceback.js";
|
|
22
|
+
/** A payload's own stack, when it carries one, or `""` when it does not. */
|
|
23
|
+
function stackOf(reason) {
|
|
24
|
+
if (typeof reason !== "object" || reason === null)
|
|
25
|
+
return "";
|
|
26
|
+
if (!("stack" in reason))
|
|
27
|
+
return "";
|
|
28
|
+
return typeof reason.stack === "string" ? reason.stack : "";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* [LAW:parse-dont-validate] The checkpoint between a crash payload, which node
|
|
32
|
+
* allows to be any value at all, and `Traceback`, which renders an `Error`.
|
|
33
|
+
* The return type is the proof: nothing downstream re-asks whether the payload
|
|
34
|
+
* was throwable, and no raw value can reach the renderable to have `.name` and
|
|
35
|
+
* `.message` read off it as `undefined`.
|
|
36
|
+
*
|
|
37
|
+
* The gate is `isNativeError`, not `instanceof Error`. An error thrown inside a
|
|
38
|
+
* `node:vm` context is a real error with real frames, but its prototype comes
|
|
39
|
+
* from that realm, so `instanceof` answers false and the frames would be
|
|
40
|
+
* discarded by the one component that exists to show them. `isNativeError`
|
|
41
|
+
* reads V8's internal error slot and is realm-independent.
|
|
42
|
+
*
|
|
43
|
+
* Whatever survives that gate is not an error, so it has no call site of its
|
|
44
|
+
* own; `stackOf` salvages a stack from a duck-typed thrower and otherwise
|
|
45
|
+
* leaves it empty rather than reporting the frames of this function, which
|
|
46
|
+
* point into rich-js and describe nothing about the fault. `inspect` renders
|
|
47
|
+
* every payload shape, including circular objects, where `String(reason)`
|
|
48
|
+
* would collapse them to `[object Object]`.
|
|
49
|
+
*/
|
|
50
|
+
function toError(reason) {
|
|
51
|
+
if (types.isNativeError(reason))
|
|
52
|
+
return reason;
|
|
53
|
+
const error = new Error(inspect(reason));
|
|
54
|
+
error.name = "NonError";
|
|
55
|
+
error.stack = stackOf(reason);
|
|
56
|
+
return error;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The handler currently registered, or a no-op standing in for "none yet".
|
|
60
|
+
*
|
|
61
|
+
* [LAW:no-shared-mutable-globals] The process listener registry is a shared
|
|
62
|
+
* global, so the handler installed into it gets a single owner here rather
|
|
63
|
+
* than a caller appending to it once per call. Holding the reference is what
|
|
64
|
+
* lets `installTraceback` replace rather than accumulate.
|
|
65
|
+
*
|
|
66
|
+
* [LAW:types-are-the-program] A no-op rather than `null`: `process.off` on an
|
|
67
|
+
* unregistered listener does nothing, so the first call needs no null check
|
|
68
|
+
* and no "have we installed yet" branch. There is no absent case to handle.
|
|
69
|
+
*/
|
|
70
|
+
let installed = () => { };
|
|
71
|
+
/**
|
|
72
|
+
* Register rich tracebacks for uncaught exceptions and unhandled rejections.
|
|
73
|
+
*
|
|
74
|
+
* Calling this more than once replaces the previous handler — the last call
|
|
75
|
+
* wins, options included — so a process always has exactly one rich crash
|
|
76
|
+
* renderer no matter how many entry points reach for it.
|
|
77
|
+
*/
|
|
78
|
+
export function installTraceback(options) {
|
|
79
|
+
// [LAW:no-ambient-temporal-coupling] "This process is already crashing" is
|
|
80
|
+
// lifecycle state with one owner, not a fact left to the interleaving of two
|
|
81
|
+
// writes. A cascade — cleanup code rejecting a promise while the first
|
|
82
|
+
// report is still draining — would otherwise start a second write and a
|
|
83
|
+
// second `process.exit(1)`, and whichever drained first would cut the other
|
|
84
|
+
// off mid-frame. The first crash is the fault and the rest is its wake, so
|
|
85
|
+
// one complete report of the fault beats two corrupt ones.
|
|
86
|
+
let crashing = false;
|
|
87
|
+
const report = (reason) => {
|
|
88
|
+
if (crashing)
|
|
89
|
+
return;
|
|
90
|
+
crashing = true;
|
|
91
|
+
// [LAW:effects-at-boundaries] Render to a string first, then perform one
|
|
92
|
+
// write. `beginCapture` redirects the console's sink without setting
|
|
93
|
+
// `file:`, so stderr's TTY status still drives colour depth — a `file:`
|
|
94
|
+
// sink would report `isTTY === false` and silently strip colour.
|
|
95
|
+
const out = new Console({ stderr: true });
|
|
96
|
+
out.beginCapture();
|
|
97
|
+
out.print(new Traceback(toError(reason), options));
|
|
98
|
+
// [LAW:no-silent-failure] Exit only once the bytes have drained. When
|
|
99
|
+
// stderr is a pipe (CI logs, `2>&1 | tee`), writes are asynchronous and
|
|
100
|
+
// an immediate `process.exit(1)` truncates the traceback at the pipe
|
|
101
|
+
// buffer — the longer the traceback, the more of it is lost, which is
|
|
102
|
+
// the reverse of what a crash report should do.
|
|
103
|
+
process.stderr.write(out.endCapture(), () => {
|
|
104
|
+
process.exit(1);
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
process.off("uncaughtException", installed);
|
|
108
|
+
process.off("unhandledRejection", installed);
|
|
109
|
+
process.on("uncaughtException", report);
|
|
110
|
+
process.on("unhandledRejection", report);
|
|
111
|
+
installed = report;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=traceback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceback.js","sourceRoot":"","sources":["../../src/node/traceback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAGxD,4EAA4E;AAC5E,SAAS,OAAO,CAAC,MAAe;IAC9B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7D,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,OAAO,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,OAAO,CAAC,MAAe;IAC9B,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;IACxB,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACH,IAAI,SAAS,GAA8B,GAAG,EAAE,GAAE,CAAC,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,2EAA2E;IAC3E,6EAA6E;IAC7E,uEAAuE;IACvE,wEAAwE;IACxE,4EAA4E;IAC5E,2EAA2E;IAC3E,2DAA2D;IAC3D,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,MAAM,GAAG,CAAC,MAAe,EAAQ,EAAE;QACvC,IAAI,QAAQ;YAAE,OAAO;QACrB,QAAQ,GAAG,IAAI,CAAC;QAEhB,yEAAyE;QACzE,qEAAqE;QACrE,wEAAwE;QACxE,iEAAiE;QACjE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,GAAG,CAAC,YAAY,EAAE,CAAC;QACnB,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QAEnD,sEAAsE;QACtE,wEAAwE;QACxE,qEAAqE;QACrE,sEAAsE;QACtE,gDAAgD;QAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE;YAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;IAE7C,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;IACzC,SAAS,GAAG,MAAM,CAAC;AACrB,CAAC"}
|
|
@@ -19,8 +19,30 @@ export declare class Columns implements Renderable, Measurable {
|
|
|
19
19
|
readonly columnFirst: boolean;
|
|
20
20
|
readonly gutterWidth: number;
|
|
21
21
|
constructor(items?: Iterable<unknown>, options?: ColumnsOptions);
|
|
22
|
-
render(
|
|
23
|
-
|
|
22
|
+
render(rawOptions: RenderOptions): Iterable<Segment>;
|
|
23
|
+
/**
|
|
24
|
+
* The requested width divided into columns, once.
|
|
25
|
+
*
|
|
26
|
+
* [LAW:single-enforcer] The three modes disagree only about how many columns
|
|
27
|
+
* there are and how wide each one is, so they disagree in one place. `render`
|
|
28
|
+
* lays out against this division and `_naturalWidth` is the width at which it
|
|
29
|
+
* comes out as one row of every item.
|
|
30
|
+
*/
|
|
31
|
+
private _divide;
|
|
32
|
+
/**
|
|
33
|
+
* The widest any one item wants to be.
|
|
34
|
+
*
|
|
35
|
+
* An item that cannot measure itself wants the offer, which is what `Panel`,
|
|
36
|
+
* `Padding`, `Layout` and `Tree` all answer for the same case — and under an
|
|
37
|
+
* unbounded offer that is `Infinity`, so `withBoundedWidth` throws and says
|
|
38
|
+
* the request was unanswerable. Counting it as one cell instead reported a
|
|
39
|
+
* natural width of 1, which resolved an unbounded offer to a single column and
|
|
40
|
+
* cropped forty cells of content down to `"x"` with no error at all.
|
|
41
|
+
*/
|
|
42
|
+
private _itemWidth;
|
|
43
|
+
/** The width at which every item sits on one row: n columns and the gutters between them. */
|
|
44
|
+
private _naturalWidth;
|
|
45
|
+
measure(rawOptions: RenderOptions): {
|
|
24
46
|
minimum: number;
|
|
25
47
|
maximum: number;
|
|
26
48
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../src/renderables/columns.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../src/renderables/columns.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;AAI7B,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AASD,qBAAa,OAAQ,YAAW,UAAU,EAAE,UAAU;IACpD,WAAW,EAAE,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc;IAgB9D,MAAM,CAAC,UAAU,EAAE,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IAqCrD;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO;IA+Bf;;;;;;;;;OASG;IACH,OAAO,CAAC,UAAU;IAalB,6FAA6F;IAC7F,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,UAAU,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAczE"}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
import { Segment } from "../core/segment.js";
|
|
5
5
|
import { Measurement } from "../core/measure.js";
|
|
6
6
|
import { RichText } from "../core/text.js";
|
|
7
|
-
import { isMeasurable } from "../core/protocol.js";
|
|
7
|
+
import { isMeasurable, withBoundedWidth, withCellWidth } from "../core/protocol.js";
|
|
8
|
+
import { cellCount } from "../core/cells.js";
|
|
8
9
|
function toRenderable(item) {
|
|
9
10
|
if (typeof item === "object" && item !== null && "render" in item) {
|
|
10
11
|
return item;
|
|
@@ -22,41 +23,29 @@ export class Columns {
|
|
|
22
23
|
this.renderables = items ? [...items].map(toRenderable) : [];
|
|
23
24
|
this.expand = options?.expand ?? false;
|
|
24
25
|
this.equal = options?.equal ?? false;
|
|
25
|
-
|
|
26
|
+
// A declared column width is a cell count like any other, and it reaches
|
|
27
|
+
// the layout without passing through `withCellWidth`, which parses only
|
|
28
|
+
// what the *caller of render* supplied. Left raw, `width: NaN` made
|
|
29
|
+
// `Math.max(1, NaN)` a NaN column count and `new Array` threw `Invalid
|
|
30
|
+
// array length` before a single column was laid out. Absence is preserved
|
|
31
|
+
// rather than parsed: `undefined` selects auto-fit, and `cellCount` would
|
|
32
|
+
// read it as a declared zero.
|
|
33
|
+
this.colWidth = options?.width === undefined ? undefined : cellCount(options.width);
|
|
26
34
|
this.columnFirst = options?.columnFirst ?? false;
|
|
27
35
|
this.gutterWidth = 2; // default gutter between columns
|
|
28
36
|
}
|
|
29
|
-
*render(
|
|
37
|
+
*render(rawOptions) {
|
|
30
38
|
const items = this.renderables;
|
|
31
39
|
if (items.length === 0)
|
|
32
40
|
return;
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
else if (this.equal) {
|
|
42
|
-
// Measure all items to find the widest
|
|
43
|
-
let maxItemWidth = 1;
|
|
44
|
-
for (const item of items) {
|
|
45
|
-
if (isMeasurable(item)) {
|
|
46
|
-
const m = Measurement.get(options, item);
|
|
47
|
-
maxItemWidth = Math.max(maxItemWidth, m.maximum);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
numCols = Math.max(1, Math.floor((maxWidth + this.gutterWidth) / (maxItemWidth + this.gutterWidth)));
|
|
51
|
-
const equalWidth = Math.floor((maxWidth - this.gutterWidth * (numCols - 1)) / numCols);
|
|
52
|
-
colWidths = new Array(numCols).fill(equalWidth);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
// Auto: fit as many columns as possible
|
|
56
|
-
numCols = Math.min(items.length, Math.max(1, Math.floor(maxWidth / 4)));
|
|
57
|
-
const colW = Math.floor((maxWidth - this.gutterWidth * (numCols - 1)) / numCols);
|
|
58
|
-
colWidths = new Array(numCols).fill(colW);
|
|
59
|
-
}
|
|
41
|
+
// The parsed options, not just a parsed local: `_divide` hands them to
|
|
42
|
+
// `Measurement.get`, and a raw NaN reaching it comes back as a NaN item
|
|
43
|
+
// width, then a NaN column count, then `Invalid array length` out of
|
|
44
|
+
// `new Array(numCols)` before a single column is laid out. An unbounded
|
|
45
|
+
// width reaches the same `new Array` by the same route, which is why the
|
|
46
|
+
// parse here is the bounded one.
|
|
47
|
+
const options = withBoundedWidth(rawOptions, this);
|
|
48
|
+
const { numCols, colWidths } = this._divide(options);
|
|
60
49
|
// Layout items into rows
|
|
61
50
|
const numRows = Math.ceil(items.length / numCols);
|
|
62
51
|
// [LAW:types-are-the-program] The element type is Renderable — any number
|
|
@@ -78,8 +67,78 @@ export class Columns {
|
|
|
78
67
|
yield* Segment.mergeHorizontal(cells, this.gutterWidth);
|
|
79
68
|
}
|
|
80
69
|
}
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
/**
|
|
71
|
+
* The requested width divided into columns, once.
|
|
72
|
+
*
|
|
73
|
+
* [LAW:single-enforcer] The three modes disagree only about how many columns
|
|
74
|
+
* there are and how wide each one is, so they disagree in one place. `render`
|
|
75
|
+
* lays out against this division and `_naturalWidth` is the width at which it
|
|
76
|
+
* comes out as one row of every item.
|
|
77
|
+
*/
|
|
78
|
+
_divide(options) {
|
|
79
|
+
const maxWidth = options.maxWidth;
|
|
80
|
+
const gutter = this.gutterWidth;
|
|
81
|
+
if (this.colWidth !== undefined) {
|
|
82
|
+
const numCols = Math.max(1, Math.floor((maxWidth + gutter) / (this.colWidth + gutter)));
|
|
83
|
+
return { numCols, colWidths: new Array(numCols).fill(this.colWidth) };
|
|
84
|
+
}
|
|
85
|
+
if (this.equal) {
|
|
86
|
+
const itemWidth = this._itemWidth(options);
|
|
87
|
+
const numCols = Math.max(1, Math.floor((maxWidth + gutter) / (itemWidth + gutter)));
|
|
88
|
+
const equalWidth = Math.floor((maxWidth - gutter * (numCols - 1)) / numCols);
|
|
89
|
+
return { numCols, colWidths: new Array(numCols).fill(equalWidth) };
|
|
90
|
+
}
|
|
91
|
+
// Auto: as many columns as the widest item fits into, capped at the item
|
|
92
|
+
// count. Sized from the content rather than from a flat four cells per
|
|
93
|
+
// column, because `_naturalWidth` below is the inverse of *this* expression
|
|
94
|
+
// and a constant has no inverse: six two-cell items reported a natural
|
|
95
|
+
// width of 22 and then wrapped into two rows at 22, since `floor(22 / 4)`
|
|
96
|
+
// is five columns no matter how narrow the items are.
|
|
97
|
+
const itemWidth = this._itemWidth(options);
|
|
98
|
+
const numCols = Math.min(this.renderables.length, Math.max(1, Math.floor((maxWidth + gutter) / (itemWidth + gutter))));
|
|
99
|
+
const colW = Math.floor((maxWidth - gutter * (numCols - 1)) / numCols);
|
|
100
|
+
return { numCols, colWidths: new Array(numCols).fill(colW) };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The widest any one item wants to be.
|
|
104
|
+
*
|
|
105
|
+
* An item that cannot measure itself wants the offer, which is what `Panel`,
|
|
106
|
+
* `Padding`, `Layout` and `Tree` all answer for the same case — and under an
|
|
107
|
+
* unbounded offer that is `Infinity`, so `withBoundedWidth` throws and says
|
|
108
|
+
* the request was unanswerable. Counting it as one cell instead reported a
|
|
109
|
+
* natural width of 1, which resolved an unbounded offer to a single column and
|
|
110
|
+
* cropped forty cells of content down to `"x"` with no error at all.
|
|
111
|
+
*/
|
|
112
|
+
_itemWidth(options) {
|
|
113
|
+
let widest = 1;
|
|
114
|
+
for (const item of this.renderables) {
|
|
115
|
+
widest = Math.max(widest, isMeasurable(item)
|
|
116
|
+
? Measurement.get(options, item).maximum
|
|
117
|
+
: options.maxWidth);
|
|
118
|
+
}
|
|
119
|
+
return widest;
|
|
120
|
+
}
|
|
121
|
+
/** The width at which every item sits on one row: n columns and the gutters between them. */
|
|
122
|
+
_naturalWidth(options) {
|
|
123
|
+
const count = this.renderables.length;
|
|
124
|
+
if (count === 0)
|
|
125
|
+
return 0;
|
|
126
|
+
const width = this.colWidth ?? this._itemWidth(options);
|
|
127
|
+
return count * width + this.gutterWidth * (count - 1);
|
|
128
|
+
}
|
|
129
|
+
measure(rawOptions) {
|
|
130
|
+
// A floor of one cell is what Columns asks for; the ceiling is what it was
|
|
131
|
+
// offered, and the ceiling wins. Stated as a bare `minimum: 1`, a Columns
|
|
132
|
+
// measured into no width at all reported the range 1..0 — a floor above
|
|
133
|
+
// its own ceiling, which the parent that asked cannot divide.
|
|
134
|
+
//
|
|
135
|
+
// The ceiling is not the whole answer, though: reported as the offer alone,
|
|
136
|
+
// a Columns claimed every cell it was shown, so `Panel` in fit mode drew a
|
|
137
|
+
// 40-cell frame around five cells of content and an unbounded offer came
|
|
138
|
+
// back unbounded.
|
|
139
|
+
const parsed = withCellWidth(rawOptions);
|
|
140
|
+
const maximum = Math.min(this._naturalWidth(parsed), parsed.maxWidth);
|
|
141
|
+
return { minimum: Math.min(1, maximum), maximum };
|
|
83
142
|
}
|
|
84
143
|
}
|
|
85
144
|
//# sourceMappingURL=columns.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"columns.js","sourceRoot":"","sources":["../../src/renderables/columns.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAO3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"columns.js","sourceRoot":"","sources":["../../src/renderables/columns.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,24 +12,80 @@ export interface LayoutOptions {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class Layout implements Renderable, Measurable {
|
|
14
14
|
name: string | undefined;
|
|
15
|
-
ratio: number;
|
|
16
|
-
size: number | undefined;
|
|
17
|
-
minimumSize: number;
|
|
18
15
|
visible: boolean;
|
|
16
|
+
private _ratio;
|
|
17
|
+
private _size;
|
|
18
|
+
private _minimumSize;
|
|
19
19
|
private _renderable;
|
|
20
20
|
private _children;
|
|
21
21
|
private _splitDirection;
|
|
22
22
|
constructor(renderable?: Renderable | string, options?: LayoutOptions);
|
|
23
|
+
/**
|
|
24
|
+
* The three declared numbers, parsed on assignment rather than at the
|
|
25
|
+
* constructor. All three are public and a caller reaches them long after
|
|
26
|
+
* construction — `layout.getByName("pane")!.ratio = -1` walked straight past a
|
|
27
|
+
* constructor-only parse and put a negative weight back into the division that
|
|
28
|
+
* `_rowBudgetFor` and `_distributeSpace` are written to trust.
|
|
29
|
+
*
|
|
30
|
+
* [LAW:parse-dont-validate] The setter is the border, so the guarantee holds
|
|
31
|
+
* for the object's whole lifetime and nothing downstream re-checks. `size` and
|
|
32
|
+
* `minimumSize` are cell counts; `ratio` is a share weight and keeps its
|
|
33
|
+
* fractions. Absence is preserved rather than parsed: an undefined `size`
|
|
34
|
+
* selects a flex pane, and `cellCount` would read it as a declared zero.
|
|
35
|
+
*/
|
|
36
|
+
get ratio(): number;
|
|
37
|
+
set ratio(value: number);
|
|
38
|
+
get size(): number | undefined;
|
|
39
|
+
set size(value: number | undefined);
|
|
40
|
+
get minimumSize(): number;
|
|
41
|
+
set minimumSize(value: number);
|
|
23
42
|
get children(): Layout[];
|
|
43
|
+
/**
|
|
44
|
+
* Whether this layout draws `_renderable` or its children.
|
|
45
|
+
*
|
|
46
|
+
* [LAW:one-source-of-truth] `render` and `_naturalWidth` must answer this the
|
|
47
|
+
* same way. Asked separately they did not: `_naturalWidth` read it off the
|
|
48
|
+
* *visible* children, so a layout holding content and a single hidden child
|
|
49
|
+
* reported that content's width while `render` emitted nothing at all, and a
|
|
50
|
+
* fit-mode `Panel` framed twelve cells of air.
|
|
51
|
+
*/
|
|
52
|
+
private get _isLeaf();
|
|
24
53
|
splitColumn(...layouts: Layout[]): void;
|
|
25
54
|
splitRow(...layouts: Layout[]): void;
|
|
26
55
|
update(renderable: Renderable | string): void;
|
|
27
56
|
getByName(name: string): Layout | undefined;
|
|
28
|
-
render(
|
|
57
|
+
render(rawOptions: RenderOptions): Iterable<Segment>;
|
|
29
58
|
private _renderColumn;
|
|
30
59
|
private _renderRow;
|
|
31
60
|
private _distributeSpace;
|
|
32
|
-
|
|
61
|
+
/**
|
|
62
|
+
* The width this layout would take if nothing constrained it: its content's
|
|
63
|
+
* for a leaf, its children's laid out the way the split lays them out.
|
|
64
|
+
*
|
|
65
|
+
* A `size` counts only across a row, which is the one direction in which it
|
|
66
|
+
* is a width — down a column the same field is a height, and reading it as a
|
|
67
|
+
* width there would report a two-line pane as two cells wide.
|
|
68
|
+
*/
|
|
69
|
+
private _naturalWidth;
|
|
70
|
+
/**
|
|
71
|
+
* The budget at which `_distributeSpace` gives every child of a row at least
|
|
72
|
+
* the width it wants — the inverse of the ratio rule above, and the reason
|
|
73
|
+
* this is not the sum of those widths.
|
|
74
|
+
*
|
|
75
|
+
* [LAW:one-source-of-truth] A growing child receives `floor(budget * ratio /
|
|
76
|
+
* totalRatio)`, so to receive `want` cells it needs the budget to reach
|
|
77
|
+
* `want * totalRatio / ratio`, and one budget serves them all: the row needs
|
|
78
|
+
* the largest demand, never their total. Summed instead, a 1:1 split of
|
|
79
|
+
* "left" and "right" reported 9 and then rendered "right" into the 4 cells
|
|
80
|
+
* that `floor(9/2)` actually hands it.
|
|
81
|
+
*
|
|
82
|
+
* The panes that do not grow are paid first here for the same reason they
|
|
83
|
+
* are paid first there — and it is the reason this divides by no zero: a
|
|
84
|
+
* `ratio` of 0 never reaches the division, because a pane that does not grow
|
|
85
|
+
* demands nothing of a budget for growing.
|
|
86
|
+
*/
|
|
87
|
+
private _rowBudgetFor;
|
|
88
|
+
measure(rawOptions: RenderOptions): {
|
|
33
89
|
minimum: number;
|
|
34
90
|
maximum: number;
|
|
35
91
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/renderables/layout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/renderables/layout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;AAK7B,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAaD,qBAAa,MAAO,YAAW,UAAU,EAAE,UAAU;IACnD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,eAAe,CAA+B;gBAE1C,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAerE;;;;;;;;;;;;OAYG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAEjC;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,MAAM,EAE5B;IAED,IAAI,QAAQ,IAAI,MAAM,EAAE,CAEvB;IAED;;;;;;;;OAQG;IACH,OAAO,KAAK,OAAO,GAElB;IAED,WAAW,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAKvC,QAAQ,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAKpC,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI;IAM7C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAS1C,MAAM,CAAC,UAAU,EAAE,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IA8BrD,OAAO,CAAE,aAAa;IAmBtB,OAAO,CAAE,UAAU;IAiBnB,OAAO,CAAC,gBAAgB;IAuDxB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IA4BrB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,UAAU,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAczE"}
|