@swifttui/web 0.0.14 → 0.0.16

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 (92) hide show
  1. package/README.md +24 -10
  2. package/dist/index.d.ts +9 -0
  3. package/dist/index.js +9 -0
  4. package/dist/manifest.d.ts +2 -0
  5. package/dist/manifest.js +2 -0
  6. package/dist/src/AccessibilityTree.js +156 -0
  7. package/dist/src/AccessibilityTree.js.map +1 -0
  8. package/dist/src/BoxDrawingRenderer.js +1106 -0
  9. package/dist/src/BoxDrawingRenderer.js.map +1 -0
  10. package/dist/src/WebHostApp.d.ts +41 -0
  11. package/dist/src/WebHostApp.js +135 -0
  12. package/dist/src/WebHostApp.js.map +1 -0
  13. package/dist/src/WebHostSceneManifest.d.ts +18 -0
  14. package/dist/src/WebHostSceneManifest.js +70 -0
  15. package/dist/src/WebHostSceneManifest.js.map +1 -0
  16. package/dist/src/WebHostSceneRuntime.d.ts +112 -0
  17. package/dist/src/WebHostSceneRuntime.js +651 -0
  18. package/dist/src/WebHostSceneRuntime.js.map +1 -0
  19. package/dist/src/WebHostSurfaceTransport.d.ts +166 -0
  20. package/dist/src/WebHostSurfaceTransport.js +252 -0
  21. package/dist/src/WebHostSurfaceTransport.js.map +1 -0
  22. package/dist/src/WebHostTerminalStyle.d.ts +92 -0
  23. package/dist/src/WebHostTerminalStyle.js +277 -0
  24. package/dist/src/WebHostTerminalStyle.js.map +1 -0
  25. package/dist/src/WebHostTestFixtures.d.ts +5 -0
  26. package/dist/src/WebHostTestFixtures.js +9 -0
  27. package/dist/src/WebHostTestFixtures.js.map +1 -0
  28. package/dist/src/WebSocketSceneBridge.d.ts +53 -0
  29. package/dist/src/WebSocketSceneBridge.js +124 -0
  30. package/dist/src/WebSocketSceneBridge.js.map +1 -0
  31. package/dist/src/wasi/BrowserWASIBridge.d.ts +33 -0
  32. package/dist/src/wasi/BrowserWASIBridge.js +97 -0
  33. package/dist/src/wasi/BrowserWASIBridge.js.map +1 -0
  34. package/dist/src/wasi/SharedInputQueue.d.ts +31 -0
  35. package/dist/src/wasi/SharedInputQueue.js +102 -0
  36. package/dist/src/wasi/SharedInputQueue.js.map +1 -0
  37. package/dist/src/wasi/StdIOPipe.d.ts +15 -0
  38. package/dist/src/wasi/StdIOPipe.js +56 -0
  39. package/dist/src/wasi/StdIOPipe.js.map +1 -0
  40. package/dist/src/wasi/WasiPollScheduler.js +114 -0
  41. package/dist/src/wasi/WasiPollScheduler.js.map +1 -0
  42. package/dist/src/wasi/WasmSceneRuntime.d.ts +23 -0
  43. package/dist/src/wasi/WasmSceneRuntime.js +119 -0
  44. package/dist/src/wasi/WasmSceneRuntime.js.map +1 -0
  45. package/dist/src/wasi/WasmSceneWorker.d.ts +27 -0
  46. package/dist/src/wasi/WasmSceneWorker.js +109 -0
  47. package/dist/src/wasi/WasmSceneWorker.js.map +1 -0
  48. package/dist/testing.d.ts +2 -0
  49. package/dist/testing.js +2 -0
  50. package/dist/wasi-worker.d.ts +2 -0
  51. package/dist/wasi-worker.js +2 -0
  52. package/dist/wasi.d.ts +6 -0
  53. package/dist/wasi.js +6 -0
  54. package/dist/websocket.d.ts +2 -0
  55. package/dist/websocket.js +2 -0
  56. package/package.json +49 -18
  57. package/AGENTS.md +0 -52
  58. package/cli.ts +0 -168
  59. package/index.html +0 -50
  60. package/index.ts +0 -8
  61. package/manifest.ts +0 -1
  62. package/src/AccessibilityTree.ts +0 -262
  63. package/src/BoxDrawingRenderer.ts +0 -585
  64. package/src/PublicEntrypointBoundary.test.ts +0 -20
  65. package/src/WebHostApp.test.ts +0 -222
  66. package/src/WebHostApp.ts +0 -269
  67. package/src/WebHostSceneManifest.test.ts +0 -38
  68. package/src/WebHostSceneManifest.ts +0 -156
  69. package/src/WebHostSceneRuntime.test.ts +0 -1982
  70. package/src/WebHostSceneRuntime.ts +0 -1142
  71. package/src/WebHostSurfaceTransport.test.ts +0 -362
  72. package/src/WebHostSurfaceTransport.ts +0 -691
  73. package/src/WebHostTerminalStyle.test.ts +0 -123
  74. package/src/WebHostTerminalStyle.ts +0 -471
  75. package/src/WebHostTestFixtures.ts +0 -10
  76. package/src/WebSocketSceneBridge.test.ts +0 -198
  77. package/src/WebSocketSceneBridge.ts +0 -233
  78. package/src/browser.ts +0 -59
  79. package/src/wasi/BrowserWASIBridge.test.ts +0 -168
  80. package/src/wasi/BrowserWASIBridge.ts +0 -167
  81. package/src/wasi/SharedInputQueue.test.ts +0 -146
  82. package/src/wasi/SharedInputQueue.ts +0 -199
  83. package/src/wasi/StdIOPipe.ts +0 -72
  84. package/src/wasi/WasiPollScheduler.test.ts +0 -176
  85. package/src/wasi/WasiPollScheduler.ts +0 -305
  86. package/src/wasi/WasmSceneRuntime.ts +0 -205
  87. package/src/wasi/WasmSceneWorker.ts +0 -182
  88. package/testing.ts +0 -1
  89. package/tsconfig.json +0 -29
  90. package/wasi-worker.ts +0 -1
  91. package/wasi.ts +0 -4
  92. package/websocket.ts +0 -1
