@matter/tools 0.12.2 → 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,212 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2024 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Chars } from "./chars.js";
8
+ import { Producer } from "./producer.js";
9
+ import { Style } from "./style.js";
10
+ import { Token } from "./token.js";
11
+
12
+ /**
13
+ * Convert ANSI text into a sequence of tokens.
14
+ */
15
+ export function* tokenize(text: string): Producer {
16
+ for (let pos = 0; pos < text.length; ) {
17
+ const unit = text[pos];
18
+ switch (unit) {
19
+ case "\n":
20
+ yield { kind: "newline" };
21
+ pos++;
22
+ break;
23
+
24
+ case "\r":
25
+ if (text[pos + 1] === "\n") {
26
+ yield { kind: "newline" };
27
+ pos += 2;
28
+ } else {
29
+ yield { kind: "carriage-return" };
30
+ pos += 1;
31
+ }
32
+ break;
33
+
34
+ case "\t":
35
+ yield { kind: "tab" };
36
+ pos++;
37
+ break;
38
+
39
+ case "\x1b":
40
+ let valid = false;
41
+ let newColumn: number | undefined;
42
+ const escapeStart = pos;
43
+ pos++;
44
+ switch (text[pos]) {
45
+ case "[":
46
+ // Fe CSI
47
+ pos++;
48
+
49
+ // Valid sequence members
50
+ while (text[pos] >= "\x30" && text[pos] <= "\x3f") {
51
+ pos++;
52
+ }
53
+
54
+ // Valid sequence termination
55
+ if (text[pos] >= "\0x40" && text[pos] <= "\x7e") {
56
+ const param = text.slice(escapeStart + 2, pos);
57
+
58
+ switch (text[pos]) {
59
+ case "m": // SGR (select graphics rendition), the sequence that controls styling
60
+ yield {
61
+ kind: "style",
62
+ style: Style(param),
63
+ };
64
+ pos++;
65
+ continue;
66
+
67
+ case "E": // Move up
68
+ case "F": // Move down
69
+ newColumn = 0;
70
+ break;
71
+
72
+ case "G": // Move to column
73
+ newColumn = Number.parseInt(param);
74
+ break;
75
+
76
+ case "H": // Move to row and column
77
+ const [, column] = param.split(";");
78
+ newColumn = column ? Number.parseInt(column) : 0;
79
+ break;
80
+
81
+ case "J": // Clear screen part
82
+ switch (param) {
83
+ case "2": // Entire screen
84
+ case "3": // Entire screen plus scrollback buffer
85
+ newColumn = 0;
86
+ }
87
+ break;
88
+ }
89
+
90
+ pos++;
91
+ valid = true;
92
+ }
93
+ break;
94
+
95
+ case "X":
96
+ case "]":
97
+ case "^":
98
+ case "_":
99
+ // Fe sequences that take a single string argument (<ESC X>, <ESC ]>, <ESC ^>, <ESC _>
100
+ // terminated by "\")
101
+ pos++;
102
+ while (pos < text.length) {
103
+ pos++;
104
+ if (text[pos] === "\\") {
105
+ valid = true;
106
+ break;
107
+ }
108
+ }
109
+ break;
110
+
111
+ default:
112
+ const code = text[pos];
113
+ if (
114
+ (code >= "\x40" && code <= "\x57") ||
115
+ (code >= "\x59" && code <= "\x5a") ||
116
+ (code >= "\x5c" && code <= "\x5d")
117
+ ) {
118
+ // Fe sequence not covered above
119
+ pos++;
120
+ valid = true;
121
+ } else if (code >= "\x30" && code <= "0x3f") {
122
+ // Fp sequence
123
+ pos++;
124
+ valid = true;
125
+ } else if (code >= "\x60" && code <= "0x7e") {
126
+ // Fs sequence
127
+ pos++;
128
+ valid = true;
129
+ } else if (code >= "\x20" && code <= "0x2f") {
130
+ pos++;
131
+ const code2 = text[pos];
132
+ if (code2 >= "\x30" && code2 <= "0x73") {
133
+ pos++;
134
+ valid = true;
135
+ }
136
+ }
137
+ break;
138
+ }
139
+
140
+ if (valid) {
141
+ const token: Token = {
142
+ kind: "ansi",
143
+ sequence: text.slice(escapeStart, pos),
144
+ };
145
+ if (newColumn !== undefined && !Number.isNaN(newColumn)) {
146
+ token.newColumn = newColumn;
147
+ }
148
+ yield token;
149
+ }
150
+
151
+ break;
152
+
153
+ default:
154
+ const start = pos;
155
+
156
+ // Whitespace - no surrogates, zero-width space does not contribute to width
157
+ if (Chars.breakingSpace.has(unit)) {
158
+ let width = 1;
159
+ pos++;
160
+ while (Chars.breakingSpace.has(text[pos])) {
161
+ pos++;
162
+ // No width for zero-width space
163
+ if (unit !== "\u200b") {
164
+ width++;
165
+ }
166
+ }
167
+ yield {
168
+ kind: "breaking",
169
+ str: text.slice(start, pos),
170
+ width,
171
+ };
172
+ break;
173
+ }
174
+
175
+ // Scan characters
176
+ let width = 0;
177
+ while (pos < text.length) {
178
+ let cp = text[pos];
179
+
180
+ // Combine proper surrogate pairs
181
+ if (cp >= "\ud800" && cp < "\udc00") {
182
+ const nextUnit = text[pos + 1];
183
+ if (nextUnit !== undefined && nextUnit >= "\udc00" && nextUnit < "\ue000") {
184
+ cp += nextUnit;
185
+ }
186
+ }
187
+
188
+ if (!cp.match(Chars.nonbreakingText)) {
189
+ break;
190
+ }
191
+
192
+ pos += cp.length;
193
+ if (!cp.match(Chars.zeroWidth)) {
194
+ width++;
195
+ }
196
+ }
197
+
198
+ // If we detected no characters, the code unit is garbage and we skip it entirely
199
+ if (start === pos) {
200
+ pos++;
201
+ break;
202
+ }
203
+
204
+ // Yield the token and skip forward to the last character
205
+ yield {
206
+ kind: "nonbreaking",
207
+ str: text.slice(start, pos),
208
+ width,
209
+ };
210
+ }
211
+ }
212
+ }
@@ -0,0 +1,63 @@
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
+
11
+ /**
12
+ * Writes lines truncated to a specific width.
13
+ */
14
+ export class Truncator implements Consumer {
15
+ #target: Consumer;
16
+ #addNewline: boolean;
17
+
18
+ constructor(target: Consumer, options: { addNewline?: boolean } = {}) {
19
+ const { addNewline } = options;
20
+ this.#target = target;
21
+ this.#addNewline = addNewline === undefined ? true : false;
22
+ }
23
+
24
+ get state() {
25
+ return this.#target.state;
26
+ }
27
+
28
+ write(...text: Producer.Sequence) {
29
+ const width = this.#target.state.remainingWidth;
30
+
31
+ if (width === undefined) {
32
+ this.#write(...text);
33
+ return;
34
+ }
35
+
36
+ const segment = new ContiguousOutputSegment(...text);
37
+ if (segment.width <= width) {
38
+ this.#write(...segment.tokens);
39
+ } else {
40
+ const scanner = segment.scan();
41
+
42
+ this.#write(...scanner.take(width - 1), { kind: "nonbreaking", str: "…", width: 1 });
43
+ for (const token of scanner) {
44
+ if (token.kind === "breaking" || token.kind === "nonbreaking") {
45
+ continue;
46
+ }
47
+ this.#write(token);
48
+ }
49
+ }
50
+ }
51
+
52
+ close() {
53
+ this.#target.close();
54
+ }
55
+
56
+ #write(...text: Producer.Sequence) {
57
+ if (this.#addNewline) {
58
+ this.#target.write(...text, { kind: "newline" });
59
+ } else {
60
+ this.#target.write(...text);
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2024 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * Returns visible width of a space or visible text segment.
9
+ */
10
+ export function visibleWidthOf(str: string) {
11
+ let width = 0;
12
+
13
+ for (let i = 0; i < str.length; i++) {
14
+ const charCode = str.charCodeAt(i);
15
+
16
+ // Skip zero width characters
17
+ switch (charCode) {
18
+ case 0x200b: // zwsp
19
+ case 0x200c: // zero width non-joiner
20
+ case 0x200d: // zero width joiner
21
+ case 0x2060: // word joiner
22
+ case 0xfeff: // bom
23
+ continue;
24
+ }
25
+
26
+ // Extend width
27
+ width++;
28
+
29
+ // Skip low surrogate if it properly follows a high surrogate
30
+ if (charCode >= 0xd800 && charCode < 0xdc00) {
31
+ const charCode2 = str.charCodeAt(i + 1);
32
+ if (charCode2 !== undefined && charCode2 >= 0xdc00 && charCode2 < 0xe000) {
33
+ i++;
34
+ }
35
+ }
36
+ }
37
+
38
+ return width;
39
+ }
@@ -0,0 +1,244 @@
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 { Style } from "./style.js";
11
+ import { type TextWriter } from "./text-writer.js";
12
+ import { Token } from "./token.js";
13
+ import { tokenize } from "./tokenize.js";
14
+
15
+ const NEWLINE: Token = { kind: "newline" };
16
+ const SPACE: Token = { kind: "nonbreaking", str: " ", width: 1 };
17
+
18
+ /**
19
+ * Writes to a {@link TextWriter} with support for smart wrapping of text.
20
+ */
21
+ export class Wrapper implements Consumer {
22
+ #target: Consumer;
23
+ #wrapPrefix?: ContiguousOutputSegment;
24
+ #preserveIndent: boolean;
25
+ #splitStyling: boolean;
26
+ #inputState: "newline" | "prefix" | "indent" | "word" | "space" = "newline";
27
+ #outputState: "newline" | "newwrap" | "inline" = "newline";
28
+ #indent?: ContiguousOutputSegment;
29
+ #output?: ContiguousOutputSegment;
30
+ #onRevert = () => {
31
+ // When state reverts we may have buffered output we have yet to emit. Do so now to ensure it receives proper
32
+ // styling
33
+ this.#emit();
34
+ };
35
+
36
+ constructor(target: Consumer, options: Wrapper.Options) {
37
+ const { wrapPrefix, preserveIndent, splitStyling } = options;
38
+
39
+ this.#target = target;
40
+ if (wrapPrefix !== undefined) {
41
+ this.#wrapPrefix = new ContiguousOutputSegment(...tokenize(wrapPrefix));
42
+ }
43
+ this.#preserveIndent = preserveIndent ?? true;
44
+ this.#splitStyling =
45
+ splitStyling ?? !!(this.#preserveIndent || this.#wrapPrefix || !this.#target.state.linePrefix);
46
+
47
+ this.#target.state.onRevert(this.#onRevert);
48
+ }
49
+
50
+ get state() {
51
+ return this.#target.state;
52
+ }
53
+
54
+ write(...text: Producer.Sequence) {
55
+ if (this.#target.state.terminalWidth === undefined) {
56
+ this.#target.write(...text);
57
+ return;
58
+ }
59
+
60
+ for (const token of Producer.of(text)) {
61
+ this.#addToken(token);
62
+ }
63
+ }
64
+
65
+ close() {
66
+ this.#emit();
67
+ this.#target.state.offRevert(this.#onRevert);
68
+ this.#target.close();
69
+ }
70
+
71
+ [Symbol.dispose]() {
72
+ this.close();
73
+ }
74
+
75
+ #addToken(token: Token) {
76
+ switch (token.kind) {
77
+ case "newline":
78
+ case "carriage-return":
79
+ this.#emit();
80
+ this.#target.write(token);
81
+ this.#indent = undefined;
82
+ this.#outputState = this.#inputState = "newline";
83
+ break;
84
+
85
+ case "ansi":
86
+ this.#enqueue(token);
87
+
88
+ switch (token.sequence) {
89
+ case Wrapper.prefixStart:
90
+ this.#inputState = "prefix";
91
+ break;
92
+
93
+ case Wrapper.prefixStop:
94
+ this.#inputState = "indent";
95
+ break;
96
+ }
97
+ break;
98
+
99
+ case "style":
100
+ this.#enqueue(token);
101
+ break;
102
+
103
+ case "nonbreaking":
104
+ if (this.#inputState === "prefix") {
105
+ this.#enqueue(token);
106
+ break;
107
+ }
108
+ if (this.#inputState === "indent") {
109
+ this.#indent = this.#output;
110
+ this.#output = undefined;
111
+ }
112
+ this.#inputState = "word";
113
+ this.#enqueue(token);
114
+ break;
115
+
116
+ case "tab":
117
+ case "breaking":
118
+ switch (this.#inputState) {
119
+ case "newline":
120
+ if (this.#preserveIndent) {
121
+ this.#enqueue(token);
122
+ }
123
+ this.#inputState = "indent";
124
+ break;
125
+
126
+ case "prefix":
127
+ case "indent":
128
+ this.#enqueue(token);
129
+ break;
130
+
131
+ case "word":
132
+ this.#emit();
133
+ this.#inputState = "space";
134
+ break;
135
+ }
136
+ break;
137
+ }
138
+ }
139
+
140
+ #emit() {
141
+ if (this.#output === undefined) {
142
+ return;
143
+ }
144
+
145
+ const outputState = this.#outputState;
146
+ if (outputState === "newline") {
147
+ this.#emitPrefix();
148
+ }
149
+ this.#outputState = "inline";
150
+
151
+ const output = this.#output;
152
+ this.#output = undefined;
153
+
154
+ let remainingWidth = this.#target.state.remainingWidth!;
155
+
156
+ // Leave room for a space except at the beginning of the line
157
+ if (remainingWidth !== undefined && outputState === "inline") {
158
+ remainingWidth--;
159
+ }
160
+
161
+ // Ideal case - not wrapping or segment fits on current line
162
+ if (remainingWidth === undefined || output.width <= remainingWidth) {
163
+ if (outputState === "inline") {
164
+ this.#target.write(SPACE);
165
+ }
166
+ this.#target.write(...output.tokens);
167
+ return;
168
+ }
169
+
170
+ // Least ideal case - the first- or tertiary- prefix fills up the line by itself. Give up on wrapping
171
+ const wrapPrefixWidth = (this.#wrapPrefix?.width ?? 0) + (this.#indent?.width ?? 0);
172
+ const availableWrappedWidth = this.#target.state.availableWidth! - wrapPrefixWidth;
173
+ if ((outputState === "newline" && remainingWidth <= 0) || availableWrappedWidth < 0) {
174
+ this.#target.write(...output.tokens);
175
+ return;
176
+ }
177
+
178
+ // Second best case - the segment fits on a new line
179
+ if (output.width < availableWrappedWidth) {
180
+ this.#wrap();
181
+ this.#target.write(...output.tokens);
182
+ return;
183
+ }
184
+
185
+ // Third best case - we need to wrap the segment itself
186
+ const scanner = output.scan();
187
+ if (outputState === "inline") {
188
+ this.#target.write(SPACE);
189
+ }
190
+ this.#target.write(...scanner.take(remainingWidth));
191
+ while (!scanner.done) {
192
+ this.#wrap();
193
+ this.#target.write(...scanner.take(availableWrappedWidth));
194
+ }
195
+ }
196
+
197
+ #emitPrefix(extra?: ContiguousOutputSegment) {
198
+ if (this.#indent !== undefined) {
199
+ this.#target.write(...this.#indent.tokens);
200
+ }
201
+ if (extra !== undefined) {
202
+ this.#target.write(...extra.tokens);
203
+ }
204
+ }
205
+
206
+ #wrap() {
207
+ let style: Style | undefined;
208
+ if (this.#splitStyling) {
209
+ style = this.#target.state.style;
210
+ this.#target.write({ kind: "style", style: Style.None });
211
+ }
212
+ this.#target.write(NEWLINE);
213
+ this.#emitPrefix(this.#wrapPrefix);
214
+ if (style) {
215
+ this.#target.write({ kind: "style", style });
216
+ }
217
+ }
218
+
219
+ #enqueue(token: Token) {
220
+ if (this.#output) {
221
+ this.#output.push(token);
222
+ } else {
223
+ this.#output = new ContiguousOutputSegment(token);
224
+ }
225
+ }
226
+ }
227
+
228
+ export namespace Wrapper {
229
+ export interface Options {
230
+ wrapPrefix?: string;
231
+ preserveIndent?: boolean;
232
+ splitStyling?: boolean;
233
+ }
234
+
235
+ /**
236
+ * Private - begin demarcation of line prefix.
237
+ */
238
+ export const prefixStart = "\x1b[<<~";
239
+
240
+ /**
241
+ * Private - end demarcation of line prefix.
242
+ */
243
+ export const prefixStop = "\x1b[>>~";
244
+ }
@@ -6,9 +6,9 @@
6
6
 
