@textui/core 0.1.0 → 0.3.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.
Files changed (70) hide show
  1. package/README.md +17 -20
  2. package/dist/app/app.d.ts +64 -0
  3. package/dist/app/app.d.ts.map +1 -1
  4. package/dist/app/app.js +202 -1
  5. package/dist/core/focus.d.ts.map +1 -1
  6. package/dist/core/focus.js +12 -1
  7. package/dist/core/store.d.ts.map +1 -1
  8. package/dist/core/store.js +2 -10
  9. package/dist/jsx/intrinsics.d.ts +18 -0
  10. package/dist/jsx/intrinsics.d.ts.map +1 -1
  11. package/dist/render/layout.js +10 -2
  12. package/dist/runtime/bindings.d.ts.map +1 -1
  13. package/dist/runtime/bindings.js +31 -4
  14. package/dist/runtime/hooks.d.ts +14 -2
  15. package/dist/runtime/hooks.d.ts.map +1 -1
  16. package/dist/runtime/hooks.js +15 -4
  17. package/dist/themes/builtin.d.ts +2 -0
  18. package/dist/themes/builtin.d.ts.map +1 -1
  19. package/dist/themes/builtin.js +64 -1
  20. package/dist/themes/dividers.d.ts +14 -0
  21. package/dist/themes/dividers.d.ts.map +1 -0
  22. package/dist/themes/dividers.js +42 -0
  23. package/dist/themes/glyphs.d.ts.map +1 -1
  24. package/dist/themes/glyphs.js +4 -0
  25. package/dist/themes/index.d.ts +1 -0
  26. package/dist/themes/index.d.ts.map +1 -1
  27. package/dist/themes/index.js +1 -0
  28. package/dist/themes/registry.d.ts.map +1 -1
  29. package/dist/themes/registry.js +31 -1
  30. package/dist/types/app.d.ts +15 -0
  31. package/dist/types/app.d.ts.map +1 -1
  32. package/dist/types/command.d.ts +18 -1
  33. package/dist/types/command.d.ts.map +1 -1
  34. package/dist/types/input.d.ts +9 -0
  35. package/dist/types/input.d.ts.map +1 -1
  36. package/dist/types/markdown.d.ts +36 -1
  37. package/dist/types/markdown.d.ts.map +1 -1
  38. package/dist/types/style.d.ts +28 -1
  39. package/dist/types/style.d.ts.map +1 -1
  40. package/dist/types/terminal.d.ts +9 -0
  41. package/dist/types/terminal.d.ts.map +1 -1
  42. package/dist/types/theme.d.ts +26 -1
  43. package/dist/types/theme.d.ts.map +1 -1
  44. package/dist/util/markdown.d.ts.map +1 -1
  45. package/dist/util/markdown.js +172 -2
  46. package/dist/util/paths.d.ts +9 -3
  47. package/dist/util/paths.d.ts.map +1 -1
  48. package/dist/util/paths.js +11 -16
  49. package/package.json +5 -5
  50. package/src/app/app.ts +198 -1
  51. package/src/core/focus.ts +12 -1
  52. package/src/core/store.ts +2 -7
  53. package/src/jsx/intrinsics.ts +18 -0
  54. package/src/render/layout.ts +7 -2
  55. package/src/runtime/bindings.ts +29 -3
  56. package/src/runtime/hooks.ts +15 -4
  57. package/src/themes/builtin.ts +65 -1
  58. package/src/themes/dividers.ts +48 -0
  59. package/src/themes/glyphs.ts +4 -0
  60. package/src/themes/index.ts +1 -0
  61. package/src/themes/registry.ts +30 -2
  62. package/src/types/app.ts +13 -0
  63. package/src/types/command.ts +18 -1
  64. package/src/types/input.ts +9 -0
  65. package/src/types/markdown.ts +38 -2
  66. package/src/types/style.ts +33 -1
  67. package/src/types/terminal.ts +9 -0
  68. package/src/types/theme.ts +29 -1
  69. package/src/util/markdown.ts +202 -3
  70. package/src/util/paths.ts +12 -15