@@ -0,0 +1,92 @@
1
+ //#region src/WebHostTerminalStyle.d.ts
2
+ type WebHostTerminalCursorStyle = "block" | "bar" | "underline";
3
+ interface WebHostANSIColors {
4
+ black?: string;
5
+ red?: string;
6
+ green?: string;
7
+ yellow?: string;
8
+ blue?: string;
9
+ magenta?: string;
10
+ cyan?: string;
11
+ white?: string;
12
+ brightBlack?: string;
13
+ brightRed?: string;
14
+ brightGreen?: string;
15
+ brightYellow?: string;
16
+ brightBlue?: string;
17
+ brightMagenta?: string;
18
+ brightCyan?: string;
19
+ brightWhite?: string;
20
+ }
21
+ interface WebHostTerminalPalette {
22
+ foreground?: string;
23
+ background?: string;
24
+ cursor?: string;
25
+ selectionBackground?: string;
26
+ selectionForeground?: string;
27
+ ansi?: WebHostANSIColors;
28
+ }
29
+ interface WebHostTerminalTheme {
30
+ foreground?: string;
31
+ background?: string;
32
+ tint?: string;
33
+ separator?: string;
34
+ selection?: string;
35
+ placeholder?: string;
36
+ link?: string;
37
+ fill?: string;
38
+ windowBackground?: string;
39
+ success?: string;
40
+ warning?: string;
41
+ danger?: string;
42
+ info?: string;
43
+ muted?: string;
44
+ }
45
+ interface WebHostTerminalStyle {
46
+ fontSize?: number;
47
+ fontFamily?: string;
48
+ cursorStyle?: WebHostTerminalCursorStyle;
49
+ cursorBlink?: boolean;
50
+ backgroundOpacity?: number;
51
+ palette?: WebHostTerminalPalette;
52
+ theme?: WebHostTerminalTheme;
53
+ }
54
+ interface ResolvedWebHostTerminalPalette {
55
+ foreground: string;
56
+ background: string;
57
+ cursor: string;
58
+ selectionBackground: string;
59
+ selectionForeground: string;
60
+ ansi: Required<WebHostANSIColors>;
61
+ }
62
+ interface ResolvedWebHostTerminalStyle {
63
+ fontSize: number;
64
+ fontFamily: string;
65
+ cursorStyle: WebHostTerminalCursorStyle;
66
+ cursorBlink: boolean;
67
+ backgroundOpacity: number;
68
+ palette: ResolvedWebHostTerminalPalette;
69
+ theme: Required<WebHostTerminalTheme>;
70
+ }
71
+ interface WebHostTerminalRenderStyle {
72
+ appearance: WebHostTerminalAppearance;
73
+ theme?: WebHostTerminalTheme;
74
+ }
75
+ interface WebHostTerminalAppearance {
76
+ foregroundColor: string;
77
+ backgroundColor: string;
78
+ tintColor: string;
79
+ palette: Record<string, string>;
80
+ colorSchemeContrast: "standard" | "increased";
81
+ source: "activeQuery" | "environmentHeuristics" | "fallback" | "override";
82
+ }
83
+ declare function normalizeWebHostTerminalStyle(style?: WebHostTerminalStyle): ResolvedWebHostTerminalStyle;
84
+ declare function mergeWebHostTerminalStyle(base: WebHostTerminalStyle, patch: WebHostTerminalStyle): ResolvedWebHostTerminalStyle;
85
+ declare function resolveWebHostTerminalRenderStyle(style: WebHostTerminalStyle): WebHostTerminalRenderStyle;
86
+ declare function encodeWebHostTerminalRenderStyleBase64(style: WebHostTerminalStyle): string;
87
+ declare function decodeWebHostTerminalRenderStyleBase64(encoded: string): WebHostTerminalRenderStyle | undefined;
88
+ declare function webTUITerminalBackgroundColor(style: WebHostTerminalStyle): string;
89
+ declare function applyWebHostTerminalStyle(element: HTMLElement, style: WebHostTerminalStyle): void;
90
+ //#endregion
91
+ export { ResolvedWebHostTerminalPalette, ResolvedWebHostTerminalStyle, WebHostANSIColors, WebHostTerminalAppearance, WebHostTerminalCursorStyle, WebHostTerminalPalette, WebHostTerminalRenderStyle, WebHostTerminalStyle, WebHostTerminalTheme, applyWebHostTerminalStyle, decodeWebHostTerminalRenderStyleBase64, encodeWebHostTerminalRenderStyleBase64, mergeWebHostTerminalStyle, normalizeWebHostTerminalStyle, resolveWebHostTerminalRenderStyle, webTUITerminalBackgroundColor };
92
+ //# sourceMappingURL=WebHostTerminalStyle.d.ts.map
@@ -0,0 +1,277 @@
1
+ //#region src/WebHostTerminalStyle.ts
2
+ const defaultFontFamily = "\"SFMono-Regular\", \"SF Mono\", \"Menlo\", \"Monaco\", \"Consolas\", \"Liberation Mono\", monospace";
3
+ const defaultPalette = {
4
+ foreground: "#eceff4",
5
+ background: "#1e222a",
6
+ cursor: "#56b6c2",
7
+ selectionBackground: "#2e3440",
8
+ selectionForeground: "#eceff4",
9
+ ansi: {
10
+ black: "#20242c",
11
+ red: "#e05757",
12
+ green: "#61c67b",
13
+ yellow: "#ebb33c",
14
+ blue: "#5ba3ff",
15
+ magenta: "#b46eff",
16
+ cyan: "#56b6c2",
17
+ white: "#eceff4",
18
+ brightBlack: "#8c92ac",
19
+ brightRed: "#ff7b72",
20
+ brightGreen: "#7ee787",
21
+ brightYellow: "#f2cc60",
22
+ brightBlue: "#79c0ff",
23
+ brightMagenta: "#d2a8ff",
24
+ brightCyan: "#7de2d1",
25
+ brightWhite: "#ffffff"
26
+ }
27
+ };
28
+ const defaultTheme = {
29
+ foreground: "#eceff4",
30
+ background: "#1e222a",
31
+ tint: "#56b6c2",
32
+ separator: "#4c566a",
33
+ selection: "#2e3440",
34
+ placeholder: "#8c92ac",
35
+ link: "#5ba3ff",
36
+ fill: "#2b303b",
37
+ windowBackground: "#15181e",
38
+ success: "#61c67b",
39
+ warning: "#ebb33c",
40
+ danger: "#e05757",
41
+ info: "#56b6c2",
42
+ muted: "#8c92ac"
43
+ };
44
+ function normalizeWebHostTerminalStyle(style = {}) {
45
+ const palette = normalizePalette(style.palette, defaultPalette);
46
+ const theme = normalizeTheme(style.theme, palette, defaultTheme);
47
+ return {
48
+ fontSize: normalizeFontSize(style.fontSize ?? 14),
49
+ fontFamily: style.fontFamily ?? defaultFontFamily,
50
+ cursorStyle: style.cursorStyle ?? "block",
51
+ cursorBlink: style.cursorBlink ?? false,
52
+ backgroundOpacity: normalizeOpacity(style.backgroundOpacity ?? 1),
53
+ palette,
54
+ theme
55
+ };
56
+ }
57
+ function mergeWebHostTerminalStyle(base, patch) {
58
+ const resolvedBase = normalizeWebHostTerminalStyle(base);
59
+ return normalizeWebHostTerminalStyle({
60
+ ...resolvedBase,
61
+ ...patch,
62
+ palette: mergePalette(resolvedBase.palette, patch.palette),
63
+ theme: patch.theme ? {
64
+ ...resolvedBase.theme,
65
+ ...patch.theme
66
+ } : resolvedBase.theme
67
+ });
68
+ }
69
+ function resolveWebHostTerminalRenderStyle(style) {
70
+ const normalized = normalizeWebHostTerminalStyle(style);
71
+ return {
72
+ appearance: {
73
+ foregroundColor: normalized.theme.foreground,
74
+ backgroundColor: normalized.theme.background,
75
+ tintColor: normalized.theme.tint,
76
+ palette: paletteToIndexedMap(normalized.palette.ansi),
77
+ colorSchemeContrast: contrastRatio(normalized.theme.foreground, normalized.theme.background) >= 7 ? "increased" : "standard",
78
+ source: "override"
79
+ },
80
+ theme: { ...normalized.theme }
81
+ };
82
+ }
83
+ function encodeWebHostTerminalRenderStyleBase64(style) {
84
+ return encodeBase64(JSON.stringify(resolveWebHostTerminalRenderStyle(style)));
85
+ }
86
+ function decodeWebHostTerminalRenderStyleBase64(encoded) {
87
+ const json = decodeBase64(encoded);
88
+ if (!json) return;
89
+ try {
90
+ return JSON.parse(json);
91
+ } catch {
92
+ return;
93
+ }
94
+ }
95
+ function webTUITerminalBackgroundColor(style) {
96
+ const normalized = normalizeWebHostTerminalStyle(style);
97
+ return hexToRgba(normalized.theme.background, normalized.backgroundOpacity);
98
+ }
99
+ function applyWebHostTerminalStyle(element, style) {
100
+ const normalized = normalizeWebHostTerminalStyle(style);
101
+ element.style.fontFamily = normalized.fontFamily;
102
+ element.style.fontSize = `${normalized.fontSize}px`;
103
+ element.style.background = hexToRgba(normalized.theme.background, normalized.backgroundOpacity);
104
+ element.style.color = normalized.theme.foreground;
105
+ }
106
+ function normalizePalette(input, defaults) {
107
+ return {
108
+ foreground: normalizeHexColor(input?.foreground ?? defaults.foreground),
109
+ background: normalizeHexColor(input?.background ?? defaults.background),
110
+ cursor: normalizeHexColor(input?.cursor ?? defaults.cursor),
111
+ selectionBackground: normalizeHexColor(input?.selectionBackground ?? defaults.selectionBackground),
112
+ selectionForeground: normalizeHexColor(input?.selectionForeground ?? defaults.selectionForeground),
113
+ ansi: normalizeANSI(input?.ansi, defaults.ansi)
114
+ };
115
+ }
116
+ function mergePalette(base, patch) {
117
+ if (!patch) return base;
118
+ return {
119
+ ...base,
120
+ ...patch,
121
+ ansi: patch.ansi ? {
122
+ ...base.ansi,
123
+ ...patch.ansi
124
+ } : base.ansi
125
+ };
126
+ }
127
+ function normalizeANSI(input, defaults) {
128
+ return {
129
+ black: normalizeHexColor(input?.black ?? defaults.black),
130
+ red: normalizeHexColor(input?.red ?? defaults.red),
131
+ green: normalizeHexColor(input?.green ?? defaults.green),
132
+ yellow: normalizeHexColor(input?.yellow ?? defaults.yellow),
133
+ blue: normalizeHexColor(input?.blue ?? defaults.blue),
134
+ magenta: normalizeHexColor(input?.magenta ?? defaults.magenta),
135
+ cyan: normalizeHexColor(input?.cyan ?? defaults.cyan),
136
+ white: normalizeHexColor(input?.white ?? defaults.white),
137
+ brightBlack: normalizeHexColor(input?.brightBlack ?? defaults.brightBlack),
138
+ brightRed: normalizeHexColor(input?.brightRed ?? defaults.brightRed),
139
+ brightGreen: normalizeHexColor(input?.brightGreen ?? defaults.brightGreen),
140
+ brightYellow: normalizeHexColor(input?.brightYellow ?? defaults.brightYellow),
141
+ brightBlue: normalizeHexColor(input?.brightBlue ?? defaults.brightBlue),
142
+ brightMagenta: normalizeHexColor(input?.brightMagenta ?? defaults.brightMagenta),
143
+ brightCyan: normalizeHexColor(input?.brightCyan ?? defaults.brightCyan),
144
+ brightWhite: normalizeHexColor(input?.brightWhite ?? defaults.brightWhite)
145
+ };
146
+ }
147
+ function normalizeTheme(input, palette, defaults) {
148
+ const derived = themeFromPalette(palette, defaults);
149
+ return {
150
+ foreground: normalizeHexColor(input?.foreground ?? derived.foreground),
151
+ background: normalizeHexColor(input?.background ?? derived.background),
152
+ tint: normalizeHexColor(input?.tint ?? derived.tint),
153
+ separator: normalizeHexColor(input?.separator ?? derived.separator),
154
+ selection: normalizeHexColor(input?.selection ?? derived.selection),
155
+ placeholder: normalizeHexColor(input?.placeholder ?? derived.placeholder),
156
+ link: normalizeHexColor(input?.link ?? derived.link),
157
+ fill: normalizeHexColor(input?.fill ?? derived.fill),
158
+ windowBackground: normalizeHexColor(input?.windowBackground ?? derived.windowBackground),
159
+ success: normalizeHexColor(input?.success ?? derived.success),
160
+ warning: normalizeHexColor(input?.warning ?? derived.warning),
161
+ danger: normalizeHexColor(input?.danger ?? derived.danger),
162
+ info: normalizeHexColor(input?.info ?? derived.info),
163
+ muted: normalizeHexColor(input?.muted ?? derived.muted)
164
+ };
165
+ }
166
+ function themeFromPalette(palette, defaults) {
167
+ return {
168
+ foreground: palette.foreground,
169
+ background: palette.background,
170
+ tint: palette.cursor,
171
+ separator: palette.ansi.brightBlack,
172
+ selection: palette.selectionBackground,
173
+ placeholder: palette.ansi.brightBlack,
174
+ link: palette.ansi.blue,
175
+ fill: defaults.fill,
176
+ windowBackground: palette.background,
177
+ success: palette.ansi.green,
178
+ warning: palette.ansi.yellow,
179
+ danger: palette.ansi.red,
180
+ info: palette.ansi.cyan,
181
+ muted: palette.ansi.brightBlack
182
+ };
183
+ }
184
+ function paletteToIndexedMap(ansi) {
185
+ return {
186
+ 0: ansi.black,
187
+ 1: ansi.red,
188
+ 2: ansi.green,
189
+ 3: ansi.yellow,
190
+ 4: ansi.blue,
191
+ 5: ansi.magenta,
192
+ 6: ansi.cyan,
193
+ 7: ansi.white,
194
+ 8: ansi.brightBlack,
195
+ 9: ansi.brightRed,
196
+ 10: ansi.brightGreen,
197
+ 11: ansi.brightYellow,
198
+ 12: ansi.brightBlue,
199
+ 13: ansi.brightMagenta,
200
+ 14: ansi.brightCyan,
201
+ 15: ansi.brightWhite
202
+ };
203
+ }
204
+ function normalizeFontSize(fontSize) {
205
+ return Number.isFinite(fontSize) && fontSize > 0 ? fontSize : 14;
206
+ }
207
+ function normalizeOpacity(opacity) {
208
+ if (!Number.isFinite(opacity)) return 1;
209
+ return Math.min(1, Math.max(0, opacity));
210
+ }
211
+ function normalizeHexColor(value) {
212
+ const trimmed = value.trim();
213
+ const normalized = trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
214
+ if (!/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(normalized)) throw new Error(`Invalid hex color: ${value}`);
215
+ return normalized.toLowerCase();
216
+ }
217
+ function hexToRgba(color, opacity) {
218
+ const normalized = normalizeHexColor(color);
219
+ const alpha = normalizeOpacity(opacity);
220
+ const channels = parseHexColor(normalized);
221
+ if (!channels) return normalized;
222
+ const finalAlpha = Math.round(channels.alpha * alpha * 1e3) / 1e3;
223
+ return `rgba(${channels.red}, ${channels.green}, ${channels.blue}, ${finalAlpha})`;
224
+ }
225
+ function parseHexColor(color) {
226
+ const hex = color.startsWith("#") ? color.slice(1) : color;
227
+ const normalized = hex.length === 3 || hex.length === 4 ? hex.split("").map((ch) => ch + ch).join("") : hex;
228
+ if (normalized.length !== 6 && normalized.length !== 8) return;
229
+ return {
230
+ red: Number.parseInt(normalized.slice(0, 2), 16),
231
+ green: Number.parseInt(normalized.slice(2, 4), 16),
232
+ blue: Number.parseInt(normalized.slice(4, 6), 16),
233
+ alpha: normalized.length === 8 ? Number.parseInt(normalized.slice(6, 8), 16) / 255 : 1
234
+ };
235
+ }
236
+ function contrastRatio(foreground, background) {
237
+ const fg = relativeLuminance(foreground);
238
+ const bg = relativeLuminance(background);
239
+ const lighter = Math.max(fg, bg);
240
+ const darker = Math.min(fg, bg);
241
+ return (lighter + .05) / (darker + .05);
242
+ }
243
+ function relativeLuminance(color) {
244
+ const channels = parseHexColor(normalizeHexColor(color));
245
+ if (!channels) return 0;
246
+ const toLinear = (channel) => {
247
+ const value = channel / 255;
248
+ return value <= .03928 ? value / 12.92 : ((value + .055) / 1.055) ** 2.4;
249
+ };
250
+ return .2126 * toLinear(channels.red) + .7152 * toLinear(channels.green) + .0722 * toLinear(channels.blue);
251
+ }
252
+ function encodeBase64(value) {
253
+ if (typeof btoa === "function") {
254
+ const bytes = new TextEncoder().encode(value);
255
+ let binary = "";
256
+ for (const byte of bytes) binary += String.fromCharCode(byte);
257
+ return btoa(binary);
258
+ }
259
+ return Buffer.from(value, "utf8").toString("base64");
260
+ }
261
+ function decodeBase64(value) {
262
+ try {
263
+ if (typeof atob === "function") {
264
+ const binary = atob(value);
265
+ const bytes = new Uint8Array(binary.length);
266
+ for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
267
+ return new TextDecoder().decode(bytes);
268
+ }
269
+ return Buffer.from(value, "base64").toString("utf8");
270
+ } catch {
271
+ return;
272
+ }
273
+ }
274
+ //#endregion
275
+ export { applyWebHostTerminalStyle, decodeWebHostTerminalRenderStyleBase64, encodeWebHostTerminalRenderStyleBase64, mergeWebHostTerminalStyle, normalizeWebHostTerminalStyle, resolveWebHostTerminalRenderStyle, webTUITerminalBackgroundColor };
276
+
277
+ //# sourceMappingURL=WebHostTerminalStyle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebHostTerminalStyle.js","names":[],"sources":["../../src/WebHostTerminalStyle.ts"],"sourcesContent":["export type WebHostTerminalCursorStyle = \"block\" | \"bar\" | \"underline\";\n\nexport interface WebHostANSIColors {\n black?: string;\n red?: string;\n green?: string;\n yellow?: string;\n blue?: string;\n magenta?: string;\n cyan?: string;\n white?: string;\n brightBlack?: string;\n brightRed?: string;\n brightGreen?: string;\n brightYellow?: string;\n brightBlue?: string;\n brightMagenta?: string;\n brightCyan?: string;\n brightWhite?: string;\n}\n\nexport interface WebHostTerminalPalette {\n foreground?: string;\n background?: string;\n cursor?: string;\n selectionBackground?: string;\n selectionForeground?: string;\n ansi?: WebHostANSIColors;\n}\n\nexport interface WebHostTerminalTheme {\n foreground?: string;\n background?: string;\n tint?: string;\n separator?: string;\n selection?: string;\n placeholder?: string;\n link?: string;\n fill?: string;\n windowBackground?: string;\n success?: string;\n warning?: string;\n danger?: string;\n info?: string;\n muted?: string;\n}\n\nexport interface WebHostTerminalStyle {\n fontSize?: number;\n fontFamily?: string;\n cursorStyle?: WebHostTerminalCursorStyle;\n cursorBlink?: boolean;\n backgroundOpacity?: number;\n palette?: WebHostTerminalPalette;\n theme?: WebHostTerminalTheme;\n}\n\nexport interface ResolvedWebHostTerminalPalette {\n foreground: string;\n background: string;\n cursor: string;\n selectionBackground: string;\n selectionForeground: string;\n ansi: Required<WebHostANSIColors>;\n}\n\nexport interface ResolvedWebHostTerminalStyle {\n fontSize: number;\n fontFamily: string;\n cursorStyle: WebHostTerminalCursorStyle;\n cursorBlink: boolean;\n backgroundOpacity: number;\n palette: ResolvedWebHostTerminalPalette;\n theme: Required<WebHostTerminalTheme>;\n}\n\nexport interface WebHostTerminalRenderStyle {\n appearance: WebHostTerminalAppearance;\n theme?: WebHostTerminalTheme;\n}\n\nexport interface WebHostTerminalAppearance {\n foregroundColor: string;\n backgroundColor: string;\n tintColor: string;\n palette: Record<string, string>;\n colorSchemeContrast: \"standard\" | \"increased\";\n source: \"activeQuery\" | \"environmentHeuristics\" | \"fallback\" | \"override\";\n}\n\nconst defaultFontFamily =\n '\"SFMono-Regular\", \"SF Mono\", \"Menlo\", \"Monaco\", \"Consolas\", \"Liberation Mono\", monospace';\n\nconst defaultANSI: Required<WebHostANSIColors> = {\n black: \"#20242c\",\n red: \"#e05757\",\n green: \"#61c67b\",\n yellow: \"#ebb33c\",\n blue: \"#5ba3ff\",\n magenta: \"#b46eff\",\n cyan: \"#56b6c2\",\n white: \"#eceff4\",\n brightBlack: \"#8c92ac\",\n brightRed: \"#ff7b72\",\n brightGreen: \"#7ee787\",\n brightYellow: \"#f2cc60\",\n brightBlue: \"#79c0ff\",\n brightMagenta: \"#d2a8ff\",\n brightCyan: \"#7de2d1\",\n brightWhite: \"#ffffff\",\n};\n\nconst defaultPalette: ResolvedWebHostTerminalPalette = {\n foreground: \"#eceff4\",\n background: \"#1e222a\",\n cursor: \"#56b6c2\",\n selectionBackground: \"#2e3440\",\n selectionForeground: \"#eceff4\",\n ansi: defaultANSI,\n};\n\nconst defaultTheme: Required<WebHostTerminalTheme> = {\n foreground: \"#eceff4\",\n background: \"#1e222a\",\n tint: \"#56b6c2\",\n separator: \"#4c566a\",\n selection: \"#2e3440\",\n placeholder: \"#8c92ac\",\n link: \"#5ba3ff\",\n fill: \"#2b303b\",\n windowBackground: \"#15181e\",\n success: \"#61c67b\",\n warning: \"#ebb33c\",\n danger: \"#e05757\",\n info: \"#56b6c2\",\n muted: \"#8c92ac\",\n};\n\nexport function normalizeWebHostTerminalStyle(\n style: WebHostTerminalStyle = {}\n): ResolvedWebHostTerminalStyle {\n const palette = normalizePalette(style.palette, defaultPalette);\n const theme = normalizeTheme(style.theme, palette, defaultTheme);\n return {\n fontSize: normalizeFontSize(style.fontSize ?? 14),\n fontFamily: style.fontFamily ?? defaultFontFamily,\n cursorStyle: style.cursorStyle ?? \"block\",\n cursorBlink: style.cursorBlink ?? false,\n backgroundOpacity: normalizeOpacity(style.backgroundOpacity ?? 1),\n palette,\n theme,\n };\n}\n\nexport function mergeWebHostTerminalStyle(\n base: WebHostTerminalStyle,\n patch: WebHostTerminalStyle\n): ResolvedWebHostTerminalStyle {\n const resolvedBase = normalizeWebHostTerminalStyle(base);\n return normalizeWebHostTerminalStyle({\n ...resolvedBase,\n ...patch,\n palette: mergePalette(resolvedBase.palette, patch.palette),\n theme: patch.theme ? { ...resolvedBase.theme, ...patch.theme } : resolvedBase.theme,\n });\n}\n\nexport function resolveWebHostTerminalRenderStyle(\n style: WebHostTerminalStyle\n): WebHostTerminalRenderStyle {\n const normalized = normalizeWebHostTerminalStyle(style);\n return {\n appearance: {\n foregroundColor: normalized.theme.foreground,\n backgroundColor: normalized.theme.background,\n tintColor: normalized.theme.tint,\n palette: paletteToIndexedMap(normalized.palette.ansi),\n colorSchemeContrast: contrastRatio(normalized.theme.foreground, normalized.theme.background) >= 7\n ? \"increased\"\n : \"standard\",\n source: \"override\",\n },\n theme: { ...normalized.theme },\n };\n}\n\nexport function encodeWebHostTerminalRenderStyleBase64(\n style: WebHostTerminalStyle\n): string {\n return encodeBase64(JSON.stringify(resolveWebHostTerminalRenderStyle(style)));\n}\n\nexport function decodeWebHostTerminalRenderStyleBase64(\n encoded: string\n): WebHostTerminalRenderStyle | undefined {\n const json = decodeBase64(encoded);\n if (!json) {\n return undefined;\n }\n\n try {\n return JSON.parse(json) as WebHostTerminalRenderStyle;\n } catch {\n return undefined;\n }\n}\n\nexport function webTUITerminalBackgroundColor(\n style: WebHostTerminalStyle\n): string {\n const normalized = normalizeWebHostTerminalStyle(style);\n return hexToRgba(normalized.theme.background, normalized.backgroundOpacity);\n}\n\nexport function applyWebHostTerminalStyle(\n element: HTMLElement,\n style: WebHostTerminalStyle\n): void {\n const normalized = normalizeWebHostTerminalStyle(style);\n element.style.fontFamily = normalized.fontFamily;\n element.style.fontSize = `${normalized.fontSize}px`;\n element.style.background = hexToRgba(normalized.theme.background, normalized.backgroundOpacity);\n element.style.color = normalized.theme.foreground;\n}\n\nfunction normalizePalette(\n input: WebHostTerminalPalette | undefined,\n defaults: ResolvedWebHostTerminalPalette\n): ResolvedWebHostTerminalPalette {\n return {\n foreground: normalizeHexColor(input?.foreground ?? defaults.foreground),\n background: normalizeHexColor(input?.background ?? defaults.background),\n cursor: normalizeHexColor(input?.cursor ?? defaults.cursor),\n selectionBackground: normalizeHexColor(\n input?.selectionBackground ?? defaults.selectionBackground\n ),\n selectionForeground: normalizeHexColor(\n input?.selectionForeground ?? defaults.selectionForeground\n ),\n ansi: normalizeANSI(input?.ansi, defaults.ansi),\n };\n}\n\nfunction mergePalette(\n base: ResolvedWebHostTerminalPalette,\n patch: WebHostTerminalPalette | undefined\n): WebHostTerminalPalette {\n if (!patch) {\n return base;\n }\n\n return {\n ...base,\n ...patch,\n ansi: patch.ansi ? { ...base.ansi, ...patch.ansi } : base.ansi,\n };\n}\n\nfunction normalizeANSI(\n input: WebHostANSIColors | undefined,\n defaults: Required<WebHostANSIColors>\n): Required<WebHostANSIColors> {\n return {\n black: normalizeHexColor(input?.black ?? defaults.black),\n red: normalizeHexColor(input?.red ?? defaults.red),\n green: normalizeHexColor(input?.green ?? defaults.green),\n yellow: normalizeHexColor(input?.yellow ?? defaults.yellow),\n blue: normalizeHexColor(input?.blue ?? defaults.blue),\n magenta: normalizeHexColor(input?.magenta ?? defaults.magenta),\n cyan: normalizeHexColor(input?.cyan ?? defaults.cyan),\n white: normalizeHexColor(input?.white ?? defaults.white),\n brightBlack: normalizeHexColor(input?.brightBlack ?? defaults.brightBlack),\n brightRed: normalizeHexColor(input?.brightRed ?? defaults.brightRed),\n brightGreen: normalizeHexColor(input?.brightGreen ?? defaults.brightGreen),\n brightYellow: normalizeHexColor(input?.brightYellow ?? defaults.brightYellow),\n brightBlue: normalizeHexColor(input?.brightBlue ?? defaults.brightBlue),\n brightMagenta: normalizeHexColor(input?.brightMagenta ?? defaults.brightMagenta),\n brightCyan: normalizeHexColor(input?.brightCyan ?? defaults.brightCyan),\n brightWhite: normalizeHexColor(input?.brightWhite ?? defaults.brightWhite),\n };\n}\n\nfunction normalizeTheme(\n input: WebHostTerminalTheme | undefined,\n palette: ResolvedWebHostTerminalPalette,\n defaults: Required<WebHostTerminalTheme>\n): Required<WebHostTerminalTheme> {\n const derived = themeFromPalette(palette, defaults);\n return {\n foreground: normalizeHexColor(input?.foreground ?? derived.foreground),\n background: normalizeHexColor(input?.background ?? derived.background),\n tint: normalizeHexColor(input?.tint ?? derived.tint),\n separator: normalizeHexColor(input?.separator ?? derived.separator),\n selection: normalizeHexColor(input?.selection ?? derived.selection),\n placeholder: normalizeHexColor(input?.placeholder ?? derived.placeholder),\n link: normalizeHexColor(input?.link ?? derived.link),\n fill: normalizeHexColor(input?.fill ?? derived.fill),\n windowBackground: normalizeHexColor(input?.windowBackground ?? derived.windowBackground),\n success: normalizeHexColor(input?.success ?? derived.success),\n warning: normalizeHexColor(input?.warning ?? derived.warning),\n danger: normalizeHexColor(input?.danger ?? derived.danger),\n info: normalizeHexColor(input?.info ?? derived.info),\n muted: normalizeHexColor(input?.muted ?? derived.muted),\n };\n}\n\nfunction themeFromPalette(\n palette: ResolvedWebHostTerminalPalette,\n defaults: Required<WebHostTerminalTheme>\n): Required<WebHostTerminalTheme> {\n return {\n foreground: palette.foreground,\n background: palette.background,\n tint: palette.cursor,\n separator: palette.ansi.brightBlack,\n selection: palette.selectionBackground,\n placeholder: palette.ansi.brightBlack,\n link: palette.ansi.blue,\n fill: defaults.fill,\n windowBackground: palette.background,\n success: palette.ansi.green,\n warning: palette.ansi.yellow,\n danger: palette.ansi.red,\n info: palette.ansi.cyan,\n muted: palette.ansi.brightBlack,\n };\n}\n\nfunction paletteToIndexedMap(\n ansi: Required<WebHostANSIColors>\n): Record<string, string> {\n return {\n 0: ansi.black,\n 1: ansi.red,\n 2: ansi.green,\n 3: ansi.yellow,\n 4: ansi.blue,\n 5: ansi.magenta,\n 6: ansi.cyan,\n 7: ansi.white,\n 8: ansi.brightBlack,\n 9: ansi.brightRed,\n 10: ansi.brightGreen,\n 11: ansi.brightYellow,\n 12: ansi.brightBlue,\n 13: ansi.brightMagenta,\n 14: ansi.brightCyan,\n 15: ansi.brightWhite,\n };\n}\n\nfunction normalizeFontSize(fontSize: number): number {\n return Number.isFinite(fontSize) && fontSize > 0 ? fontSize : 14;\n}\n\nfunction normalizeOpacity(opacity: number): number {\n if (!Number.isFinite(opacity)) {\n return 1;\n }\n\n return Math.min(1, Math.max(0, opacity));\n}\n\nfunction normalizeHexColor(value: string): string {\n const trimmed = value.trim();\n const normalized = trimmed.startsWith(\"#\") ? trimmed : `#${trimmed}`;\n if (!/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(normalized)) {\n throw new Error(`Invalid hex color: ${value}`);\n }\n\n return normalized.toLowerCase();\n}\n\nfunction hexToRgba(\n color: string,\n opacity: number\n): string {\n const normalized = normalizeHexColor(color);\n const alpha = normalizeOpacity(opacity);\n const channels = parseHexColor(normalized);\n if (!channels) {\n return normalized;\n }\n\n const finalAlpha = Math.round(channels.alpha * alpha * 1000) / 1000;\n return `rgba(${channels.red}, ${channels.green}, ${channels.blue}, ${finalAlpha})`;\n}\n\nfunction parseHexColor(\n color: string\n): {\n red: number;\n green: number;\n blue: number;\n alpha: number;\n} | undefined {\n const hex = color.startsWith(\"#\") ? color.slice(1) : color;\n const normalized = hex.length === 3 || hex.length === 4\n ? hex.split(\"\").map((ch) => ch + ch).join(\"\")\n : hex;\n\n if (normalized.length !== 6 && normalized.length !== 8) {\n return undefined;\n }\n\n const red = Number.parseInt(normalized.slice(0, 2), 16);\n const green = Number.parseInt(normalized.slice(2, 4), 16);\n const blue = Number.parseInt(normalized.slice(4, 6), 16);\n const alpha = normalized.length === 8\n ? Number.parseInt(normalized.slice(6, 8), 16) / 255\n : 1;\n return { red, green, blue, alpha };\n}\n\nfunction contrastRatio(\n foreground: string,\n background: string\n): number {\n const fg = relativeLuminance(foreground);\n const bg = relativeLuminance(background);\n const lighter = Math.max(fg, bg);\n const darker = Math.min(fg, bg);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\nfunction relativeLuminance(color: string): number {\n const channels = parseHexColor(normalizeHexColor(color));\n if (!channels) {\n return 0;\n }\n\n const toLinear = (channel: number) => {\n const value = channel / 255;\n return value <= 0.03928\n ? value / 12.92\n : ((value + 0.055) / 1.055) ** 2.4;\n };\n\n return 0.2126 * toLinear(channels.red) + 0.7152 * toLinear(channels.green)\n + 0.0722 * toLinear(channels.blue);\n}\n\nfunction encodeBase64(value: string): string {\n if (typeof btoa === \"function\") {\n const bytes = new TextEncoder().encode(value);\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n }\n\n return Buffer.from(value, \"utf8\").toString(\"base64\");\n}\n\nfunction decodeBase64(value: string): string | undefined {\n try {\n if (typeof atob === \"function\") {\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return new TextDecoder().decode(bytes);\n }\n\n return Buffer.from(value, \"base64\").toString(\"utf8\");\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ //#region src/WebHostTestFixtures.d.ts
2
+ declare function transportFixture(basename: string): string;
3
+ //#endregion
4
+ export { transportFixture };
5
+ //# sourceMappingURL=WebHostTestFixtures.d.ts.map
@@ -0,0 +1,9 @@
1
+ import { readFileSync } from "node:fs";
2
+ //#region src/WebHostTestFixtures.ts
3
+ function transportFixture(basename) {
4
+ return readFileSync(new URL(`../../../Fixtures/Transport/${basename}.txt`, import.meta.url), "utf8").replaceAll("\\u001E", "");
5
+ }
6
+ //#endregion
7
+ export { transportFixture };
8
+
9
+ //# sourceMappingURL=WebHostTestFixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebHostTestFixtures.js","names":[],"sources":["../../src/WebHostTestFixtures.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\n\nexport function transportFixture(\n basename: string\n): string {\n return readFileSync(\n new URL(`../../../Fixtures/Transport/${basename}.txt`, import.meta.url),\n \"utf8\"\n ).replaceAll(\"\\\\u001E\", \"\\u001E\");\n}\n"],"mappings":";;AAEA,SAAgB,iBACd,UACQ;CACR,OAAO,aACL,IAAI,IAAI,+BAA+B,SAAS,OAAO,OAAO,KAAK,GAAG,GACtE,MACF,CAAC,CAAC,WAAW,WAAW,GAAQ;AAClC"}
@@ -0,0 +1,53 @@
1
+ import { WebHostTerminalStyle } from "./WebHostTerminalStyle.js";
2
+ import { WebHostOutputSink } from "./WebHostSurfaceTransport.js";
3
+ import { WebHostSceneBridge } from "./WebHostSceneRuntime.js";
4
+
5
+ //#region src/WebSocketSceneBridge.d.ts
6
+ interface WebSocketSceneBridgeOptions {
7
+ sceneId: string;
8
+ token: string;
9
+ baseURL?: string | URL;
10
+ webSocketURL?: string | URL;
11
+ webSocketFactory?: WebSocketSceneBridgeFactory;
12
+ }
13
+ type WebSocketSceneBridgeFactory = (url: string | URL) => WebSocketSceneSocket;
14
+ interface WebSocketSceneSocket {
15
+ binaryType: BinaryType;
16
+ readonly readyState: number;
17
+ send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
18
+ close(code?: number, reason?: string): void;
19
+ addEventListener(type: "open", listener: (event: Event) => void): void;
20
+ addEventListener(type: "message", listener: (event: MessageEvent) => void): void;
21
+ addEventListener(type: "close", listener: (event: CloseEvent) => void): void;
22
+ addEventListener(type: "error", listener: (event: Event) => void): void;
23
+ removeEventListener(type: "open", listener: (event: Event) => void): void;
24
+ removeEventListener(type: "message", listener: (event: MessageEvent) => void): void;
25
+ removeEventListener(type: "close", listener: (event: CloseEvent) => void): void;
26
+ removeEventListener(type: "error", listener: (event: Event) => void): void;
27
+ }
28
+ declare class WebSocketSceneBridge implements WebHostSceneBridge {
29
+ readonly url: URL;
30
+ private readonly socket;
31
+ private readonly decoder;
32
+ private readonly queuedInput;
33
+ private readonly queuedOutput;
34
+ private sink?;
35
+ private disposed;
36
+ private readonly handleOpen;
37
+ private readonly handleMessage;
38
+ private readonly handleClose;
39
+ private readonly handleError;
40
+ constructor(options: WebSocketSceneBridgeOptions);
41
+ bindOutput(sink: WebHostOutputSink): void;
42
+ resize(columns: number, rows: number, cellWidth?: number, cellHeight?: number): void;
43
+ updateRenderStyle(style: WebHostTerminalStyle): void;
44
+ sendInput(chunk: Uint8Array): void;
45
+ dispose(): void;
46
+ private receive;
47
+ private deliver;
48
+ private flushQueuedInput;
49
+ }
50
+ declare function webSocketSceneURL(options: Pick<WebSocketSceneBridgeOptions, "baseURL" | "webSocketURL" | "sceneId" | "token">): URL;
51
+ //#endregion
52
+ export { WebSocketSceneBridge, WebSocketSceneBridgeFactory, WebSocketSceneBridgeOptions, WebSocketSceneSocket, webSocketSceneURL };
53
+ //# sourceMappingURL=WebSocketSceneBridge.d.ts.map
@@ -0,0 +1,124 @@
1
+ import { WebHostOutputDecoder, encodeRenderStyleControlMessage, encodeResizeControlMessage } from "./WebHostSurfaceTransport.js";
2
+ //#region src/WebSocketSceneBridge.ts
3
+ const socketOpenState = 1;
4
+ const textEncoder = new TextEncoder();
5
+ var WebSocketSceneBridge = class {
6
+ url;
7
+ socket;
8
+ decoder = new WebHostOutputDecoder();
9
+ queuedInput = [];
10
+ queuedOutput = [];
11
+ sink;
12
+ disposed = false;
13
+ handleOpen = () => {
14
+ this.flushQueuedInput();
15
+ };
16
+ handleMessage = (event) => {
17
+ this.receive(event.data);
18
+ };
19
+ handleClose = () => {
20
+ for (const record of this.decoder.flush()) this.deliver(record);
21
+ };
22
+ handleError = () => {};
23
+ constructor(options) {
24
+ this.url = webSocketSceneURL(options);
25
+ this.socket = (options.webSocketFactory ?? defaultWebSocketFactory)(this.url);
26
+ this.socket.binaryType = "arraybuffer";
27
+ this.socket.addEventListener("open", this.handleOpen);
28
+ this.socket.addEventListener("message", this.handleMessage);
29
+ this.socket.addEventListener("close", this.handleClose);
30
+ this.socket.addEventListener("error", this.handleError);
31
+ }
32
+ bindOutput(sink) {
33
+ this.sink = sink;
34
+ while (this.queuedOutput.length > 0) this.deliver(this.queuedOutput.shift());
35
+ }
36
+ resize(columns, rows, cellWidth, cellHeight) {
37
+ this.sendInput(encodeResizeControlMessage(columns, rows, cellWidth, cellHeight));
38
+ }
39
+ updateRenderStyle(style) {
40
+ this.sendInput(encodeRenderStyleControlMessage(style));
41
+ }
42
+ sendInput(chunk) {
43
+ if (this.disposed) return;
44
+ const copy = new Uint8Array(chunk);
45
+ if (this.socket.readyState === socketOpenState) this.socket.send(copy);
46
+ else this.queuedInput.push(copy);
47
+ }
48
+ dispose() {
49
+ if (this.disposed) return;
50
+ this.disposed = true;
51
+ this.socket.removeEventListener("open", this.handleOpen);
52
+ this.socket.removeEventListener("message", this.handleMessage);
53
+ this.socket.removeEventListener("close", this.handleClose);
54
+ this.socket.removeEventListener("error", this.handleError);
55
+ this.queuedInput.length = 0;
56
+ this.queuedOutput.length = 0;
57
+ this.socket.close(1e3, "WebHost scene disposed");
58
+ }
59
+ async receive(message) {
60
+ if (this.disposed) return;
61
+ const bytes = await bytesFromWebSocketMessage(message);
62
+ if (!bytes) return;
63
+ for (const record of this.decoder.feed(bytes)) this.deliver(record);
64
+ }
65
+ deliver(record) {
66
+ const sink = this.sink;
67
+ if (!sink) {
68
+ this.queuedOutput.push(record);
69
+ return;
70
+ }
71
+ switch (record.type) {
72
+ case "surface":
73
+ sink.presentSurface(record.frame);
74
+ break;
75
+ case "clipboard":
76
+ sink.writeClipboard?.(record.text);
77
+ break;
78
+ case "runtimeIssue":
79
+ sink.notifyRuntimeIssue?.(record.issue);
80
+ break;
81
+ case "frameDiagnostic":
82
+ sink.recordFrameDiagnostic?.(record.diagnostic);
83
+ break;
84
+ case "text":
85
+ sink.writeOutput?.(record.text);
86
+ break;
87
+ }
88
+ }
89
+ flushQueuedInput() {
90
+ if (this.disposed || this.socket.readyState !== socketOpenState) return;
91
+ while (this.queuedInput.length > 0) this.socket.send(this.queuedInput.shift());
92
+ }
93
+ };
94
+ function webSocketSceneURL(options) {
95
+ if (options.webSocketURL) {
96
+ const explicit = new URL(String(options.webSocketURL), currentPageURL());
97
+ explicit.searchParams.set("token", options.token);
98
+ return explicit;
99
+ }
100
+ const url = new URL(String(options.baseURL ?? currentPageURL()), currentPageURL());
101
+ url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
102
+ url.pathname = `${url.pathname.endsWith("/") ? url.pathname.slice(0, -1) : url.pathname}/ws/scene/${encodeURIComponent(options.sceneId)}`;
103
+ url.search = "";
104
+ url.searchParams.set("token", options.token);
105
+ return url;
106
+ }
107
+ async function bytesFromWebSocketMessage(message) {
108
+ if (typeof message === "string") return textEncoder.encode(message);
109
+ if (message instanceof Uint8Array) return message;
110
+ if (message instanceof ArrayBuffer) return new Uint8Array(message);
111
+ if (ArrayBuffer.isView(message)) return new Uint8Array(message.buffer, message.byteOffset, message.byteLength);
112
+ if (typeof Blob !== "undefined" && message instanceof Blob) return new Uint8Array(await message.arrayBuffer());
113
+ }
114
+ function defaultWebSocketFactory(url) {
115
+ if (typeof WebSocket === "undefined") throw new Error("WebSocket is not available");
116
+ return new WebSocket(url);
117
+ }
118
+ function currentPageURL() {
119
+ return globalThis.location?.href ?? "http://127.0.0.1/";
120
+ }
121
+ //#endregion
122
+ export { WebSocketSceneBridge, webSocketSceneURL };
123
+
124
+ //# sourceMappingURL=WebSocketSceneBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketSceneBridge.js","names":[],"sources":["../../src/WebSocketSceneBridge.ts"],"sourcesContent":["import {\n WebHostOutputDecoder,\n encodeRenderStyleControlMessage,\n encodeResizeControlMessage,\n type WebHostOutputRecord,\n type WebHostOutputSink,\n} from \"./WebHostSurfaceTransport.ts\";\nimport type { WebHostTerminalStyle } from \"./WebHostTerminalStyle.ts\";\nimport type { WebHostSceneBridge } from \"./WebHostSceneRuntime.ts\";\n\nexport interface WebSocketSceneBridgeOptions {\n sceneId: string;\n token: string;\n baseURL?: string | URL;\n webSocketURL?: string | URL;\n webSocketFactory?: WebSocketSceneBridgeFactory;\n}\n\nexport type WebSocketSceneBridgeFactory = (url: string | URL) => WebSocketSceneSocket;\n\nexport interface WebSocketSceneSocket {\n binaryType: BinaryType;\n readonly readyState: number;\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;\n close(code?: number, reason?: string): void;\n addEventListener(type: \"open\", listener: (event: Event) => void): void;\n addEventListener(type: \"message\", listener: (event: MessageEvent) => void): void;\n addEventListener(type: \"close\", listener: (event: CloseEvent) => void): void;\n addEventListener(type: \"error\", listener: (event: Event) => void): void;\n removeEventListener(type: \"open\", listener: (event: Event) => void): void;\n removeEventListener(type: \"message\", listener: (event: MessageEvent) => void): void;\n removeEventListener(type: \"close\", listener: (event: CloseEvent) => void): void;\n removeEventListener(type: \"error\", listener: (event: Event) => void): void;\n}\n\nconst socketOpenState = 1;\nconst textEncoder = new TextEncoder();\n\nexport class WebSocketSceneBridge implements WebHostSceneBridge {\n readonly url: URL;\n\n private readonly socket: WebSocketSceneSocket;\n private readonly decoder = new WebHostOutputDecoder();\n private readonly queuedInput: Uint8Array[] = [];\n private readonly queuedOutput: WebHostOutputRecord[] = [];\n private sink?: WebHostOutputSink;\n private disposed = false;\n\n private readonly handleOpen = () => {\n this.flushQueuedInput();\n };\n\n private readonly handleMessage = (event: MessageEvent) => {\n void this.receive(event.data);\n };\n\n private readonly handleClose = () => {\n for (const record of this.decoder.flush()) {\n this.deliver(record);\n }\n };\n\n private readonly handleError = () => {};\n\n constructor(options: WebSocketSceneBridgeOptions) {\n this.url = webSocketSceneURL(options);\n this.socket = (options.webSocketFactory ?? defaultWebSocketFactory)(this.url);\n this.socket.binaryType = \"arraybuffer\";\n this.socket.addEventListener(\"open\", this.handleOpen);\n this.socket.addEventListener(\"message\", this.handleMessage);\n this.socket.addEventListener(\"close\", this.handleClose);\n this.socket.addEventListener(\"error\", this.handleError);\n }\n\n bindOutput(\n sink: WebHostOutputSink\n ): void {\n this.sink = sink;\n while (this.queuedOutput.length > 0) {\n this.deliver(this.queuedOutput.shift()!);\n }\n }\n\n resize(\n columns: number,\n rows: number,\n cellWidth?: number,\n cellHeight?: number\n ): void {\n this.sendInput(encodeResizeControlMessage(columns, rows, cellWidth, cellHeight));\n }\n\n updateRenderStyle(\n style: WebHostTerminalStyle\n ): void {\n this.sendInput(encodeRenderStyleControlMessage(style));\n }\n\n sendInput(\n chunk: Uint8Array\n ): void {\n if (this.disposed) {\n return;\n }\n\n const copy = new Uint8Array(chunk);\n if (this.socket.readyState === socketOpenState) {\n this.socket.send(copy);\n } else {\n this.queuedInput.push(copy);\n }\n }\n\n dispose(): void {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.socket.removeEventListener(\"open\", this.handleOpen);\n this.socket.removeEventListener(\"message\", this.handleMessage);\n this.socket.removeEventListener(\"close\", this.handleClose);\n this.socket.removeEventListener(\"error\", this.handleError);\n this.queuedInput.length = 0;\n this.queuedOutput.length = 0;\n this.socket.close(1000, \"WebHost scene disposed\");\n }\n\n private async receive(\n message: unknown\n ): Promise<void> {\n if (this.disposed) {\n return;\n }\n\n const bytes = await bytesFromWebSocketMessage(message);\n if (!bytes) {\n return;\n }\n\n for (const record of this.decoder.feed(bytes)) {\n this.deliver(record);\n }\n }\n\n private deliver(\n record: WebHostOutputRecord\n ): void {\n const sink = this.sink;\n if (!sink) {\n this.queuedOutput.push(record);\n return;\n }\n\n switch (record.type) {\n case \"surface\":\n sink.presentSurface(record.frame);\n break;\n case \"clipboard\":\n void sink.writeClipboard?.(record.text);\n break;\n case \"runtimeIssue\":\n sink.notifyRuntimeIssue?.(record.issue);\n break;\n case \"frameDiagnostic\":\n sink.recordFrameDiagnostic?.(record.diagnostic);\n break;\n case \"text\":\n sink.writeOutput?.(record.text);\n break;\n }\n }\n\n private flushQueuedInput(): void {\n if (this.disposed || this.socket.readyState !== socketOpenState) {\n return;\n }\n while (this.queuedInput.length > 0) {\n this.socket.send(this.queuedInput.shift()!);\n }\n }\n}\n\nexport function webSocketSceneURL(\n options: Pick<WebSocketSceneBridgeOptions, \"baseURL\" | \"webSocketURL\" | \"sceneId\" | \"token\">\n): URL {\n if (options.webSocketURL) {\n const explicit = new URL(String(options.webSocketURL), currentPageURL());\n explicit.searchParams.set(\"token\", options.token);\n return explicit;\n }\n\n const url = new URL(String(options.baseURL ?? currentPageURL()), currentPageURL());\n url.protocol = url.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n const basePath = url.pathname.endsWith(\"/\") ? url.pathname.slice(0, -1) : url.pathname;\n url.pathname = `${basePath}/ws/scene/${encodeURIComponent(options.sceneId)}`;\n url.search = \"\";\n url.searchParams.set(\"token\", options.token);\n return url;\n}\n\nasync function bytesFromWebSocketMessage(\n message: unknown\n): Promise<Uint8Array | undefined> {\n if (typeof message === \"string\") {\n return textEncoder.encode(message);\n }\n if (message instanceof Uint8Array) {\n return message;\n }\n if (message instanceof ArrayBuffer) {\n return new Uint8Array(message);\n }\n if (ArrayBuffer.isView(message)) {\n return new Uint8Array(message.buffer, message.byteOffset, message.byteLength);\n }\n if (typeof Blob !== \"undefined\" && message instanceof Blob) {\n return new Uint8Array(await message.arrayBuffer());\n }\n return undefined;\n}\n\nfunction defaultWebSocketFactory(\n url: string | URL\n): WebSocketSceneSocket {\n if (typeof WebSocket === \"undefined\") {\n throw new Error(\"WebSocket is not available\");\n }\n return new WebSocket(url) as WebSocketSceneSocket;\n}\n\nfunction currentPageURL(): string {\n return globalThis.location?.href ?? \"http://127.0.0.1/\";\n}\n"],"mappings":"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"}