@alchemy.run/sigil 0.0.0-alpha.4 → 0.0.0-alpha.6

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 (138) hide show
  1. package/README.md +21 -9
  2. package/THIRD_PARTY_NOTICES.md +39 -1
  3. package/dist/Text-BobFKi74.d.ts +452 -0
  4. package/dist/ansi.d.ts +122 -131
  5. package/dist/ansi.js +86 -6
  6. package/dist/capabilities.d.ts +5 -0
  7. package/dist/capabilities.js +3 -0
  8. package/dist/cell-_ZVhbfl0.js +44 -0
  9. package/dist/color-CkbalRqK.js +2 -0
  10. package/dist/color-policy-BMzMwV7Q.d.ts +22 -0
  11. package/dist/color-policy-SVj1pYTA.js +560 -0
  12. package/dist/color-profile-DHhQHY55.js +36 -0
  13. package/dist/color-profile-u0Nhe9Nv.d.ts +97 -0
  14. package/dist/color.d.ts +21 -0
  15. package/dist/color.js +3 -0
  16. package/dist/cursor-position-D2LAkRG0.d.ts +7 -0
  17. package/dist/detect-Bh4yGP6w.d.ts +186 -0
  18. package/dist/detect-BuTXtY6e.js +373 -0
  19. package/dist/env-YVw64yZS.js +9 -0
  20. package/dist/escapes-CB_6CWOE.d.ts +72 -0
  21. package/dist/geometry-BxXOzJgo.d.ts +11 -0
  22. package/dist/index-DZ88EXJv.d.ts +21 -0
  23. package/dist/index.d.ts +143 -498
  24. package/dist/index.js +1026 -2244
  25. package/dist/osc-CCH7xDoS.js +71 -0
  26. package/dist/osc-Cn0fw77g.d.ts +23 -0
  27. package/dist/paint-C19minOS.d.ts +81 -0
  28. package/dist/query-vaIeGOkH.d.ts +152 -0
  29. package/dist/router.d.ts +392 -0
  30. package/dist/router.js +709 -0
  31. package/dist/sample-Cqw1bjUL.js +445 -0
  32. package/dist/screen-BOSLQ8fF.d.ts +49 -0
  33. package/dist/screen-CiPytswf.js +342 -0
  34. package/dist/screen.d.ts +5 -0
  35. package/dist/screen.js +5 -0
  36. package/dist/semantic-text-style-DIMzC7xt.js +91 -0
  37. package/dist/serialize-BTkAZgw1.js +79 -0
  38. package/dist/session-aZr9O8h3.js +665 -0
  39. package/dist/sgr-BhwaWAJB.js +246 -0
  40. package/dist/store-CgrG9K4y.d.ts +72 -0
  41. package/dist/string-width-CijQwpIk.js +69 -0
  42. package/dist/strip-BvU4toXG.js +6 -0
  43. package/dist/terminal.d.ts +118 -0
  44. package/dist/terminal.js +2 -0
  45. package/dist/tokenize-AjqbvtiT.js +1242 -0
  46. package/dist/tokenize-Dx1y_l5H.d.ts +57 -0
  47. package/dist/truncate-D31fhU6i.js +562 -0
  48. package/dist/use-focus-BzqAJi0n.js +1337 -0
  49. package/package.json +41 -9
  50. package/src/ansi/chalk.ts +5 -3
  51. package/src/ansi/escapes.ts +14 -0
  52. package/src/ansi/graphemes.ts +8 -0
  53. package/src/ansi/hyperlink.ts +44 -0
  54. package/src/ansi/index.ts +3 -1
  55. package/src/ansi/osc.ts +77 -0
  56. package/src/ansi/tokenize.ts +3 -4
  57. package/src/capabilities/color-policy.ts +34 -0
  58. package/src/capabilities/detect.ts +594 -0
  59. package/src/capabilities/index.ts +37 -0
  60. package/src/capabilities/query.ts +657 -0
  61. package/src/capabilities/store.ts +379 -0
  62. package/src/color/index.ts +3 -0
  63. package/src/color/paint.ts +169 -0
  64. package/src/color/palette.ts +48 -0
  65. package/src/color/sample.ts +323 -0
  66. package/src/color.ts +1 -0
  67. package/src/components/AnsiText.tsx +42 -0
  68. package/src/components/App.tsx +98 -10
  69. package/src/components/BackgroundContext.ts +2 -3
  70. package/src/components/Box.tsx +0 -8
  71. package/src/components/CursorContext.ts +1 -1
  72. package/src/components/Hyperlink.tsx +56 -0
  73. package/src/components/TerminalOscContext.ts +25 -0
  74. package/src/components/Text.tsx +22 -45
  75. package/src/components/Transform.tsx +1 -1
  76. package/src/dom.ts +11 -2
  77. package/src/global.d.ts +3 -0
  78. package/src/hooks/use-capabilities.ts +73 -0
  79. package/src/hooks/use-cursor.ts +2 -2
  80. package/src/hooks/use-terminal-osc.ts +59 -0
  81. package/src/index.ts +45 -1
  82. package/src/ink.tsx +213 -153
  83. package/src/{render-node-to-output.ts → paint-tree.ts} +75 -48
  84. package/src/reconciler.ts +24 -3
  85. package/src/render-background.ts +36 -15
  86. package/src/render-border.ts +94 -61
  87. package/src/render-frame.ts +83 -0
  88. package/src/render-to-string.ts +21 -6
  89. package/src/render.ts +15 -6
  90. package/src/router/components.tsx +343 -0
  91. package/src/router/context.ts +41 -0
  92. package/src/router/history.ts +194 -0
  93. package/src/router/hooks.tsx +391 -0
  94. package/src/router/index.ts +34 -0
  95. package/src/router/matcher.ts +571 -0
  96. package/src/screen/ansi.ts +184 -0
  97. package/src/screen/canvas.ts +160 -0
  98. package/src/screen/cell.ts +138 -0
  99. package/src/screen/color-profile.ts +47 -0
  100. package/src/screen/geometry.ts +9 -0
  101. package/src/screen/index.ts +6 -0
  102. package/src/screen/screen.ts +305 -0
  103. package/src/screen/serialize.ts +129 -0
  104. package/src/screen.ts +1 -0
  105. package/src/semantic-text-style.ts +118 -0
  106. package/src/squash-text-nodes.ts +2 -5
  107. package/src/structured-text.ts +325 -0
  108. package/src/styles.ts +19 -14
  109. package/src/terminal/index.ts +2 -0
  110. package/src/terminal/inline-presenter.ts +120 -0
  111. package/src/terminal/input.ts +86 -0
  112. package/src/terminal/render-scheduler.ts +37 -0
  113. package/src/terminal/screen-presenter.ts +188 -0
  114. package/src/terminal/session.ts +407 -0
  115. package/src/terminal.ts +1 -0
  116. package/src/testing/browser.ts +588 -0
  117. package/src/testing/emulators.ts +205 -0
  118. package/src/testing/explorer-app/index.html +12 -0
  119. package/src/testing/explorer-app/main.ts +381 -0
  120. package/src/testing/explorer-app/style.css +194 -0
  121. package/src/testing/explorer-app/tsconfig.json +15 -0
  122. package/src/testing/explorer-app/vite-env.d.ts +1 -0
  123. package/src/testing/index.ts +26 -0
  124. package/src/testing/keys.ts +56 -0
  125. package/src/testing/live.ts +85 -0
  126. package/src/testing/matchers.ts +70 -0
  127. package/src/testing/public.ts +94 -0
  128. package/src/testing/terminal.ts +349 -0
  129. package/src/testing/vitest.ts +157 -0
  130. package/src/transform-adapter.ts +14 -0
  131. package/src/wrap-text.ts +4 -0
  132. package/dist/sgr-CMfEpjSk.d.ts +0 -91
  133. package/dist/truncate-Cr6xVFMa.js +0 -2330
  134. package/src/ansi/supports-color.ts +0 -207
  135. package/src/colorize.ts +0 -60
  136. package/src/log-update.ts +0 -370
  137. package/src/output.ts +0 -308
  138. package/src/renderer.ts +0 -73
