@matter/tools 0.12.2-alpha.0-20250201-eb5d40a2f → 0.12.3-alpha.0-20250203-34ba45cae

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 (225) hide show
  1. package/dist/cjs/ansi-text/chars.d.ts +11 -0
  2. package/dist/cjs/ansi-text/chars.d.ts.map +1 -0
  3. package/dist/cjs/ansi-text/chars.js +57 -0
  4. package/dist/cjs/ansi-text/chars.js.map +6 -0
  5. package/dist/cjs/ansi-text/consumer.d.ts +45 -0
  6. package/dist/cjs/ansi-text/consumer.d.ts.map +1 -0
  7. package/dist/cjs/ansi-text/consumer.js +22 -0
  8. package/dist/cjs/ansi-text/consumer.js.map +6 -0
  9. package/dist/cjs/ansi-text/contiguous-output-segment.d.ts +31 -0
  10. package/dist/cjs/ansi-text/contiguous-output-segment.d.ts.map +1 -0
  11. package/dist/cjs/ansi-text/contiguous-output-segment.js +156 -0
  12. package/dist/cjs/ansi-text/contiguous-output-segment.js.map +6 -0
  13. package/dist/cjs/ansi-text/index.d.ts +12 -0
  14. package/dist/cjs/ansi-text/index.d.ts.map +1 -0
  15. package/dist/cjs/ansi-text/index.js +29 -0
  16. package/dist/cjs/ansi-text/index.js.map +6 -0
  17. package/dist/cjs/ansi-text/printer.d.ts +24 -0
  18. package/dist/cjs/ansi-text/printer.d.ts.map +1 -0
  19. package/dist/cjs/ansi-text/printer.js +81 -0
  20. package/dist/cjs/ansi-text/printer.js.map +6 -0
  21. package/dist/cjs/ansi-text/producer.d.ts +17 -0
  22. package/dist/cjs/ansi-text/producer.d.ts.map +1 -0
  23. package/dist/cjs/ansi-text/producer.js +45 -0
  24. package/dist/cjs/ansi-text/producer.js.map +6 -0
  25. package/dist/cjs/ansi-text/screen.d.ts +13 -0
  26. package/dist/cjs/ansi-text/screen.d.ts.map +1 -0
  27. package/dist/cjs/ansi-text/screen.js +38 -0
  28. package/dist/cjs/ansi-text/screen.js.map +6 -0
  29. package/dist/cjs/ansi-text/sgr.d.ts +100 -0
  30. package/dist/cjs/ansi-text/sgr.d.ts.map +1 -0
  31. package/dist/cjs/ansi-text/sgr.js +140 -0
  32. package/dist/cjs/ansi-text/sgr.js.map +6 -0
  33. package/dist/cjs/ansi-text/std.d.ts +17 -0
  34. package/dist/cjs/ansi-text/std.d.ts.map +1 -0
  35. package/dist/cjs/ansi-text/std.js +43 -0
  36. package/dist/cjs/ansi-text/std.js.map +6 -0
  37. package/dist/cjs/ansi-text/style.d.ts +88 -0
  38. package/dist/cjs/ansi-text/style.d.ts.map +1 -0
  39. package/dist/cjs/ansi-text/style.js +257 -0
  40. package/dist/cjs/ansi-text/style.js.map +6 -0
  41. package/dist/cjs/ansi-text/text-builder.d.ts +78 -0
  42. package/dist/cjs/ansi-text/text-builder.d.ts.map +1 -0
  43. package/dist/cjs/ansi-text/text-builder.js +164 -0
  44. package/dist/cjs/ansi-text/text-builder.js.map +6 -0
  45. package/dist/cjs/ansi-text/text-writer.d.ts +30 -0
  46. package/dist/cjs/ansi-text/text-writer.d.ts.map +1 -0
  47. package/dist/cjs/ansi-text/text-writer.js +317 -0
  48. package/dist/cjs/ansi-text/text-writer.js.map +6 -0
  49. package/dist/cjs/ansi-text/token.d.ts +61 -0
  50. package/dist/cjs/ansi-text/token.d.ts.map +1 -0
  51. package/dist/cjs/ansi-text/token.js +22 -0
  52. package/dist/cjs/ansi-text/token.js.map +6 -0
  53. package/dist/cjs/ansi-text/tokenize.d.ts +11 -0
  54. package/dist/cjs/ansi-text/tokenize.d.ts.map +1 -0
  55. package/dist/cjs/ansi-text/tokenize.js +190 -0
  56. package/dist/cjs/ansi-text/tokenize.js.map +6 -0
  57. package/dist/cjs/ansi-text/truncator.d.ts +20 -0
  58. package/dist/cjs/ansi-text/truncator.d.ts.map +1 -0
  59. package/dist/cjs/ansi-text/truncator.js +72 -0
  60. package/dist/cjs/ansi-text/truncator.js.map +6 -0
  61. package/dist/cjs/ansi-text/visible-width-of.d.ts +10 -0
  62. package/dist/cjs/ansi-text/visible-width-of.d.ts.map +1 -0
  63. package/dist/cjs/ansi-text/visible-width-of.js +55 -0
  64. package/dist/cjs/ansi-text/visible-width-of.js.map +6 -0
  65. package/dist/cjs/ansi-text/wrapper.d.ts +34 -0
  66. package/dist/cjs/ansi-text/wrapper.d.ts.map +1 -0
  67. package/dist/cjs/ansi-text/wrapper.js +208 -0
  68. package/dist/cjs/ansi-text/wrapper.js.map +6 -0
  69. package/dist/cjs/building/cli.js +6 -6
  70. package/dist/cjs/building/cli.js.map +1 -1
  71. package/dist/cjs/building/graph.d.ts +2 -2
  72. package/dist/cjs/building/graph.d.ts.map +1 -1
  73. package/dist/cjs/building/graph.js.map +1 -1
  74. package/dist/cjs/building/project-builder.d.ts +38 -0
  75. package/dist/cjs/building/project-builder.d.ts.map +1 -0
  76. package/dist/cjs/building/project-builder.js +200 -0
  77. package/dist/cjs/building/project-builder.js.map +6 -0
  78. package/dist/cjs/building/tsconfig.js +1 -1
  79. package/dist/cjs/building/tsconfig.js.map +1 -1
  80. package/dist/cjs/index.d.ts +4 -6
  81. package/dist/cjs/index.d.ts.map +1 -1
  82. package/dist/cjs/index.js +4 -6
  83. package/dist/cjs/index.js.map +1 -1
  84. package/dist/cjs/running/ensure-compiled.js +2 -2
  85. package/dist/cjs/running/ensure-compiled.js.map +1 -1
  86. package/dist/cjs/util/commander.d.ts.map +1 -1
  87. package/dist/cjs/util/commander.js +4 -5
  88. package/dist/cjs/util/commander.js.map +2 -2
  89. package/dist/cjs/util/index.d.ts +1 -0
  90. package/dist/cjs/util/index.d.ts.map +1 -1
  91. package/dist/cjs/util/index.js +1 -0
  92. package/dist/cjs/util/index.js.map +1 -1
  93. package/dist/cjs/util/progress.d.ts +2 -2
  94. package/dist/cjs/util/progress.d.ts.map +1 -1
  95. package/dist/cjs/util/progress.js +25 -53
  96. package/dist/cjs/util/progress.js.map +2 -2
  97. package/dist/cjs/versioning/versioner.js +2 -12
  98. package/dist/cjs/versioning/versioner.js.map +2 -2
  99. package/dist/esm/ansi-text/chars.d.ts +11 -0
  100. package/dist/esm/ansi-text/chars.d.ts.map +1 -0
  101. package/dist/esm/ansi-text/chars.js +37 -0
  102. package/dist/esm/ansi-text/chars.js.map +6 -0
  103. package/dist/esm/ansi-text/consumer.d.ts +45 -0
  104. package/dist/esm/ansi-text/consumer.d.ts.map +1 -0
  105. package/dist/esm/ansi-text/consumer.js +6 -0
  106. package/dist/esm/ansi-text/consumer.js.map +6 -0
  107. package/dist/esm/ansi-text/contiguous-output-segment.d.ts +31 -0
  108. package/dist/esm/ansi-text/contiguous-output-segment.d.ts.map +1 -0
  109. package/dist/esm/ansi-text/contiguous-output-segment.js +136 -0
  110. package/dist/esm/ansi-text/contiguous-output-segment.js.map +6 -0
  111. package/dist/esm/ansi-text/index.d.ts +12 -0
  112. package/dist/esm/ansi-text/index.d.ts.map +1 -0
  113. package/dist/esm/ansi-text/index.js +12 -0
  114. package/dist/esm/ansi-text/index.js.map +6 -0
  115. package/dist/esm/ansi-text/printer.d.ts +24 -0
  116. package/dist/esm/ansi-text/printer.d.ts.map +1 -0
  117. package/dist/esm/ansi-text/printer.js +61 -0
  118. package/dist/esm/ansi-text/printer.js.map +6 -0
  119. package/dist/esm/ansi-text/producer.d.ts +17 -0
  120. package/dist/esm/ansi-text/producer.d.ts.map +1 -0
  121. package/dist/esm/ansi-text/producer.js +25 -0
  122. package/dist/esm/ansi-text/producer.js.map +6 -0
  123. package/dist/esm/ansi-text/screen.d.ts +13 -0
  124. package/dist/esm/ansi-text/screen.d.ts.map +1 -0
  125. package/dist/esm/ansi-text/screen.js +18 -0
  126. package/dist/esm/ansi-text/screen.js.map +6 -0
  127. package/dist/esm/ansi-text/sgr.d.ts +100 -0
  128. package/dist/esm/ansi-text/sgr.d.ts.map +1 -0
  129. package/dist/esm/ansi-text/sgr.js +120 -0
  130. package/dist/esm/ansi-text/sgr.js.map +6 -0
  131. package/dist/esm/ansi-text/std.d.ts +17 -0
  132. package/dist/esm/ansi-text/std.d.ts.map +1 -0
  133. package/dist/esm/ansi-text/std.js +23 -0
  134. package/dist/esm/ansi-text/std.js.map +6 -0
  135. package/dist/esm/ansi-text/style.d.ts +88 -0
  136. package/dist/esm/ansi-text/style.d.ts.map +1 -0
  137. package/dist/esm/ansi-text/style.js +245 -0
  138. package/dist/esm/ansi-text/style.js.map +6 -0
  139. package/dist/esm/ansi-text/text-builder.d.ts +78 -0
  140. package/dist/esm/ansi-text/text-builder.d.ts.map +1 -0
  141. package/dist/esm/ansi-text/text-builder.js +150 -0
  142. package/dist/esm/ansi-text/text-builder.js.map +6 -0
  143. package/dist/esm/ansi-text/text-writer.d.ts +30 -0
  144. package/dist/esm/ansi-text/text-writer.d.ts.map +1 -0
  145. package/dist/esm/ansi-text/text-writer.js +297 -0
  146. package/dist/esm/ansi-text/text-writer.js.map +6 -0
  147. package/dist/esm/ansi-text/token.d.ts +61 -0
  148. package/dist/esm/ansi-text/token.d.ts.map +1 -0
  149. package/dist/esm/ansi-text/token.js +6 -0
  150. package/dist/esm/ansi-text/token.js.map +6 -0
  151. package/dist/esm/ansi-text/tokenize.d.ts +11 -0
  152. package/dist/esm/ansi-text/tokenize.d.ts.map +1 -0
  153. package/dist/esm/ansi-text/tokenize.js +170 -0
  154. package/dist/esm/ansi-text/tokenize.js.map +6 -0
  155. package/dist/esm/ansi-text/truncator.d.ts +20 -0
  156. package/dist/esm/ansi-text/truncator.d.ts.map +1 -0
  157. package/dist/esm/ansi-text/truncator.js +52 -0
  158. package/dist/esm/ansi-text/truncator.js.map +6 -0
  159. package/dist/esm/ansi-text/visible-width-of.d.ts +10 -0
  160. package/dist/esm/ansi-text/visible-width-of.d.ts.map +1 -0
  161. package/dist/esm/ansi-text/visible-width-of.js +35 -0
  162. package/dist/esm/ansi-text/visible-width-of.js.map +6 -0
  163. package/dist/esm/ansi-text/wrapper.d.ts +34 -0
  164. package/dist/esm/ansi-text/wrapper.d.ts.map +1 -0
  165. package/dist/esm/ansi-text/wrapper.js +188 -0
  166. package/dist/esm/ansi-text/wrapper.js.map +6 -0
  167. package/dist/esm/building/cli.js +3 -3
  168. package/dist/esm/building/cli.js.map +1 -1
  169. package/dist/esm/building/graph.d.ts +2 -2
  170. package/dist/esm/building/graph.d.ts.map +1 -1
  171. package/dist/esm/building/graph.js +1 -1
  172. package/dist/esm/building/graph.js.map +1 -1
  173. package/dist/esm/building/project-builder.d.ts +38 -0
  174. package/dist/esm/building/project-builder.d.ts.map +1 -0
  175. package/dist/esm/building/project-builder.js +180 -0
  176. package/dist/esm/building/project-builder.js.map +6 -0
  177. package/dist/esm/building/tsconfig.js +2 -2
  178. package/dist/esm/building/tsconfig.js.map +1 -1
  179. package/dist/esm/index.d.ts +4 -6
  180. package/dist/esm/index.d.ts.map +1 -1
  181. package/dist/esm/index.js +5 -7
  182. package/dist/esm/index.js.map +1 -1
  183. package/dist/esm/running/ensure-compiled.js +3 -3
  184. package/dist/esm/running/ensure-compiled.js.map +1 -1
  185. package/dist/esm/util/commander.d.ts.map +1 -1
  186. package/dist/esm/util/commander.js +5 -6
  187. package/dist/esm/util/commander.js.map +1 -1
  188. package/dist/esm/util/index.d.ts +1 -0
  189. package/dist/esm/util/index.d.ts.map +1 -1
  190. package/dist/esm/util/index.js +2 -1
  191. package/dist/esm/util/index.js.map +1 -1
  192. package/dist/esm/util/progress.d.ts +2 -2
  193. package/dist/esm/util/progress.d.ts.map +1 -1
  194. package/dist/esm/util/progress.js +26 -44
  195. package/dist/esm/util/progress.js.map +1 -1
  196. package/dist/esm/versioning/versioner.js +3 -3
  197. package/dist/esm/versioning/versioner.js.map +1 -1
  198. package/package.json +11 -1
  199. package/src/ansi-text/chars.ts +31 -0
  200. package/src/ansi-text/consumer.ts +53 -0
  201. package/src/ansi-text/contiguous-output-segment.ts +181 -0
  202. package/src/ansi-text/index.ts +14 -0
  203. package/src/ansi-text/printer.ts +86 -0
  204. package/src/ansi-text/producer.ts +29 -0
  205. package/src/ansi-text/screen.ts +18 -0
  206. package/src/ansi-text/sgr.ts +154 -0
  207. package/src/ansi-text/std.ts +28 -0
  208. package/src/ansi-text/style.ts +369 -0
  209. package/src/ansi-text/text-builder.ts +261 -0
  210. package/src/ansi-text/text-writer.ts +363 -0
  211. package/src/ansi-text/token.ts +76 -0
  212. package/src/ansi-text/tokenize.ts +212 -0
  213. package/src/ansi-text/truncator.ts +63 -0
  214. package/src/ansi-text/visible-width-of.ts +39 -0
  215. package/src/ansi-text/wrapper.ts +244 -0
  216. package/src/building/cli.ts +2 -2
  217. package/src/building/graph.ts +2 -2
  218. package/src/building/project-builder.ts +230 -0
  219. package/src/building/tsconfig.ts +2 -4
  220. package/src/index.ts +4 -6
  221. package/src/running/ensure-compiled.ts +2 -2
  222. package/src/util/commander.ts +4 -6
  223. package/src/util/index.ts +1 -0
  224. package/src/util/progress.ts +24 -61
  225. package/src/versioning/versioner.ts +2 -2