7
7
  import { commander } from "../util/commander.js";
8
8
  import { Package } from "../util/package.js";
9
- import { Builder, Target } from "./builder.js";
10
9
  import { buildDocs, mergeDocs } from "./docs.js";
11
10
  import { Graph } from "./graph.js";
11
+ import { ProjectBuilder, Target } from "./project-builder.js";
12
12
  import { Project } from "./project.js";
13
13
  import { syncAllTsconfigs } from "./tsconfig.js";
14
14
 
@@ -105,7 +105,7 @@ export async function main(argv = process.argv) {
105
105
  }
106
106
 
107
107
  function builder(graph?: Graph) {
108
- return new Builder({ ...args, targets: [...targets], graph });
108
+ return new ProjectBuilder({ ...args, targets: [...targets], graph });
109
109
  }
110
110
 
111
111
  switch (mode as Mode) {
@@ -7,8 +7,8 @@
7
7
  import colors from "ansi-colors";
8
8
  import { JsonNotFoundError, Package } from "../util/package.js";
9
9
  import { Progress } from "../util/progress.js";
10
- import { Builder } from "./builder.js";
11
10
  import { InternalBuildError } from "./error.js";
11
+ import { ProjectBuilder } from "./project-builder.js";
12
12
  import { BUILD_INFO_LOCATION, BuildInformation, Project } from "./project.js";
13
13
 
14
14
  /**
@@ -72,7 +72,7 @@ export class Graph {
72
72
 
73
73
  // TODO - parallelization will be trivial except need to update Progress to support display of multiple simultaneous
74
74
  // tasks
75
- async build(builder: Builder, showSkipped = true) {
75
+ async build(builder: ProjectBuilder, showSkipped = true) {
76
76
  const toBuild = new Set(this.nodes);
77
77
 
78
78
  const needsConfig = this.nodes.find(node => node.pkg.hasConfig);