package/src/output.ts DELETED
@@ -1,308 +0,0 @@
1
- import { sliceAnsi } from "#/ansi/slice.ts";
2
- import { stringWidth } from "#/ansi/string-width.ts";
3
- import {
4
- type StyledChar,
5
- styledCharsFromTokens,
6
- styledCharsToString,
7
- tokenize,
8
- } from "#/ansi/tokenize.ts";
9
- import { type OutputTransformer } from "#/render-node-to-output.ts";
10
-
11
- /**
12
- "Virtual" output class
13
-
14
- Handles the positioning and saving of the output of each node in the tree. Also responsible for applying transformations to each character of the output.
15
-
16
- Used to generate the final output of all nodes before writing it to actual output stream (e.g. stdout)
17
- */
18
-
19
- type Options = {
20
- width: number;
21
- height: number;
22
- };
23
-
24
- type Operation = WriteOperation | ClipOperation | UnclipOperation;
25
-
26
- type WriteOperation = {
27
- type: "write";
28
- x: number;
29
- y: number;
30
- text: string;
31
- transformers: OutputTransformer[];
32
- };
33
-
34
- type ClipOperation = {
35
- type: "clip";
36
- clip: Clip;
37
- };
38
-
39
- type Clip = {
40
- x1: number | undefined;
41
- x2: number | undefined;
42
- y1: number | undefined;
43
- y2: number | undefined;
44
- };
45
-
46
- type UnclipOperation = {
47
- type: "unclip";
48
- };
49
-
50
- class OutputCaches {
51
- widths = new Map<string, number>();
52
- blockWidths = new Map<string, number>();
53
- styledChars = new Map<string, StyledChar[]>();
54
-
55
- getStyledChars(line: string): StyledChar[] {
56
- let cached = this.styledChars.get(line);
57
- if (cached === undefined) {
58
- cached = styledCharsFromTokens(tokenize(line));
59
- this.styledChars.set(line, cached);
60
- }
61
-
62
- return cached;
63
- }
64
-
65
- getStringWidth(text: string): number {
66
- let cached = this.widths.get(text);
67
- if (cached === undefined) {
68
- cached = stringWidth(text);
69
- this.widths.set(text, cached);
70
- }
71
-
72
- return cached;
73
- }
74
-
75
- getWidestLine(text: string): number {
76
- let cached = this.blockWidths.get(text);
77
- if (cached === undefined) {
78
- let lineWidth = 0;
79
- for (const line of text.split("\n")) {
80
- lineWidth = Math.max(lineWidth, this.getStringWidth(line));
81
- }
82
-
83
- cached = lineWidth;
84
- this.blockWidths.set(text, cached);
85
- }
86
-
87
- return cached;
88
- }
89
- }
90
-
91
- export class Output {
92
- width: number;
93
- height: number;
94
-
95
- private readonly operations: Operation[] = [];
96
- private readonly caches: OutputCaches = new OutputCaches();
97
-
98
- constructor(options: Options) {
99
- const { width, height } = options;
100
-
101
- this.width = width;
102
- this.height = height;
103
- }
104
-
105
- write(x: number, y: number, text: string, options: { transformers: OutputTransformer[] }): void {
106
- const { transformers } = options;
107
-
108
- if (!text) {
109
- return;
110
- }
111
-
112
- this.operations.push({
113
- type: "write",
114
- x,
115
- y,
116
- text,
117
- transformers,
118
- });
119
- }
120
-
121
- clip(clip: Clip) {
122
- this.operations.push({
123
- type: "clip",
124
- clip,
125
- });
126
- }
127
-
128
- unclip() {
129
- this.operations.push({
130
- type: "unclip",
131
- });
132
- }
133
-
134
- get(): { output: string; height: number } {
135
- // Initialize output array with a specific set of rows, so that margin/padding at the bottom is preserved
136
- const output: StyledChar[][] = [];
137
-
138
- for (let y = 0; y < this.height; y++) {
139
- const row: StyledChar[] = [];
140
-
141
- for (let x = 0; x < this.width; x++) {
142
- row.push({
143
- type: "char",
144
- value: " ",
145
- fullWidth: false,
146
- styles: [],
147
- });
148
- }
149
-
150
- output.push(row);
151
- }
152
-
153
- const clips: Clip[] = [];
154
-
155
- for (const operation of this.operations) {
156
- if (operation.type === "clip") {
157
- clips.push(operation.clip);
158
- }
159
-
160
- if (operation.type === "unclip") {
161
- clips.pop();
162
- }
163
-
164
- if (operation.type === "write") {
165
- const { text, transformers } = operation;
166
- let { x, y } = operation;
167
- let lines = text.split("\n");
168
-
169
- const clip = clips.at(-1);
170
-
171
- if (clip) {
172
- const clipHorizontally = typeof clip?.x1 === "number" && typeof clip?.x2 === "number";
173
-
174
- const clipVertically = typeof clip?.y1 === "number" && typeof clip?.y2 === "number";
175
-
176
- // If text is positioned outside of clipping area altogether,
177
- // skip to the next operation to avoid unnecessary calculations
178
- if (clipHorizontally) {
179
- const width = this.caches.getWidestLine(text);
180
-
181
- if (x + width < clip.x1! || x > clip.x2!) {
182
- continue;
183
- }
184
- }
185
-
186
- if (clipVertically) {
187
- const height = lines.length;
188
-
189
- if (y + height < clip.y1! || y > clip.y2!) {
190
- continue;
191
- }
192
- }
193
-
194
- if (clipHorizontally) {
195
- lines = lines.map((line) => {
196
- const from = x < clip.x1! ? clip.x1! - x : 0;
197
- const width = this.caches.getStringWidth(line);
198
- const to = x + width > clip.x2! ? clip.x2! - x : width;
199
-
200
- return sliceAnsi(line, from, to);
201
- });
202
-
203
- if (x < clip.x1!) {
204
- x = clip.x1!;
205
- }
206
- }
207
-
208
- if (clipVertically) {
209
- const from = y < clip.y1! ? clip.y1! - y : 0;
210
- const height = lines.length;
211
- const to = y + height > clip.y2! ? clip.y2! - y : height;
212
-
213
- lines = lines.slice(from, to);
214
-
215
- if (y < clip.y1!) {
216
- y = clip.y1!;
217
- }
218
- }
219
- }
220
-
221
- let offsetY = 0;
222
-
223
- for (let [index, line] of lines.entries()) {
224
- const currentLine = output[y + offsetY];
225
-
226
- // Line can be missing if `text` is taller than height of pre-initialized `this.output`
227
- if (!currentLine) {
228
- continue;
229
- }
230
-
231
- for (const transformer of transformers) {
232
- line = transformer(line, index);
233
- }
234
-
235
- const characters = this.caches.getStyledChars(line);
236
- let offsetX = x;
237
-
238
- // Nothing to write (e.g. line was clipped away).
239
- if (characters.length === 0) {
240
- offsetY++;
241
- continue;
242
- }
243
-
244
- const spaceCell: StyledChar = {
245
- type: "char",
246
- value: " ",
247
- fullWidth: false,
248
- styles: [],
249
- };
250
-
251
- // Wide characters (e.g. CJK) occupy two cells: a leading
252
- // cell with the character and a trailing placeholder with
253
- // value ''. When an overlapping write lands in the middle
254
- // of a wide character, the boundary cells need cleanup so
255
- // the terminal never renders a half-visible wide character.
256
- if (
257
- currentLine[offsetX]?.value === "" &&
258
- offsetX > 0 &&
259
- this.caches.getStringWidth(currentLine[offsetX - 1]?.value ?? "") > 1
260
- ) {
261
- currentLine[offsetX - 1] = spaceCell;
262
- }
263
-
264
- for (const character of characters) {
265
- currentLine[offsetX] = character;
266
-
267
- // Determine printed width using string-width to align with measurement
268
- const characterWidth = Math.max(1, this.caches.getStringWidth(character.value));
269
-
270
- // For multi-column characters, clear following cells to avoid stray spaces/artifacts
271
- if (characterWidth > 1) {
272
- for (let columnOffset = 1; columnOffset < characterWidth; columnOffset++) {
273
- currentLine[offsetX + columnOffset] = {
274
- type: "char",
275
- value: "",
276
- fullWidth: false,
277
- styles: character.styles,
278
- };
279
- }
280
- }
281
-
282
- offsetX += characterWidth;
283
- }
284
-
285
- if (currentLine[offsetX]?.value === "") {
286
- currentLine[offsetX] = spaceCell;
287
- }
288
-
289
- offsetY++;
290
- }
291
- }
292
- }
293
-
294
- const generatedOutput = output
295
- .map((line) => {
296
- // See https://github.com/vadimdemedes/ink/pull/564#issuecomment-1637022742
297
- const lineWithoutEmptyItems = line.filter((item) => item !== undefined);
298
-
299
- return styledCharsToString(lineWithoutEmptyItems).trimEnd();
300
- })
301
- .join("\n");
302
-
303
- return {
304
- output: generatedOutput,
305
- height: output.length,
306
- };
307
- }
308
- }
package/src/renderer.ts DELETED
@@ -1,73 +0,0 @@
1
- import { type DOMElement } from "#/dom.ts";
2
- import { Output } from "#/output.ts";
3
- import { renderNodeToOutput, renderNodeToScreenReaderOutput } from "#/render-node-to-output.ts";
4
-
5
- type Result = {
6
- output: string;
7
- outputHeight: number;
8
- staticOutput: string;
9
- };
10
-
11
- export const renderer = (node: DOMElement, isScreenReaderEnabled: boolean): Result => {
12
- if (node.yogaNode) {
13
- if (isScreenReaderEnabled) {
14
- const output = renderNodeToScreenReaderOutput(node, {
15
- skipStaticElements: true,
16
- });
17
-
18
- const outputHeight = output === "" ? 0 : output.split("\n").length;
19
-
20
- let staticOutput = "";
21
-
22
- if (node.staticNode) {
23
- staticOutput = renderNodeToScreenReaderOutput(node.staticNode, {
24
- skipStaticElements: false,
25
- });
26
- }
27
-
28
- return {
29
- output,
30
- outputHeight,
31
- staticOutput: staticOutput ? `${staticOutput}\n` : "",
32
- };
33
- }
34
-
35
- const output = new Output({
36
- width: node.yogaNode.getComputedWidth(),
37
- height: node.yogaNode.getComputedHeight(),
38
- });
39
-
40
- renderNodeToOutput(node, output, {
41
- skipStaticElements: true,
42
- });
43
-
44
- let staticOutput;
45
-
46
- if (node.staticNode?.yogaNode) {
47
- staticOutput = new Output({
48
- width: node.staticNode.yogaNode.getComputedWidth(),
49
- height: node.staticNode.yogaNode.getComputedHeight(),
50
- });
51
-
52
- renderNodeToOutput(node.staticNode, staticOutput, {
53
- skipStaticElements: false,
54
- });
55
- }
56
-
57
- const { output: generatedOutput, height: outputHeight } = output.get();
58
-
59
- return {
60
- output: generatedOutput,
61
- outputHeight,
62
- // Newline at the end is needed, because static output doesn't have one, so
63
- // interactive output will override last line of static output
64
- staticOutput: staticOutput ? `${staticOutput.get().output}\n` : "",
65
- };
66
- }
67
-
68
- return {
69
- output: "",
70
- outputHeight: 0,
71
- staticOutput: "",
72
- };
73
- };