@@ -0,0 +1,261 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2024 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Producer } from "./producer.js";
8
+ import {
9
+ Color,
10
+ EightBitColor,
11
+ ExtendedColor,
12
+ RgbColor,
13
+ SgrOpcode,
14
+ SgrOpcodeBlock,
15
+ SgrOpcodeToUndoOpcode,
16
+ } from "./sgr.js";
17
+ import { Style } from "./style.js";
18
+ import { TextWriter } from "./text-writer.js";
19
+
20
+ /**
21
+ * Convenience API for building ANSI text.
22
+ *
23
+ * Allows you to create ANSI escape sequences using e.g. `ansi.bright.yellow.bg.blue.blink`.
24
+ */
25
+ export interface TextBuilder extends Style {
26
+ (...text: Producer.Sequence): TextBuilder;
27
+
28
+ readonly state: TextBuilder.State;
29
+ readonly bg: TextBuilder;
30
+ readonly not: TextBuilder;
31
+ readonly reset: TextBuilder;
32
+ readonly bold: TextBuilder;
33
+ readonly dim: TextBuilder;
34
+ readonly bright: TextBuilder;
35
+ readonly italic: TextBuilder;
36
+ readonly underline: TextBuilder;
37
+ readonly doubleUnderline: TextBuilder;
38
+ readonly blink: TextBuilder;
39
+ readonly fastBlink: TextBuilder;
40
+ readonly invert: TextBuilder;
41
+ readonly conceal: TextBuilder;
42
+ readonly strike: TextBuilder;
43
+ readonly black: TextBuilder;
44
+ readonly red: TextBuilder;
45
+ readonly green: TextBuilder;
46
+ readonly yellow: TextBuilder;
47
+ readonly blue: TextBuilder;
48
+ readonly magenta: TextBuilder;
49
+ readonly cyan: TextBuilder;
50
+ readonly white: TextBuilder;
51
+ color(color: Color | EightBitColor | RgbColor): TextBuilder;
52
+
53
+ factory: TextBuilder.Factory;
54
+ }
55
+
56
+ export function TextBuilder(
57
+ definition?: Style.InputDefinition | Style,
58
+ derivesFrom?: Style,
59
+ state?: TextBuilder.State,
60
+ ) {
61
+ if (derivesFrom instanceof TextBuilder) {
62
+ state = { ...(derivesFrom as TextBuilder).state, ...state };
63
+ } else if (state === undefined) {
64
+ state = {};
65
+ }
66
+
67
+ definition = Style.definitionOf(definition);
68
+
69
+ const self = function TextBuilderInstance(...text: Producer.Sequence) {
70
+ const sequence = self.state.sequence ? [...self.state.sequence] : [];
71
+ if (self.styleDefinition?.length) {
72
+ sequence.push(self.styleToken);
73
+ }
74
+ sequence.push(...text);
75
+ return TextBuilder(self, self, { sequence, revert: true });
76
+ } as TextBuilder;
77
+
78
+ Object.setPrototypeOf(self, TextBuilder.prototype);
79
+
80
+ (self as any).state = state;
81
+
82
+ if (definition !== undefined) {
83
+ self.styleDefinition = definition;
84
+ }
85
+
86
+ return self;
87
+ }
88
+
89
+ TextBuilder.prototype = Object.create(Style.prototype, {
90
+ bg: chmode({ bg: true }),
91
+ not: chmode({ not: true }),
92
+ bold: toggle("bold"),
93
+ dim: toggle("dim"),
94
+ bright: chmode({ bright: true }),
95
+ italic: toggle("italic"),
96
+ underline: toggle("underline"),
97
+ doubleUnderline: toggle("doubleUnderline"),
98
+ slowBlink: toggle("slowBlink"),
99
+ fastBlink: toggle("fastBlink"),
100
+ invert: toggle("invert"),
101
+ conceal: toggle("conceal"),
102
+ strike: toggle("strike"),
103
+ black: color("black"),
104
+ red: color("red"),
105
+ green: color("green"),
106
+ yellow: color("yellow"),
107
+ blue: color("blue"),
108
+ magenta: color("magenta"),
109
+ cyan: color("cyan"),
110
+ white: color("white"),
111
+
112
+ reset: {
113
+ get() {
114
+ return (this as TextBuilder).addStyle([0]);
115
+ },
116
+ },
117
+
118
+ color: {
119
+ value(this: TextBuilder, color: Color | EightBitColor | RgbColor) {
120
+ if (this.state.not) {
121
+ return this.addStyle([this.state.bg ? SgrOpcode.normalBg : SgrOpcode.normalFg]);
122
+ }
123
+
124
+ if (typeof color === "object") {
125
+ if ("color" in color) {
126
+ return this.addStyle([Color.extended, ExtendedColor.eightBit, color.color]);
127
+ }
128
+ return this.addStyle([Color.extended, ExtendedColor.rgb, color.r ?? 0, color.g ?? 0, color.b ?? 0]);
129
+ }
130
+
131
+ const block = this.state.bg
132
+ ? this.state.bright
133
+ ? SgrOpcodeBlock.bgBright
134
+ : SgrOpcodeBlock.bg
135
+ : this.state.bright
136
+ ? SgrOpcodeBlock.fgBright
137
+ : SgrOpcodeBlock.fg;
138
+
139
+ return this.addStyle([block + color]);
140
+ },
141
+ },
142
+
143
+ toString: {
144
+ value(this: TextBuilder) {
145
+ let { sequence } = this.state;
146
+ if (!sequence) {
147
+ sequence = [this.styleToken];
148
+ }
149
+
150
+ if (this.state.revert) {
151
+ sequence = [...sequence, this.undoStyle.styleToken];
152
+ }
153
+
154
+ const parts = Array<string>();
155
+
156
+ const writer = new TextWriter(part => parts.push(part));
157
+ writer.write(...sequence);
158
+ writer.close();
159
+
160
+ return parts.join("");
161
+ },
162
+ },
163
+
164
+ [Symbol.iterator]: {
165
+ get(this: TextBuilder) {
166
+ if (this.state.sequence === undefined) {
167
+ return {
168
+ next() {
169
+ return undefined;
170
+ },
171
+
172
+ done: true,
173
+ };
174
+ }
175
+ let sequence = this.state.sequence;
176
+ if (this.state.revert) {
177
+ sequence = [...sequence, this.undoStyle.styleToken];
178
+ }
179
+ const iterable = Producer.of(sequence);
180
+ return iterable[Symbol.iterator].bind(iterable);
181
+ },
182
+ },
183
+
184
+ factory: {
185
+ value: TextBuilder,
186
+ },
187
+ });
188
+
189
+ function chmode(state?: TextBuilder.State) {
190
+ return {
191
+ get(this: TextBuilder) {
192
+ return TextBuilder(this, this, state);
193
+ },
194
+ };
195
+ }
196
+
197
+ function toggle(name: keyof typeof SgrOpcode) {
198
+ const on = SgrOpcode[name];
199
+ const off = SgrOpcodeToUndoOpcode[on];
200
+ if (off === undefined) {
201
+ throw new Error(`Can't toggle opcode ${on}`);
202
+ }
203
+
204
+ return {
205
+ get(this: TextBuilder) {
206
+ return this.addStyle([this.state.not ? off : on]);
207
+ },
208
+ };
209
+ }
210
+
211
+ function color(color: keyof typeof Color) {
212
+ const opcode = Color[color];
213
+ return {
214
+ get(this: TextBuilder) {
215
+ return this.color(opcode);
216
+ },
217
+ };
218
+ }
219
+
220
+ export namespace TextBuilder {
221
+ export interface State {
222
+ /**
223
+ * If next build affects a color it will modify bg rather than fg.
224
+ */
225
+ readonly bg?: boolean;
226
+
227
+ /**
228
+ * If next build affects 8-bit color the color will render as bright.
229
+ */
230
+ readonly bright?: boolean;
231
+
232
+ /**
233
+ * If next build modifies ANSI styling its meaning is inverted.
234
+ */
235
+ readonly not?: boolean;
236
+
237
+ /**
238
+ * Serialization will include style reversion as the final token.
239
+ *
240
+ * Set after invoking builder as function, cleared when modifying style. This means that ansi.red("foo") is
241
+ * terminated but ansi.red("foo").green will render as a red "foo" and leave text styled green.
242
+ */
243
+ readonly revert?: boolean;
244
+
245
+ /**
246
+ * The serialization sequence. Populated by invoking builder as function.
247
+ */
248
+ readonly sequence?: Producer.Sequence;
249
+ }
250
+
251
+ export type Factory = (
252
+ definition?: Style.Definition | Style,
253
+ derivesFrom?: Style,
254
+ state?: TextBuilder.State,
255
+ ) => TextBuilder;
256
+ }
257
+
258
+ /**
259
+ * Initial builder.
260
+ */
261
+ export const ansi = TextBuilder();
@@ -0,0 +1,363 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2024 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Consumer } from "./consumer.js";
8
+ import { ContiguousOutputSegment } from "./contiguous-output-segment.js";
9
+ import { Producer } from "./producer.js";
10
+ import { SgrOpcode } from "./sgr.js";
11
+ import { Style } from "./style.js";
12
+ import { Token } from "./token.js";
13
+ import { tokenize } from "./tokenize.js";
14
+
15
+ const DEFAULT_TAB_WIDTH = 4;
16
+
17
+ /**
18
+ * Low-level text output with ANSI escape sequences, maintaining state regarding style and width of current line.
19
+ */
20
+ export class TextWriter implements Consumer {
21
+ tabWidth: number;
22
+
23
+ #terminalWidth?: number;
24
+ #currentLineWidth = 0;
25
+ #out: (text: string) => void;
26
+ #activeStyle = Style.Inherit;
27
+ #styleDirty = true;
28
+ #currentStyle = Style.Inherit;
29
+ #linePrefix?: ContiguousOutputSegment;
30
+ #state: Consumer.State;
31
+ #styleEnabled = true;
32
+ #isNewLine = true;
33
+ #buffer?: string[];
34
+ #revertHandlers?: Set<() => void>;
35
+
36
+ constructor(out: (text: string) => void, options?: Writer.Options) {
37
+ const { tabWidth, terminalWidth, linePrefix } = options ?? {};
38
+ this.#out = out;
39
+ this.tabWidth = tabWidth ?? DEFAULT_TAB_WIDTH;
40
+ this.#terminalWidth = terminalWidth;
41
+ if (linePrefix) {
42
+ this.#linePrefix = new ContiguousOutputSegment(...tokenize(linePrefix));
43
+ }
44
+
45
+ const self = this;
46
+
47
+ this.#state = function state(options?: Consumer.Options, executor?: () => void): Consumer.Context | undefined {
48
+ options = { ...options };
49
+
50
+ const revertTo = { ...self.state, options } as Consumer.Options;
51
+
52
+ const { linePrefix, style, buffer } = options;
53
+ if (linePrefix) {
54
+ if (self.#linePrefix) {
55
+ self.#linePrefix.push(linePrefix);
56
+ } else {
57
+ self.#linePrefix = new ContiguousOutputSegment(linePrefix);
58
+ }
59
+ }
60
+
61
+ if (style) {
62
+ if (self.#currentStyle) {
63
+ self.#currentStyle = self.#currentStyle.addStyle(style);
64
+ } else {
65
+ self.#currentStyle = style;
66
+ }
67
+ self.#styleDirty = true;
68
+ }
69
+
70
+ if (!!buffer !== !!self.#buffer) {
71
+ if (buffer) {
72
+ self.#buffer = [];
73
+ } else {
74
+ self.#buffer = undefined;
75
+ }
76
+ }
77
+
78
+ const context = {
79
+ close() {
80
+ if (self.#revertHandlers) {
81
+ for (const fn of self.#revertHandlers) {
82
+ fn();
83
+ }
84
+ }
85
+
86
+ if (revertTo.style) {
87
+ revertTo.style = self.#currentStyle.undoStyle.addStyle(revertTo.style);
88
+ } else {
89
+ revertTo.style = Style.None;
90
+ }
91
+
92
+ for (const key in revertTo) {
93
+ (self.state as any)[key] = (revertTo as any)[key];
94
+ }
95
+ },
96
+
97
+ [Symbol.dispose]() {
98
+ this.close();
99
+ },
100
+ };
101
+
102
+ if (executor) {
103
+ try {
104
+ executor();
105
+ } finally {
106
+ context.close();
107
+ }
108
+ } else {
109
+ return context;
110
+ }
111
+ } as Consumer.State;
112
+
113
+ Object.defineProperties(this.#state, {
114
+ style: {
115
+ get(this: never) {
116
+ return self.#currentStyle;
117
+ },
118
+
119
+ set(this: never, style) {
120
+ self.#currentStyle = style ?? Style.Inherit;
121
+ self.#styleDirty = true;
122
+ },
123
+
124
+ enumerable: true,
125
+ },
126
+
127
+ linePrefix: {
128
+ get(this: never) {
129
+ return self.#linePrefix?.toString();
130
+ },
131
+
132
+ set(this: never, prefix) {
133
+ if (prefix) {
134
+ self.#linePrefix = new ContiguousOutputSegment(...tokenize(prefix));
135
+ } else {
136
+ self.#linePrefix = undefined;
137
+ }
138
+ },
139
+
140
+ enumerable: true,
141
+ },
142
+
143
+ terminalWidth: {
144
+ get(this: never) {
145
+ return self.#terminalWidth;
146
+ },
147
+
148
+ set(this: never, width: number | undefined) {
149
+ self.#terminalWidth = width;
150
+ },
151
+
152
+ enumerable: true,
153
+ },
154
+
155
+ styleEnabled: {
156
+ get(this: never) {
157
+ return self.#styleEnabled;
158
+ },
159
+
160
+ set(this: never, enabled: boolean) {
161
+ self.#styleEnabled = enabled;
162
+ },
163
+
164
+ enumerable: true,
165
+ },
166
+
167
+ availableWidth: {
168
+ get(this: never) {
169
+ if (self.#terminalWidth === undefined) {
170
+ return undefined;
171
+ }
172
+
173
+ if (self.#linePrefix) {
174
+ const width = self.#terminalWidth - self.#linePrefix.width;
175
+ if (width > 0) {
176
+ return width;
177
+ }
178
+ return undefined;
179
+ }
180
+
181
+ return self.#terminalWidth;
182
+ },
183
+ },
184
+
185
+ remainingWidth: {
186
+ get(this: never) {
187
+ if (self.#terminalWidth === undefined) {
188
+ return undefined;
189
+ }
190
+ return self.#terminalWidth - self.#currentLineWidth;
191
+ },
192
+ },
193
+
194
+ buffer: {
195
+ get(this: never) {
196
+ return !!self.#buffer;
197
+ },
198
+
199
+ set(this: never, buffering: boolean) {
200
+ if (!!self.#buffer === buffering) {
201
+ return;
202
+ }
203
+ if (buffering) {
204
+ self.#buffer = [];
205
+ return;
206
+ }
207
+ if (self.#buffer) {
208
+ self.#out(self.#buffer.join(""));
209
+ self.#buffer = undefined;
210
+ }
211
+ },
212
+
213
+ enumerable: true,
214
+ },
215
+
216
+ onRevert: {
217
+ value(fn: () => void) {
218
+ if (!self.#revertHandlers) {
219
+ self.#revertHandlers = new Set();
220
+ }
221
+ self.#revertHandlers.add(fn);
222
+ },
223
+ },
224
+
225
+ offRevert: {
226
+ value(fn: () => void) {
227
+ if (self.#revertHandlers) {
228
+ self.#revertHandlers.add(fn);
229
+ }
230
+ },
231
+ },
232
+ });
233
+ }
234
+
235
+ get state() {
236
+ return this.#state;
237
+ }
238
+
239
+ write(...text: Producer.Sequence) {
240
+ for (const token of Producer.of(text)) {
241
+ this.#addToken(token);
242
+ }
243
+ }
244
+
245
+ close() {
246
+ this.#writeStyle();
247
+ }
248
+
249
+ /**
250
+ * Reset styling.
251
+ */
252
+ reset() {
253
+ if (this.#currentStyle.styleCodes.find(code => code !== SgrOpcode.reset)) {
254
+ this.#currentStyle = Style.None;
255
+ this.#styleDirty = true;
256
+ }
257
+ }
258
+
259
+ #addToken(token: Token, forLinePrefix = false) {
260
+ if (this.#isNewLine && this.#linePrefix && !forLinePrefix) {
261
+ this.#isNewLine = false;
262
+ const style = this.#currentStyle;
263
+ this.#currentStyle = Style.None;
264
+ this.#styleDirty = true;
265
+ for (const token of this.#linePrefix.tokens) {
266
+ this.#addToken(token, true);
267
+ }
268
+ this.#currentStyle = style;
269
+ this.#styleDirty = true;
270
+ }
271
+
272
+ switch (token.kind) {
273
+ case "newline":
274
+ this.#emitLine("\n");
275
+ break;
276
+
277
+ case "carriage-return":
278
+ this.#emitLine("\r");
279
+ break;
280
+
281
+ case "tab":
282
+ let width = this.tabWidth - (this.#currentLineWidth % this.tabWidth);
283
+ if (width === 0) {
284
+ width = this.tabWidth;
285
+ }
286
+ this.#writeText("".padStart(width));
287
+ this.#currentLineWidth += width;
288
+ break;
289
+
290
+ case "breaking":
291
+ this.#writeText(token.str);
292
+ this.#currentLineWidth += token.width;
293
+ break;
294
+
295
+ case "style":
296
+ this.#currentStyle = this.#currentStyle.addStyle(token.style);
297
+ this.#styleDirty = true;
298
+ break;
299
+
300
+ case "ansi":
301
+ if (this.#styleEnabled) {
302
+ this.#writeText(token.sequence);
303
+ }
304
+ if (token.newColumn !== undefined) {
305
+ // TODO - don't need to support yet but to be correct should adjust sequence to account for indent
306
+ if (!this.#currentLineWidth) {
307
+ this.#isNewLine = true;
308
+ }
309
+ this.#currentLineWidth = token.newColumn;
310
+ }
311
+ break;
312
+
313
+ case "nonbreaking":
314
+ this.#writeText(token.str);
315
+ this.#currentLineWidth += token.width;
316
+ break;
317
+ }
318
+ }
319
+
320
+ #writeText(text: string) {
321
+ this.#writeStyle();
322
+ this.#emit(text);
323
+ }
324
+
325
+ #writeStyle() {
326
+ if (this.#styleDirty && this.#styleEnabled) {
327
+ this.#styleDirty = false;
328
+
329
+ this.#emit(this.#activeStyle.diffStyle(this.#currentStyle).toString());
330
+
331
+ this.#activeStyle = this.#currentStyle;
332
+ }
333
+ }
334
+
335
+ #emit(text: string) {
336
+ if (this.#buffer) {
337
+ this.#buffer.push(text);
338
+ } else {
339
+ this.#out(text);
340
+ }
341
+ }
342
+
343
+ #emitLine(terminator?: string) {
344
+ this.#writeStyle();
345
+ this.#beginLine();
346
+ if (terminator) {
347
+ this.#emit(terminator);
348
+ }
349
+ }
350
+
351
+ #beginLine() {
352
+ this.#isNewLine = true;
353
+ this.#currentLineWidth = 0;
354
+ }
355
+ }
356
+
357
+ export namespace Writer {
358
+ export interface Options {
359
+ tabWidth?: number;
360
+ terminalWidth?: number;
361
+ linePrefix?: string;
362
+ }
363
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2024 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Style } from "./style.js";
8
+
9
+ /**
10
+ * An individual lexical token in a Unicode string with ANSI escape codes.
11
+ */
12
+ export type Token =
13
+ | NonbreakingToken
14
+ | BreakingToken
15
+ | StyleToken
16
+ | NewlineToken
17
+ | CarriageReturnToken
18
+ | TabToken
19
+ | AnsiToken;
20
+
21
+ /**
22
+ * Text sequence that is not whitespace or a control sequence.
23
+ */
24
+ export interface NonbreakingToken {
25
+ kind: "nonbreaking";
26
+ str: string;
27
+ width: number;
28
+ }
29
+
30
+ /**
31
+ * Non-tab non-newline whitespace sequence.
32
+ */
33
+ export interface BreakingToken {
34
+ kind: "breaking";
35
+ str: string;
36
+ width: number;
37
+ }
38
+
39
+ /**
40
+ * A text styling sequence.
41
+ */
42
+ export interface StyleToken {
43
+ kind: "style";
44
+ style: Style;
45
+ }
46
+
47
+ /**
48
+ * Newline character.
49
+ */
50
+ export interface NewlineToken {
51
+ kind: "newline";
52
+ }
53
+
54
+ /**
55
+ * Carriage return character.
56
+ */
57
+ export interface CarriageReturnToken {
58
+ kind: "carriage-return";
59
+ }
60
+
61
+ /**
62
+ * Tab character.
63
+ */
64
+ export interface TabToken {
65
+ kind: "tab";
66
+ }
67
+
68
+ /**
69
+ * Misc valid non-CSI (style) ANSI codes. Currently we tokenize because we have to parse them anyway to skip, but
70
+ * otherwise we ignore.
71
+ */
72
+ export interface AnsiToken {
73
+ kind: "ansi";
74
+ sequence: string;
75
+ newColumn?: number;
76
+ }