@@ -1,4 +1,4 @@
1
- import type { StyleColor } from './style.js';
1
+ import type { StyleColor, TableRules } from './style.js';
2
2
  /**
3
3
  * Markdown, as rows a terminal can scroll.
4
4
  *
@@ -12,6 +12,8 @@ import type { StyleColor } from './style.js';
12
12
  * several rows here, each tagged with the fence it belongs to so a painter can
13
13
  * put the visible ones back into one box.
14
14
  */
15
+ /** Which edge a table column's text is pushed against. */
16
+ export type MarkdownAlign = 'left' | 'center' | 'right';
15
17
  /** A run of text with one style. Inline emphasis is why rows are not strings. */
16
18
  export interface MarkdownRun {
17
19
  text: string;
@@ -39,6 +41,29 @@ export type MarkdownRow = {
39
41
  part: 'open' | 'code' | 'close';
40
42
  text?: string;
41
43
  language?: string;
44
+ }
45
+ /**
46
+ * One line of a table, with its cells already fitted to their columns.
47
+ *
48
+ * The widths are decided once for the whole table and repeated on every row
49
+ * of it, because a column that is measured per row is not a column. Cells
50
+ * arrive padded and truncated to exactly `widths[i]`, so a painter only has
51
+ * to put the separators in - which is also what keeps the one-row-per-row
52
+ * invariant: a cell too long for its column is cut, never wrapped, or the
53
+ * table would be a different height than the document said it was.
54
+ *
55
+ * `top`, `rule` and `bottom` are edges and carry no cells; the painter draws
56
+ * them from the widths, in whatever the theme's border characters are. They
57
+ * are rows here for the same reason a fence's rules are: they take a line on
58
+ * the screen, so anything counting rows has to be able to count them.
59
+ */
60
+ | {
61
+ kind: 'table';
62
+ table: number;
63
+ part: 'top' | 'head' | 'rule' | 'body' | 'bottom';
64
+ cells: MarkdownRun[][];
65
+ widths: number[];
66
+ align: MarkdownAlign[];
42
67
  };
43
68
  export interface MarkdownLayoutOptions {
44
69
  /** Cells to wrap to. Zero means "not measured yet" - nothing is wrapped. */
@@ -54,5 +79,15 @@ export interface MarkdownLayoutOptions {
54
79
  * rules nobody draws stops two rows short of the end of the document.
55
80
  */
56
81
  ruled?: boolean;
82
+ /**
83
+ * How much of a table gets ruled. The theme's `tableRules`, passed through.
84
+ *
85
+ * It has to be decided here rather than by whatever paints the rows,
86
+ * because a rule between two rows *is* a row - it takes a line on the
87
+ * screen. A painter that added them would be drawing more lines than the
88
+ * layout counted, and every viewer that scrolls by row index would land in
89
+ * the wrong place by one per table row.
90
+ */
91
+ tableRules?: TableRules;
57
92
  }
58
93
  //# sourceMappingURL=markdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/types/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;GAYG;AAEH,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAAC,EAAE,CAAC,EAAE,UAAU,CAAA;CAAE,GAC9F;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAExG,MAAM,WAAW,qBAAqB;IACpC,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/types/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;;;;;;;GAYG;AAEH,0DAA0D;AAC1D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAExD,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAAC,EAAE,CAAC,EAAE,UAAU,CAAA;CAAE,GAC9F;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;AACrG;;;;;;;;;;;;;;GAcG;GACD;IACA,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClD,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB,CAAC;AAEJ,MAAM,WAAW,qBAAqB;IACpC,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB"}
@@ -5,7 +5,7 @@ import type { EdgeSpec } from './geometry.js';
5
5
  * what lets one catalog render the same under a light theme, a dark theme and
6
6
  * a 16-colour ssh session.
7
7
  */
8
- export type ColorToken = 'canvas' | 'surface' | 'surfaceAlt' | 'overlay' | 'border' | 'borderStrong' | 'borderSubtle' | 'text' | 'muted' | 'subtle' | 'inverted' | 'accent' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'onDefault' | 'onMuted' | 'onAccent' | 'onPrimary' | 'onSecondary' | 'onSuccess' | 'onWarning' | 'onDanger' | 'onInfo' | 'hover' | 'active' | 'selected' | 'focus' | 'disabled' | 'scrim' | 'cursor' | 'shadow';
8
+ export type ColorToken = 'canvas' | 'surface' | 'surfaceAlt' | 'overlay' | 'border' | 'borderStrong' | 'borderSubtle' | 'text' | 'muted' | 'subtle' | 'inverted' | 'accent' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'onDefault' | 'onMuted' | 'onAccent' | 'onPrimary' | 'onSecondary' | 'onSuccess' | 'onWarning' | 'onDanger' | 'onInfo' | 'hover' | 'active' | 'selected' | 'focus' | 'disabled' | 'scrim' | 'cursor' | 'shadow' | 'divider';
9
9
  /** Anywhere a colour is accepted, a semantic token is accepted too. */
10
10
  export type StyleColor = ColorToken | Color;
11
11
  export type Dimension = number | `${number}%` | 'auto';
@@ -27,6 +27,33 @@ export interface BorderChars {
27
27
  teeLeft: string;
28
28
  teeRight: string;
29
29
  }
30
+ /**
31
+ * A rule that separates, rather than a frame that encloses.
32
+ *
33
+ * Kept apart from `BorderStyle` on purpose: a theme that draws no frames may
34
+ * still want a rule, and tying the two means choosing a divider glyph decides
35
+ * whether every bordered component reserves a ring.
36
+ */
37
+ export type DividerStyle = 'none' | 'single' | 'double' | 'dashed' | 'thick' | 'ascii';
38
+ /** A divider runs either way, so it names both. */
39
+ export interface DividerChars {
40
+ horizontal: string;
41
+ vertical: string;
42
+ }
43
+ /**
44
+ * The shape of the caret.
45
+ *
46
+ * Named for DECSCUSR, which is what a terminal understands, so a theme value
47
+ * maps straight onto the escape sequence with nothing to translate.
48
+ */
49
+ export type CursorStyle = 'block' | 'underline' | 'bar';
50
+ /**
51
+ * How much of a table gets ruled: the header only, or between every row.
52
+ *
53
+ * Not a border style - it is a question about how many lines, not which
54
+ * glyphs. The glyphs are the theme's border set either way.
55
+ */
56
+ export type TableRules = 'header' | 'all';
30
57
  export type BorderSides = {
31
58
  top?: boolean;
32
59
  right?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/types/style.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/types/style.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { CursorStyle } from './style.js';
1
2
  import type { Disposable } from './disposable.js';
2
3
  import type { Size } from './geometry.js';
3
4
  import type { TerminalCapabilities, CapabilityOverrides } from './capabilities.js';
@@ -28,6 +29,8 @@ export interface AcquiredState {
28
29
  focusEvents: boolean;
29
30
  paste: boolean;
30
31
  cursorHidden: boolean;
32
+ /** Whether this session changed the caret shape, and so owes a reset. */
33
+ cursorShaped?: boolean;
31
34
  enhancedKeys: boolean;
32
35
  rawMode: boolean;
33
36
  titleSet: boolean;
@@ -48,5 +51,11 @@ export interface TerminalAdapter extends Disposable {
48
51
  /** OSC 52, when the terminal allows it. */
49
52
  writeClipboard?(text: string): void;
50
53
  setTitle?(title: string): void;
54
+ /**
55
+ * DECSCUSR. Session state rather than frame state - it survives until
56
+ * something changes it, so it is set when it changes and put back on
57
+ * teardown, the way the alt screen and raw mode are.
58
+ */
59
+ setCursorShape?(shape: CursorStyle): void;
51
60
  }
52
61
  //# sourceMappingURL=terminal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/types/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,IAAI,IAAI,IAAI,CAAC;IACb,YAAY,IAAI,oBAAoB,CAAC;IACrC,6CAA6C;IAC7C,sBAAsB,CAAC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAE7D,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC;IACjF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAExC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE9B,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,UAAU,CAAC;IACrD,QAAQ,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,UAAU,CAAC;IAE/C,2CAA2C;IAC3C,cAAc,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/types/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,IAAI,IAAI,IAAI,CAAC;IACb,YAAY,IAAI,oBAAoB,CAAC;IACrC,6CAA6C;IAC7C,sBAAsB,CAAC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAE7D,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC;IACjF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAExC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE9B,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,UAAU,CAAC;IACrD,QAAQ,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,UAAU,CAAC;IAE/C,2CAA2C;IAC3C,cAAc,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;OAIG;IACH,cAAc,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CAC3C"}
@@ -1,5 +1,5 @@
1
1
  import type { Color } from './cells.js';
2
- import type { BorderChars, BorderStyle, ColorToken, Density, Style, StyleColor } from './style.js';
2
+ import type { BorderChars, BorderStyle, ColorToken, CursorStyle, Density, DividerChars, DividerStyle, Style, StyleColor, TableRules } from './style.js';
3
3
  import type { SyntaxScope } from './syntax.js';
4
4
  import type { Disposable } from './disposable.js';
5
5
  import type { TerminalCapabilities } from './capabilities.js';
@@ -31,6 +31,8 @@ export interface ThemeGlyphs {
31
31
  chevronUp: string;
32
32
  arrowUp: string;
33
33
  arrowDown: string;
34
+ arrowLeft: string;
35
+ arrowRight: string;
34
36
  ellipsis: string;
35
37
  search: string;
36
38
  radioOn: string;
@@ -77,6 +79,25 @@ export interface ThemeDefinition {
77
79
  /** Default border style for chrome. `'none'` gives the borderless look. */
78
80
  border?: BorderStyle;
79
81
  borderChars?: Partial<Record<BorderStyle, BorderChars>>;
82
+ /**
83
+ * Default rule style. Independent of `border`, so a borderless theme can
84
+ * still separate with a line.
85
+ */
86
+ divider?: DividerStyle;
87
+ dividerChars?: Partial<Record<DividerStyle, DividerChars>>;
88
+ /** The caret's shape. The terminal's own setting is the default. */
89
+ cursor?: CursorStyle;
90
+ /**
91
+ * How much of a table gets ruled.
92
+ *
93
+ * `header` is the default and the quiet one: a box, and a rule under the
94
+ * header. `all` puts a rule between every pair of rows as well, which is
95
+ * what a table of few, long rows wants - a wrapped-looking cell beside a
96
+ * short one is ambiguous about which row it belongs to until something
97
+ * separates them. On a table of twenty short rows the same lines are noise,
98
+ * which is why it is the theme's call rather than the default.
99
+ */
100
+ tableRules?: TableRules;
80
101
  density?: Density;
81
102
  /** Per-component style overrides, keyed by component name then variant. */
82
103
  components?: Record<string, Record<string, Style>>;
@@ -96,6 +117,9 @@ export interface ResolvedTheme {
96
117
  spacing: ThemeSpacing;
97
118
  glyphs: ThemeGlyphs;
98
119
  border: BorderStyle;
120
+ divider: DividerStyle;
121
+ cursor: CursorStyle | undefined;
122
+ tableRules: TableRules;
99
123
  density: Density;
100
124
  components: Record<string, Record<string, Style>>;
101
125
  /** Every syntax scope, resolved to a colour. */
@@ -103,6 +127,7 @@ export interface ResolvedTheme {
103
127
  /** Resolve a token (or pass a literal colour through). */
104
128
  color(token: string): Color;
105
129
  borderChars(style?: BorderStyle): BorderChars;
130
+ dividerChars(style?: DividerStyle): DividerChars;
106
131
  /** Component style for a name + variant list, merged in order. */
107
132
  styleFor(component: string, variants?: string[]): Style;
108
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/types/theme.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/types/theme.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/util/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAsC5F;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAiBtD;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,EAAE,CA2C5E;AAwBD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,OAAO,EAAE,qBAAqB,GAC7B,WAAW,EAAE,CAsEf;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAEtD;AAED,yEAAyE;AACzE,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAI5D"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/util/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACK,qBAAqB,EAAE,WAAW,EAAE,WAAW,EAC/D,MAAM,sBAAsB,CAAC;AAuC9B;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAiBtD;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,EAAE,CA2C5E;AAwBD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,OAAO,EAAE,qBAAqB,GAC7B,WAAW,EAAE,CA4Ff;AAgLD,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAEtD;AAED,yEAAyE;AACzE,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAI5D"}
@@ -136,13 +136,17 @@ function withPrefix(runs, width, prefix, options = {}) {
136
136
  }));
137
137
  }
138
138
  export function layoutMarkdown(source, options) {
139
- const { width, bullet = '-', quoteBar = '|', ruled = true } = options;
139
+ const { width, bullet = '-', quoteBar = '|', ruled = true, tableRules = 'header' } = options;
140
140
  const lines = Array.isArray(source) ? source : source.replace(/\r\n/g, '\n').split('\n');
141
141
  const rows = [];
142
142
  let fence = 0;
143
143
  let inFence = false;
144
144
  let language = '';
145
- for (const line of lines) {
145
+ let table = 0;
146
+ // By index rather than by value: a table is only a table because of the line
147
+ // *after* its header, so this loop has to be able to look at it.
148
+ for (let at = 0; at < lines.length; at++) {
149
+ const line = lines[at];
146
150
  const marker = /^\s*```(\S*)\s*$/.exec(line);
147
151
  if (marker) {
148
152
  // An open fence is laid out as a fence from the moment it opens. A turn
@@ -162,6 +166,24 @@ export function layoutMarkdown(source, options) {
162
166
  rows.push({ kind: 'fence', fence, part: 'code', text: line, ...(language ? { language } : {}) });
163
167
  continue;
164
168
  }
169
+ // Before headings and lists, because a cell may contain either and the
170
+ // pipes are what decide. After fences, because inside one nothing is.
171
+ if (line.includes('|') && DIVIDER.test(lines[at + 1] ?? '')) {
172
+ const align = cellsOf(lines[at + 1]).map(alignOf);
173
+ const body = [];
174
+ let end = at + 2;
175
+ while (end < lines.length) {
176
+ const next = lines[end];
177
+ if (!next.includes('|') || next.trim() === '')
178
+ break;
179
+ body.push(cellsOf(next));
180
+ end++;
181
+ }
182
+ rows.push(...tableRows(cellsOf(line), body, align, width, table, tableRules));
183
+ table++;
184
+ at = end - 1;
185
+ continue;
186
+ }
165
187
  const heading = /^(#{1,6})\s+(.*)$/.exec(line);
166
188
  if (heading) {
167
189
  const level = heading[1].length;
@@ -207,6 +229,154 @@ export function layoutMarkdown(source, options) {
207
229
  rows.push({ kind: 'fence', fence, part: 'close' });
208
230
  return rows;
209
231
  }
232
+ /**
233
+ * The `|---|:--:|---:|` line, which is what makes the line above it a header.
234
+ *
235
+ * A row of pipes on its own is a row of pipes - `a | b` is arithmetic or a
236
+ * shell pipeline far more often than it is a one-column table, and treating
237
+ * every line with a bar in it as a table is how prose ends up in a grid.
238
+ */
239
+ const DIVIDER = /^\s*\|?\s*:?-+:?\s*(\|\s*:?-+:?\s*)*\|?\s*$/;
240
+ /**
241
+ * One line into its cells.
242
+ *
243
+ * The outer pipes are optional in every dialect anybody writes, so they are
244
+ * stripped rather than required. `\|` is an escaped bar inside a cell and not
245
+ * a boundary - which is the only way to put a bar in a table at all.
246
+ */
247
+ function cellsOf(line) {
248
+ const trimmed = line.trim().replace(/^\|/, '').replace(/\|$/, '');
249
+ return trimmed
250
+ .split(/(?<!\\)\|/)
251
+ .map((cell) => cell.replace(/\\\|/g, '|').trim());
252
+ }
253
+ function alignOf(spec) {
254
+ const left = spec.startsWith(':');
255
+ const right = spec.endsWith(':');
256
+ if (left && right)
257
+ return 'center';
258
+ return right ? 'right' : 'left';
259
+ }
260
+ /**
261
+ * Cut and pad one cell to exactly `width`, keeping the styles.
262
+ *
263
+ * Cut, never wrapped: a table row has to stay one row tall or the document's
264
+ * length stops being a count of rows, and every viewer that windows this
265
+ * scrolls to the wrong place.
266
+ */
267
+ function fitRuns(runs, width, align) {
268
+ const out = [];
269
+ let used = 0;
270
+ for (const run of runs) {
271
+ if (used >= width)
272
+ break;
273
+ const room = width - used;
274
+ if (stringWidth(run.text) <= room) {
275
+ out.push(run);
276
+ used += stringWidth(run.text);
277
+ continue;
278
+ }
279
+ // The ellipsis costs a cell, so it is only worth it when there is a cell
280
+ // to spend: at a width of one, a bare glyph says less than the letter.
281
+ const keep = room > 1 ? room - 1 : room;
282
+ const cut = [];
283
+ let taken = 0;
284
+ for (const g of graphemes(run.text)) {
285
+ const w = stringWidth(g);
286
+ if (taken + w > keep)
287
+ break;
288
+ cut.push(g);
289
+ taken += w;
290
+ }
291
+ out.push({ ...run, text: room > 1 ? `${cut.join('')}\u2026` : cut.join('') });
292
+ used = width;
293
+ break;
294
+ }
295
+ const slack = Math.max(0, width - used);
296
+ if (slack === 0)
297
+ return out;
298
+ const before = align === 'right' ? slack : align === 'center' ? Math.floor(slack / 2) : 0;
299
+ const after = slack - before;
300
+ return [
301
+ ...(before ? [{ text: ' '.repeat(before) }] : []),
302
+ ...out,
303
+ ...(after ? [{ text: ' '.repeat(after) }] : []),
304
+ ];
305
+ }
306
+ /**
307
+ * A whole table, measured once.
308
+ *
309
+ * The columns are as wide as their widest cell wants, and when that is more
310
+ * than the space there is they give it back in proportion - the widest loses
311
+ * the most, because it is the one with the most to lose. Three cells is the
312
+ * floor: below that a column is an ellipsis and a space, which is narrower
313
+ * than saying nothing.
314
+ */
315
+ function tableRows(head, body, align, width, table, rules) {
316
+ const columns = Math.max(head.length, align.length, ...body.map((r) => r.length));
317
+ const at = (row, i) => row[i] ?? '';
318
+ const runsFor = (text, bold) => inlineRuns(text).map((run) => (bold ? { ...run, bold: true } : run));
319
+ const natural = Array.from({ length: columns }, (_, i) => Math.max(stringWidth(at(head, i)), ...body.map((row) => stringWidth(at(row, i))), 1));
320
+ // A rule between every pair of columns, and a box around the lot. The box
321
+ // is what makes it read as a table rather than as text that happens to line
322
+ // up - which matters most on a theme that draws no borders anywhere else,
323
+ // because there a table with only its columns ruled has nothing to say it
324
+ // ended.
325
+ const gaps = (columns - 1) * SEPARATOR + OUTER;
326
+ const room = width > 0 ? Math.max(columns * MIN_COLUMN, width - gaps) : Infinity;
327
+ const wanted = natural.reduce((sum, n) => sum + n, 0);
328
+ const widths = wanted <= room
329
+ ? natural
330
+ : share(natural, room);
331
+ const line = (cells, part) => ({
332
+ kind: 'table',
333
+ table,
334
+ part,
335
+ widths,
336
+ align,
337
+ cells: widths.map((w, i) => fitRuns(runsFor(at(cells, i), part === 'head'), w, align[i] ?? 'left')),
338
+ });
339
+ const edge = (part) => ({ kind: 'table', table, part, cells: [], widths, align });
340
+ return [
341
+ edge('top'),
342
+ line(head, 'head'),
343
+ edge('rule'),
344
+ // A rule between every pair, when the theme asked for them. Between, not
345
+ // after: a rule under the last row and then the box's own bottom edge is
346
+ // two lines saying the same thing.
347
+ ...body.flatMap((row, i) => (rules === 'all' && i > 0
348
+ ? [edge('rule'), line(row, 'body')]
349
+ : [line(row, 'body')])),
350
+ edge('bottom'),
351
+ ];
352
+ }
353
+ /** Cells between two columns: a space, a rule, a space. */
354
+ const SEPARATOR = 3;
355
+ /** The box: a rule and a space at each end. */
356
+ const OUTER = 4;
357
+ const MIN_COLUMN = 3;
358
+ /**
359
+ * Shrink columns into `room`, proportionally, without losing a cell to
360
+ * rounding.
361
+ *
362
+ * The remainder goes to the widest columns one at a time rather than to the
363
+ * first: handing every leftover cell to column one is what turns a five-column
364
+ * table into one wide column and four ellipses.
365
+ */
366
+ function share(natural, room) {
367
+ const total = natural.reduce((sum, n) => sum + n, 0);
368
+ const scaled = natural.map((n) => Math.max(MIN_COLUMN, Math.floor((n / total) * room)));
369
+ let spare = room - scaled.reduce((sum, n) => sum + n, 0);
370
+ const order = natural
371
+ .map((n, i) => [n, i])
372
+ .sort((a, b) => b[0] - a[0])
373
+ .map(([, i]) => i);
374
+ for (let i = 0; spare > 0; i = (i + 1) % order.length) {
375
+ scaled[order[i]] = scaled[order[i]] + 1;
376
+ spare--;
377
+ }
378
+ return scaled;
379
+ }
210
380
  /** Every run's text, for a measurement or a test that does not care how it looks. */
211
381
  export function runsToText(runs) {
212
382
  return runs.map((run) => run.text).join('');
@@ -24,7 +24,7 @@ export declare function segments(path: string): string[];
24
24
  * Canonical map key for a path: segments joined, no sigil.
25
25
  *
26
26
  * The segments are re-escaped on the way out. Everything downstream - the
27
- * store's own walk, `ancestorKeys`, `matchKey` - splits a key on `/`, so a
27
+ * store's own walk, `keysTouch`, `matchKey` - splits a key on `/`, so a
28
28
  * segment that legitimately contains one (a URI used as a key, a filename with
29
29
  * a slash) has to stay escaped or it silently becomes several segments and the
30
30
  * value lands somewhere nobody looks.
@@ -38,9 +38,15 @@ export declare function joinPath(...parts: (string | number)[]): BindingPath;
38
38
  export declare function resolvePath(path: string, dataContext?: string): BindingPath;
39
39
  export declare function scopeOf(path: string): string;
40
40
  export declare function parentKey(key: string): string | null;
41
- /** Every ancestor key of `key`, closest first, including `''` for the root. */
42
- export declare function ancestorKeys(key: string): string[];
43
41
  export declare function isDescendantKey(key: string, ancestor: string): boolean;
42
+ /**
43
+ * Whether two concrete keys can affect the same subscribed value.
44
+ *
45
+ * A write to a descendant changes the ancestor object a subscriber reads, and a
46
+ * write to an ancestor may replace the whole subtree below it. This relation is
47
+ * symmetric and avoids building ancestor lists in hot subscription checks.
48
+ */
49
+ export declare function keysTouch(a: string, b: string): boolean;
44
50
  export declare function hasWildcard(path: string): boolean;
45
51
  /** Match a concrete key against a pattern key that may contain `*`. */
46
52
  export declare function matchKey(key: string, pattern: string, subtree?: boolean): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/util/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;;;;;GAWG;AAEH,qBAAa,SAAU,SAAQ,KAAK;IACL,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAtC,OAAO,EAAE,MAAM,EAAW,IAAI,EAAE,MAAM;CAInD;AAMD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,KAAK,MAAM,EAAE,CAE9D;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,QAAQ,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,WAAW,CASnE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAW3E;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpD;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAWlD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGtE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAa/E"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/util/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;;;;;GAWG;AAEH,qBAAa,SAAU,SAAQ,KAAK;IACL,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAtC,OAAO,EAAE,MAAM,EAAW,IAAI,EAAE,MAAM;CAInD;AAMD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,KAAK,MAAM,EAAE,CAE9D;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,QAAQ,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,WAAW,CASnE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAW3E;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGtE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAa/E"}
@@ -46,7 +46,7 @@ export function segments(path) {
46
46
  * Canonical map key for a path: segments joined, no sigil.
47
47
  *
48
48
  * The segments are re-escaped on the way out. Everything downstream - the
49
- * store's own walk, `ancestorKeys`, `matchKey` - splits a key on `/`, so a
49
+ * store's own walk, `keysTouch`, `matchKey` - splits a key on `/`, so a
50
50
  * segment that legitimately contains one (a URI used as a key, a filename with
51
51
  * a slash) has to stay escaped or it silently becomes several segments and the
52
52
  * value lands somewhere nobody looks.
@@ -90,26 +90,21 @@ export function parentKey(key) {
90
90
  const i = key.lastIndexOf('/');
91
91
  return i === -1 ? (key === '' ? null : '') : key.slice(0, i);
92
92
  }
93
- /** Every ancestor key of `key`, closest first, including `''` for the root. */
94
- export function ancestorKeys(key) {
95
- const out = [];
96
- let cur = key;
97
- for (;;) {
98
- const p = parentKey(cur);
99
- if (p === null)
100
- break;
101
- out.push(p);
102
- cur = p;
103
- if (p === '')
104
- break;
105
- }
106
- return out;
107
- }
108
93
  export function isDescendantKey(key, ancestor) {
109
94
  if (ancestor === '')
110
95
  return key !== '';
111
96
  return key.startsWith(ancestor + '/');
112
97
  }
98
+ /**
99
+ * Whether two concrete keys can affect the same subscribed value.
100
+ *
101
+ * A write to a descendant changes the ancestor object a subscriber reads, and a
102
+ * write to an ancestor may replace the whole subtree below it. This relation is
103
+ * symmetric and avoids building ancestor lists in hot subscription checks.
104
+ */
105
+ export function keysTouch(a, b) {
106
+ return a === b || isDescendantKey(a, b) || isDescendantKey(b, a);
107
+ }
113
108
  export function hasWildcard(path) {
114
109
  return path.includes('*');
115
110
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textui/core",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Graph-mounted terminal UI runtime - store, registries, renderer, host primitives",
5
5
  "keywords": [
6
6
  "terminal",
@@ -58,13 +58,13 @@
58
58
  "import": "./dist/themes/index.js"
59
59
  }
60
60
  },
61
- "publishConfig": {
62
- "access": "public"
63
- },
64
61
  "scripts": {
65
62
  "build": "tsc -p tsconfig.json",
66
63
  "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json",
67
64
  "test": "vitest run",
68
65
  "test:watch": "vitest"
66
+ },
67
+ "publishConfig": {
68
+ "access": "public"
69
69
  }
70
- }
70
+ }