@zenbu-labs/pixel 0.0.0 → 0.0.13
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.
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +161 -0
- package/dist/bootstrap.d.ts +1 -0
- package/dist/bootstrap.js +75 -0
- package/dist/context-menu.d.ts +20 -0
- package/dist/context-menu.js +57 -0
- package/dist/debug.d.ts +1 -0
- package/dist/debug.js +9 -0
- package/dist/devtools-layout.d.ts +21 -0
- package/dist/devtools-layout.js +45 -0
- package/dist/devtools.d.ts +33 -0
- package/dist/devtools.js +125 -0
- package/dist/electron/index.d.ts +3 -0
- package/dist/electron/index.js +4 -0
- package/dist/host/guest.d.ts +5 -0
- package/dist/host/guest.js +178 -0
- package/dist/host/server.d.ts +91 -0
- package/dist/host/server.js +296 -0
- package/dist/host/shell.d.ts +35 -0
- package/dist/host/shell.js +113 -0
- package/dist/host/strip.d.ts +6 -0
- package/dist/host/strip.js +63 -0
- package/dist/icons.d.ts +30 -0
- package/dist/icons.js +58 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +39 -0
- package/dist/instances.d.ts +30 -0
- package/dist/instances.js +177 -0
- package/dist/layout.d.ts +5 -0
- package/dist/layout.js +34 -0
- package/dist/popup.d.ts +21 -0
- package/dist/popup.js +47 -0
- package/dist/preload/index.d.ts +15 -0
- package/dist/preload/index.js +3 -0
- package/dist/react/colors.d.ts +3 -0
- package/dist/react/colors.js +25 -0
- package/dist/react/components.d.ts +21 -0
- package/dist/react/components.js +45 -0
- package/dist/react/devtools/app.d.ts +3 -0
- package/dist/react/devtools/app.js +89 -0
- package/dist/react/devtools/console-capture.d.ts +1 -0
- package/dist/react/devtools/console-capture.js +41 -0
- package/dist/react/devtools/controller.d.ts +45 -0
- package/dist/react/devtools/controller.js +252 -0
- package/dist/react/devtools/elements.d.ts +4 -0
- package/dist/react/devtools/elements.js +152 -0
- package/dist/react/devtools/export-profile.d.ts +2 -0
- package/dist/react/devtools/export-profile.js +225 -0
- package/dist/react/devtools/fiber-hook.d.ts +1 -0
- package/dist/react/devtools/fiber-hook.js +89 -0
- package/dist/react/devtools/log-panel.d.ts +4 -0
- package/dist/react/devtools/log-panel.js +113 -0
- package/dist/react/devtools/profiler.d.ts +11 -0
- package/dist/react/devtools/profiler.js +374 -0
- package/dist/react/devtools/store.d.ts +27 -0
- package/dist/react/devtools/store.js +61 -0
- package/dist/react/devtools/stores.d.ts +92 -0
- package/dist/react/devtools/stores.js +41 -0
- package/dist/react/devtools/theme.d.ts +35 -0
- package/dist/react/devtools/theme.js +77 -0
- package/dist/react/devtools/ui.d.ts +24 -0
- package/dist/react/devtools/ui.js +59 -0
- package/dist/react/index.d.ts +110 -0
- package/dist/react/index.js +538 -0
- package/dist/react/markdown.d.ts +25 -0
- package/dist/react/markdown.js +270 -0
- package/dist/react/native.d.ts +116 -0
- package/dist/react/native.js +56 -0
- package/dist/react/reconciler-config.d.ts +241 -0
- package/dist/react/reconciler-config.js +412 -0
- package/dist/react/styles.d.ts +88 -0
- package/dist/react/styles.js +85 -0
- package/dist/react/surface.d.ts +55 -0
- package/dist/react/surface.js +74 -0
- package/dist/registry.d.ts +53 -0
- package/dist/registry.js +193 -0
- package/dist/root.d.ts +19 -0
- package/dist/root.js +342 -0
- package/dist/sandbox.d.ts +4 -0
- package/dist/sandbox.js +84 -0
- package/dist/scale.d.ts +7 -0
- package/dist/scale.js +31 -0
- package/dist/ssh/index.d.ts +58 -0
- package/dist/ssh/index.js +445 -0
- package/dist/terminal/applescript.d.ts +2 -0
- package/dist/terminal/applescript.js +20 -0
- package/dist/terminal/detect.d.ts +10 -0
- package/dist/terminal/detect.js +34 -0
- package/dist/terminal/graphics.d.ts +9 -0
- package/dist/terminal/graphics.js +142 -0
- package/dist/terminal/index.d.ts +12 -0
- package/dist/terminal/index.js +23 -0
- package/dist/terminal/run.d.ts +2 -0
- package/dist/terminal/run.js +15 -0
- package/dist/terminal/shared.d.ts +20 -0
- package/dist/terminal/shared.js +88 -0
- package/dist/terminal/terminal.d.ts +66 -0
- package/dist/terminal/terminal.js +6 -0
- package/dist/terminal/terminals/cmux.d.ts +2 -0
- package/dist/terminal/terminals/cmux.js +98 -0
- package/dist/terminal/terminals/ghostty-script.d.ts +1 -0
- package/dist/terminal/terminals/ghostty-script.js +179 -0
- package/dist/terminal/terminals/ghostty.d.ts +2 -0
- package/dist/terminal/terminals/ghostty.js +336 -0
- package/dist/terminal/terminals/herdr.d.ts +2 -0
- package/dist/terminal/terminals/herdr.js +141 -0
- package/dist/terminal/terminals/index.d.ts +5 -0
- package/dist/terminal/terminals/index.js +26 -0
- package/dist/terminal/terminals/kitty.d.ts +2 -0
- package/dist/terminal/terminals/kitty.js +209 -0
- package/dist/terminal/terminals/supacode.d.ts +2 -0
- package/dist/terminal/terminals/supacode.js +79 -0
- package/dist/terminal/terminals/tmux.d.ts +2 -0
- package/dist/terminal/terminals/tmux.js +132 -0
- package/dist/terminal/terminals/tty7.d.ts +2 -0
- package/dist/terminal/terminals/tty7.js +58 -0
- package/dist/terminal/terminals/vscode.d.ts +2 -0
- package/dist/terminal/terminals/vscode.js +13 -0
- package/dist/terminal/terminals/wezterm.d.ts +2 -0
- package/dist/terminal/terminals/wezterm.js +59 -0
- package/dist/theme.d.ts +22 -0
- package/dist/theme.js +40 -0
- package/dist/web/browser-session.d.ts +13 -0
- package/dist/web/browser-session.js +186 -0
- package/dist/web/cursor.d.ts +1 -0
- package/dist/web/cursor.js +24 -0
- package/dist/web/devtools.d.ts +39 -0
- package/dist/web/devtools.js +300 -0
- package/dist/web/favicon.d.ts +7 -0
- package/dist/web/favicon.js +73 -0
- package/dist/web/frame-rate.d.ts +1 -0
- package/dist/web/frame-rate.js +12 -0
- package/dist/web/host.d.ts +123 -0
- package/dist/web/host.js +573 -0
- package/dist/web/input.d.ts +49 -0
- package/dist/web/input.js +468 -0
- package/dist/web/offscreen.d.ts +2 -0
- package/dist/web/offscreen.js +23 -0
- package/dist/web/paint.d.ts +11 -0
- package/dist/web/paint.js +128 -0
- package/dist/web/popup.d.ts +40 -0
- package/dist/web/popup.js +144 -0
- package/dist/web/session.d.ts +20 -0
- package/dist/web/session.js +110 -0
- package/dist/web/types.d.ts +38 -0
- package/dist/web/types.js +39 -0
- package/dist/web/zoom.d.ts +5 -0
- package/dist/web/zoom.js +36 -0
- package/dist/webview.d.ts +55 -0
- package/dist/webview.js +481 -0
- package/package.json +69 -3
- package/scripts/apparmor.sh +71 -0
- package/scripts/postinstall.mjs +150 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Markdown = Markdown;
|
|
4
|
+
exports.slugify = slugify;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const components_1 = require("./components");
|
|
8
|
+
const native_1 = require("./native");
|
|
9
|
+
const HEADING_SCALE = [1.7, 1.4, 1.2, 1.05, 1, 1];
|
|
10
|
+
function Markdown({ text, theme, rem, streaming, monoFont, onLinkClick, highlight, highlightBg, }) {
|
|
11
|
+
const blocks = (0, react_1.useMemo)(() => (0, native_1.parseMarkdown)(text, streaming), [text, streaming]);
|
|
12
|
+
const groups = (0, react_1.useMemo)(() => groupQuotes(blocks), [blocks]);
|
|
13
|
+
const slugs = (0, react_1.useMemo)(() => headingSlugs(blocks), [blocks]);
|
|
14
|
+
const anchors = (0, react_1.useRef)(new Map());
|
|
15
|
+
const external = (0, react_1.useRef)(onLinkClick);
|
|
16
|
+
external.current = onLinkClick;
|
|
17
|
+
const nav = (0, react_1.useRef)({
|
|
18
|
+
anchors,
|
|
19
|
+
follow: (href) => {
|
|
20
|
+
if (href.startsWith("#")) {
|
|
21
|
+
anchors.current.get(href.slice(1))?.scrollIntoView(true); // bad api
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
external.current?.(href);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
const highlighted = (block) => highlight != null && block.sourceEnd > highlight.start && block.sourceStart < highlight.end;
|
|
29
|
+
const firstHighlighted = (0, react_1.useRef)(null);
|
|
30
|
+
(0, react_1.useEffect)(() => {
|
|
31
|
+
if (highlight != null)
|
|
32
|
+
firstHighlighted.current?.scrollIntoView(true);
|
|
33
|
+
}, [highlight?.start, highlight?.end, text]);
|
|
34
|
+
let highlightSeen = false;
|
|
35
|
+
const blockProps = (block, index) => {
|
|
36
|
+
const hit = highlighted(block);
|
|
37
|
+
const first = hit && !highlightSeen;
|
|
38
|
+
if (hit)
|
|
39
|
+
highlightSeen = true;
|
|
40
|
+
return {
|
|
41
|
+
block,
|
|
42
|
+
index,
|
|
43
|
+
slug: slugs.get(index),
|
|
44
|
+
nav: nav.current,
|
|
45
|
+
theme,
|
|
46
|
+
rem,
|
|
47
|
+
monoFont,
|
|
48
|
+
highlightBg: hit ? highlightBg ?? theme.codeBg : undefined,
|
|
49
|
+
highlightRef: first ? firstHighlighted : undefined,
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
return ((0, jsx_runtime_1.jsx)(components_1.Box, { style: { flexDirection: "column", gap: rem * 0.55 }, children: groups.map((group, i) => group.quote > 0 ? ((0, jsx_runtime_1.jsxs)(components_1.Box, { style: { gap: rem * 0.6 }, children: [Array.from({ length: group.quote }, (_, bar) => ((0, jsx_runtime_1.jsx)(components_1.Box, { style: { width: Math.max(2, rem * 0.18), background: theme.separator } }, bar))), (0, jsx_runtime_1.jsx)(components_1.Box, { style: { flexDirection: "column", gap: rem * 0.55, flexShrink: 1 }, children: group.blocks.map(({ block, index }, j) => ((0, jsx_runtime_1.jsx)(Block, { ...blockProps(block, index) }, j))) })] }, i)) : ((0, jsx_runtime_1.jsx)(Block, { ...blockProps(group.blocks[0].block, group.blocks[0].index) }, i))) }));
|
|
53
|
+
}
|
|
54
|
+
function groupQuotes(blocks) {
|
|
55
|
+
const groups = [];
|
|
56
|
+
blocks.forEach((block, index) => {
|
|
57
|
+
const last = groups[groups.length - 1];
|
|
58
|
+
if (block.quote > 0 && last?.quote === block.quote) {
|
|
59
|
+
last.blocks.push({ block, index });
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
groups.push({ quote: block.quote, blocks: [{ block, index }] });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return groups;
|
|
66
|
+
}
|
|
67
|
+
function slugify(text) {
|
|
68
|
+
return text
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
.trim()
|
|
71
|
+
.replace(/[^\p{L}\p{N}\s-]/gu, "")
|
|
72
|
+
.replace(/\s+/g, "-");
|
|
73
|
+
}
|
|
74
|
+
function headingSlugs(blocks) {
|
|
75
|
+
const used = new Map();
|
|
76
|
+
const out = new Map();
|
|
77
|
+
blocks.forEach((block, index) => {
|
|
78
|
+
if (block.kind !== "heading")
|
|
79
|
+
return;
|
|
80
|
+
const base = slugify(block.text);
|
|
81
|
+
const n = used.get(base) ?? 0;
|
|
82
|
+
used.set(base, n + 1);
|
|
83
|
+
out.set(index, n === 0 ? base : `${base}-${n}`);
|
|
84
|
+
});
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
const Block = (0, react_1.memo)(function Block({ block, theme, rem, monoFont, slug, nav, index, highlightBg, highlightRef, }) {
|
|
88
|
+
let body = ((0, jsx_runtime_1.jsx)(BlockBody, { block: block, theme: theme, rem: rem, monoFont: monoFont, slug: slug, nav: nav, index: index }));
|
|
89
|
+
if (highlightBg != null) {
|
|
90
|
+
body = ((0, jsx_runtime_1.jsx)(components_1.Box, { ref: (handle) => {
|
|
91
|
+
if (highlightRef)
|
|
92
|
+
highlightRef.current = handle;
|
|
93
|
+
}, style: {
|
|
94
|
+
background: highlightBg,
|
|
95
|
+
cornerRadius: rem * 0.25,
|
|
96
|
+
margin: { left: -rem * 0.35, right: -rem * 0.35 },
|
|
97
|
+
padding: { left: rem * 0.35, right: rem * 0.35, top: rem * 0.15, bottom: rem * 0.15 },
|
|
98
|
+
}, children: (0, jsx_runtime_1.jsx)(components_1.Box, { style: { flexDirection: "column", flexGrow: 1 }, children: body }) }));
|
|
99
|
+
}
|
|
100
|
+
if (block.listDepth == null)
|
|
101
|
+
return body;
|
|
102
|
+
const indent = block.listDepth * rem * 1.3;
|
|
103
|
+
return ((0, jsx_runtime_1.jsxs)(components_1.Box, { style: { margin: { left: indent } }, children: [(0, jsx_runtime_1.jsx)(components_1.Box, { style: { width: rem * 1.4, flexShrink: 0 }, children: block.itemStart && ((0, jsx_runtime_1.jsx)(components_1.Text, { style: { color: block.task != null ? theme.link : theme.muted }, children: marker(block) })) }), (0, jsx_runtime_1.jsx)(components_1.Box, { style: { flexDirection: "column", flexShrink: 1 }, children: body })] }));
|
|
104
|
+
}, (a, b) => a.theme === b.theme &&
|
|
105
|
+
a.rem === b.rem &&
|
|
106
|
+
a.monoFont === b.monoFont &&
|
|
107
|
+
a.slug === b.slug &&
|
|
108
|
+
a.index === b.index &&
|
|
109
|
+
a.highlightBg === b.highlightBg &&
|
|
110
|
+
a.highlightRef === b.highlightRef &&
|
|
111
|
+
blockEqual(a.block, b.block));
|
|
112
|
+
function marker(block) {
|
|
113
|
+
if (block.task != null)
|
|
114
|
+
return block.task ? "☑" : "□";
|
|
115
|
+
if (block.ordinal != null)
|
|
116
|
+
return `${block.ordinal}.`;
|
|
117
|
+
return "•";
|
|
118
|
+
}
|
|
119
|
+
function blockEqual(a, b) {
|
|
120
|
+
return (a.kind === b.kind &&
|
|
121
|
+
a.text === b.text &&
|
|
122
|
+
a.level === b.level &&
|
|
123
|
+
a.language === b.language &&
|
|
124
|
+
a.closed === b.closed &&
|
|
125
|
+
a.quote === b.quote &&
|
|
126
|
+
a.listDepth === b.listDepth &&
|
|
127
|
+
a.ordinal === b.ordinal &&
|
|
128
|
+
a.task === b.task &&
|
|
129
|
+
a.itemStart === b.itemStart &&
|
|
130
|
+
a.src === b.src &&
|
|
131
|
+
spansEqual(a.spans, b.spans) &&
|
|
132
|
+
a.aligns.length === b.aligns.length &&
|
|
133
|
+
a.aligns.every((al, i) => al === b.aligns[i]) &&
|
|
134
|
+
a.rows.length === b.rows.length &&
|
|
135
|
+
a.rows.every((row, i) => rowEqual(row, b.rows[i])));
|
|
136
|
+
}
|
|
137
|
+
function rowEqual(a, b) {
|
|
138
|
+
return (a.cells.length === b.cells.length &&
|
|
139
|
+
a.cells.every((cell, i) => cell.text === b.cells[i].text && spansEqual(cell.spans, b.cells[i].spans)));
|
|
140
|
+
}
|
|
141
|
+
function spansEqual(a, b) {
|
|
142
|
+
return (a.length === b.length &&
|
|
143
|
+
a.every((s, i) => {
|
|
144
|
+
const o = b[i];
|
|
145
|
+
return (s.start === o.start &&
|
|
146
|
+
s.end === o.end &&
|
|
147
|
+
s.bold === o.bold &&
|
|
148
|
+
s.italic === o.italic &&
|
|
149
|
+
s.strikethrough === o.strikethrough &&
|
|
150
|
+
s.code === o.code &&
|
|
151
|
+
s.link === o.link &&
|
|
152
|
+
s.incompleteLink === o.incompleteLink);
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
function blockId(index) {
|
|
156
|
+
return index != null ? `md:${index}` : undefined;
|
|
157
|
+
}
|
|
158
|
+
function BlockBody({ block, theme, rem, monoFont, slug, nav, index }) {
|
|
159
|
+
switch (block.kind) {
|
|
160
|
+
case "heading": {
|
|
161
|
+
const scale = HEADING_SCALE[block.level - 1] ?? 1;
|
|
162
|
+
return ((0, jsx_runtime_1.jsx)(components_1.Text, { id: blockId(index), ref: (handle) => {
|
|
163
|
+
if (!slug || !nav)
|
|
164
|
+
return;
|
|
165
|
+
if (handle)
|
|
166
|
+
nav.anchors.current.set(slug, handle);
|
|
167
|
+
else
|
|
168
|
+
nav.anchors.current.delete(slug);
|
|
169
|
+
}, style: { fontSize: rem * scale, color: theme.fg }, spans: styledSpans(block.text, block.spans, theme, { bold: true, cover: true }), onClick: linkClick(block.spans, nav), children: block.text }));
|
|
170
|
+
}
|
|
171
|
+
case "code":
|
|
172
|
+
return ((0, jsx_runtime_1.jsx)(CodeBlock, { block: block, theme: theme, rem: rem, monoFont: monoFont, index: index }));
|
|
173
|
+
case "rule":
|
|
174
|
+
return (0, jsx_runtime_1.jsx)(components_1.Box, { style: { height: 1, background: theme.separator } });
|
|
175
|
+
case "image":
|
|
176
|
+
return ((0, jsx_runtime_1.jsx)(components_1.Image, { src: block.src, style: { height: rem * 8, cornerRadius: rem * 0.4 }, placeholder: (0, jsx_runtime_1.jsx)(components_1.Box, { style: { background: theme.codeBg } }) }));
|
|
177
|
+
case "table":
|
|
178
|
+
return (0, jsx_runtime_1.jsx)(Table, { block: block, theme: theme, rem: rem, nav: nav, index: index });
|
|
179
|
+
default:
|
|
180
|
+
return ((0, jsx_runtime_1.jsx)(components_1.Text, { id: blockId(index), style: { color: theme.fg }, spans: styledSpans(block.text, block.spans, theme, {}), onClick: linkClick(block.spans, nav), children: block.text }));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function linkClick(spans, nav) {
|
|
184
|
+
if (!nav || !spans.some((s) => s.link))
|
|
185
|
+
return undefined;
|
|
186
|
+
return (event) => {
|
|
187
|
+
if (event.offset == null)
|
|
188
|
+
return;
|
|
189
|
+
const hit = spans.find((s) => s.link && s.start <= event.offset && event.offset < s.end);
|
|
190
|
+
if (hit?.link)
|
|
191
|
+
nav.follow(hit.link);
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function styledSpans(text, spans, theme, opts) {
|
|
195
|
+
if (!spans.length && !opts.cover)
|
|
196
|
+
return undefined;
|
|
197
|
+
const styled = spans.map((s) => ({
|
|
198
|
+
start: s.start,
|
|
199
|
+
end: s.end,
|
|
200
|
+
color: s.code ? theme.inlineCode : s.link || s.incompleteLink ? theme.link : theme.fg,
|
|
201
|
+
background: s.code ? theme.codeBg : undefined,
|
|
202
|
+
bold: s.bold || opts.bold,
|
|
203
|
+
italic: s.italic,
|
|
204
|
+
underline: Boolean(s.link),
|
|
205
|
+
strikethrough: s.strikethrough,
|
|
206
|
+
}));
|
|
207
|
+
if (!opts.cover)
|
|
208
|
+
return styled;
|
|
209
|
+
const bytes = Buffer.byteLength(text);
|
|
210
|
+
const covered = [];
|
|
211
|
+
let at = 0;
|
|
212
|
+
for (const span of styled) {
|
|
213
|
+
if (span.start > at)
|
|
214
|
+
covered.push({ start: at, end: span.start, color: theme.fg, bold: opts.bold });
|
|
215
|
+
covered.push(span);
|
|
216
|
+
at = span.end;
|
|
217
|
+
}
|
|
218
|
+
if (at < bytes)
|
|
219
|
+
covered.push({ start: at, end: bytes, color: theme.fg, bold: opts.bold });
|
|
220
|
+
return covered;
|
|
221
|
+
}
|
|
222
|
+
const CELL_JUSTIFY = { left: "start", center: "center", right: "end", none: "start" };
|
|
223
|
+
function Table({ block, theme, rem, nav, index }) {
|
|
224
|
+
const columns = block.rows[0]?.cells.length ?? 0;
|
|
225
|
+
const weights = Array.from({ length: columns }, (_, c) => Math.min(42, Math.max(3, ...block.rows.map((row) => row.cells[c]?.text.length ?? 0))));
|
|
226
|
+
if (columns === 0)
|
|
227
|
+
return null;
|
|
228
|
+
return ((0, jsx_runtime_1.jsx)(components_1.Box, { style: {
|
|
229
|
+
flexDirection: "column",
|
|
230
|
+
border: { width: 1, color: theme.separator },
|
|
231
|
+
padding: 1,
|
|
232
|
+
overflow: "hidden",
|
|
233
|
+
}, children: block.rows.map((row, r) => ((0, jsx_runtime_1.jsx)(components_1.Box, { style: {
|
|
234
|
+
background: r === 0 ? theme.codeBg : undefined,
|
|
235
|
+
border: r > 0 ? { top: [1, theme.separator] } : undefined,
|
|
236
|
+
}, children: Array.from({ length: columns }, (_, c) => {
|
|
237
|
+
const cell = row.cells[c];
|
|
238
|
+
const align = block.aligns[c] ?? "none";
|
|
239
|
+
return ((0, jsx_runtime_1.jsx)(components_1.Box, { style: {
|
|
240
|
+
flexGrow: weights[c],
|
|
241
|
+
flexBasis: 0,
|
|
242
|
+
justifyContent: CELL_JUSTIFY[align],
|
|
243
|
+
border: c > 0 ? { left: [1, theme.separator] } : undefined,
|
|
244
|
+
padding: {
|
|
245
|
+
left: rem * 0.6,
|
|
246
|
+
right: rem * 0.6,
|
|
247
|
+
top: rem * 0.35,
|
|
248
|
+
bottom: rem * 0.35,
|
|
249
|
+
},
|
|
250
|
+
}, children: cell && ((0, jsx_runtime_1.jsx)(components_1.Text, { id: blockId(index), style: { color: theme.fg }, spans: styledSpans(cell.text, cell.spans, theme, {
|
|
251
|
+
bold: r === 0,
|
|
252
|
+
cover: r === 0,
|
|
253
|
+
}), onClick: linkClick(cell.spans, nav), children: cell.text })) }, c));
|
|
254
|
+
}) }, r))) }));
|
|
255
|
+
}
|
|
256
|
+
function CodeBlock({ block, theme, rem, monoFont, index }) {
|
|
257
|
+
const spans = (0, react_1.useMemo)(() => (0, native_1.highlight)(block.text, block.language).map((s) => ({
|
|
258
|
+
start: s.start,
|
|
259
|
+
end: s.end,
|
|
260
|
+
color: theme.syntax[native_1.HIGHLIGHT_CAPTURES[s.capture]] ?? theme.fg,
|
|
261
|
+
})), [block.text, block.language, theme]);
|
|
262
|
+
return ((0, jsx_runtime_1.jsxs)(components_1.Box, { style: {
|
|
263
|
+
flexDirection: "column",
|
|
264
|
+
background: theme.codeBg,
|
|
265
|
+
cornerRadius: rem * 0.35,
|
|
266
|
+
padding: { left: rem * 0.75, right: rem * 0.75, top: rem * 0.5, bottom: rem * 0.5 },
|
|
267
|
+
gap: rem * 0.35,
|
|
268
|
+
overflow: "hidden",
|
|
269
|
+
}, children: [block.language !== "" && ((0, jsx_runtime_1.jsx)(components_1.Text, { style: { color: theme.muted, fontSize: rem * 0.8 }, children: block.language + (block.closed ? "" : " …") })), (0, jsx_runtime_1.jsx)(components_1.Text, { id: blockId(index), style: { wrap: false, color: theme.fg, font: monoFont }, spans: spans, children: block.text })] }));
|
|
270
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export interface DamageRect {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
}
|
|
7
|
+
export interface SurfaceShm {
|
|
8
|
+
fd: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
stride: number;
|
|
12
|
+
size: number;
|
|
13
|
+
}
|
|
14
|
+
export interface NativeEngine {
|
|
15
|
+
info(): string;
|
|
16
|
+
applyOps(ops: string): void;
|
|
17
|
+
updateSurface(id: number, bgra: Buffer, width: number, height: number, damage?: DamageRect): void;
|
|
18
|
+
updateSurfaceTexture?(id: number, handle: Buffer, damage?: DamageRect): void;
|
|
19
|
+
updateSurfaceShm?(id: number, shm: SurfaceShm, damage?: DamageRect, released?: (...args: unknown[]) => void): void;
|
|
20
|
+
removeSurface(id: number): void;
|
|
21
|
+
surfaceStats(): string;
|
|
22
|
+
startSurfaceCapture(surfaceId: number, dir: string): number;
|
|
23
|
+
stopSurfaceCapture(captureId: number): string;
|
|
24
|
+
captureIndex(captureId: number): string;
|
|
25
|
+
captureFrame(captureId: number, index: number): Buffer;
|
|
26
|
+
releaseCapture(captureId: number): void;
|
|
27
|
+
setKeyEventTypes(enabled: boolean): void;
|
|
28
|
+
start(callback: (err: unknown, event: string) => void): void;
|
|
29
|
+
stop(): void;
|
|
30
|
+
}
|
|
31
|
+
export type Rgba = [number, number, number, number];
|
|
32
|
+
export type TerminalColors = {
|
|
33
|
+
foreground: Rgba | null;
|
|
34
|
+
background: Rgba | null;
|
|
35
|
+
palette: (Rgba | null)[];
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* fixme: this is a very weird name to export
|
|
39
|
+
*/
|
|
40
|
+
export interface EngineInfo {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
cellWidth: number;
|
|
44
|
+
cellHeight: number;
|
|
45
|
+
basePx: number;
|
|
46
|
+
kittyKeyboard: boolean;
|
|
47
|
+
hosted: boolean;
|
|
48
|
+
colors: TerminalColors;
|
|
49
|
+
}
|
|
50
|
+
export interface HostOptions {
|
|
51
|
+
socket: string;
|
|
52
|
+
pane: string;
|
|
53
|
+
name: string;
|
|
54
|
+
/** [placeholder copy: Set when the host is not pixel: frames are drawn into this terminal as kitty virtual placements the host positions.] */
|
|
55
|
+
tty?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface HighlightSpan {
|
|
58
|
+
start: number;
|
|
59
|
+
end: number;
|
|
60
|
+
capture: number;
|
|
61
|
+
}
|
|
62
|
+
export interface MarkdownSpan {
|
|
63
|
+
start: number;
|
|
64
|
+
end: number;
|
|
65
|
+
bold: boolean;
|
|
66
|
+
italic: boolean;
|
|
67
|
+
strikethrough: boolean;
|
|
68
|
+
code: boolean;
|
|
69
|
+
link?: string;
|
|
70
|
+
incompleteLink: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface MarkdownCell {
|
|
73
|
+
text: string;
|
|
74
|
+
spans: MarkdownSpan[];
|
|
75
|
+
}
|
|
76
|
+
export interface MarkdownRow {
|
|
77
|
+
cells: MarkdownCell[];
|
|
78
|
+
}
|
|
79
|
+
export interface MarkdownBlock {
|
|
80
|
+
kind: "paragraph" | "heading" | "code" | "rule" | "image" | "table";
|
|
81
|
+
text: string;
|
|
82
|
+
spans: MarkdownSpan[];
|
|
83
|
+
level: number;
|
|
84
|
+
language: string;
|
|
85
|
+
closed: boolean;
|
|
86
|
+
quote: number;
|
|
87
|
+
listDepth?: number;
|
|
88
|
+
ordinal?: number;
|
|
89
|
+
task?: boolean;
|
|
90
|
+
itemStart: boolean;
|
|
91
|
+
src: string;
|
|
92
|
+
rows: MarkdownRow[];
|
|
93
|
+
aligns: ("left" | "center" | "right" | "none")[];
|
|
94
|
+
sourceStart: number;
|
|
95
|
+
sourceEnd: number;
|
|
96
|
+
}
|
|
97
|
+
export interface DiffEmphasis {
|
|
98
|
+
start: number;
|
|
99
|
+
end: number;
|
|
100
|
+
}
|
|
101
|
+
export interface DiffRow {
|
|
102
|
+
kind: "context" | "del" | "add" | "gap";
|
|
103
|
+
oldLine?: number;
|
|
104
|
+
newLine?: number;
|
|
105
|
+
text: string;
|
|
106
|
+
sideStart: number;
|
|
107
|
+
emphasis: DiffEmphasis[];
|
|
108
|
+
count?: number;
|
|
109
|
+
}
|
|
110
|
+
export declare function createNativeEngine(tty?: string, wrapper?: string, sessionEnv?: NodeJS.ProcessEnv, host?: HostOptions): NativeEngine;
|
|
111
|
+
export declare function highlight(source: string, language: string): HighlightSpan[];
|
|
112
|
+
export declare const HIGHLIGHT_CAPTURES: readonly string[];
|
|
113
|
+
export declare function diff(oldSource: string, newSource: string, contextLines?: number): DiffRow[];
|
|
114
|
+
export declare function encodeRecording(jobJson: string, onProgress?: (percent: number) => void): Promise<void>;
|
|
115
|
+
export declare function captureFilmstrip(dir: string, frames: number[], tileWidth: number, width: number, height: number): Promise<Buffer>;
|
|
116
|
+
export declare function parseMarkdown(source: string, streaming?: boolean): MarkdownBlock[];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HIGHLIGHT_CAPTURES = void 0;
|
|
4
|
+
exports.createNativeEngine = createNativeEngine;
|
|
5
|
+
exports.highlight = highlight;
|
|
6
|
+
exports.diff = diff;
|
|
7
|
+
exports.encodeRecording = encodeRecording;
|
|
8
|
+
exports.captureFilmstrip = captureFilmstrip;
|
|
9
|
+
exports.parseMarkdown = parseMarkdown;
|
|
10
|
+
const NATIVE_PACKAGE = `@zenbu-labs/pixel-native-${process.platform}-${process.arch}`;
|
|
11
|
+
function loadBinding() {
|
|
12
|
+
try {
|
|
13
|
+
return require(`${NATIVE_PACKAGE}/pixel.node`);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const target = `${process.platform}-${process.arch} (${NATIVE_PACKAGE})`;
|
|
17
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
18
|
+
throw new Error(error.code === "MODULE_NOT_FOUND"
|
|
19
|
+
? `no native build for ${target}: ${message}]`
|
|
20
|
+
: `failed to load: ${message}]`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (process.platform === "darwin" && !process.env.NATIVE_SCROLL_HELPER) {
|
|
24
|
+
try {
|
|
25
|
+
process.env.NATIVE_SCROLL_HELPER = require.resolve(`${NATIVE_PACKAGE}/native-scroll-helper`);
|
|
26
|
+
}
|
|
27
|
+
catch { }
|
|
28
|
+
}
|
|
29
|
+
const binding = loadBinding();
|
|
30
|
+
function createNativeEngine(tty, wrapper, sessionEnv, host) {
|
|
31
|
+
const env = sessionEnv
|
|
32
|
+
? Object.fromEntries(Object.entries(sessionEnv).filter((entry) => typeof entry[1] === "string"))
|
|
33
|
+
: undefined;
|
|
34
|
+
const pixelEngine = new binding.PixelEngine(tty, wrapper, env, host);
|
|
35
|
+
return pixelEngine;
|
|
36
|
+
}
|
|
37
|
+
function highlight(source, language) {
|
|
38
|
+
return binding.highlight(source, language);
|
|
39
|
+
}
|
|
40
|
+
exports.HIGHLIGHT_CAPTURES = binding.highlightCaptures();
|
|
41
|
+
function diff(oldSource, newSource, contextLines) {
|
|
42
|
+
return binding.diff(oldSource, newSource, contextLines);
|
|
43
|
+
}
|
|
44
|
+
function encodeRecording(jobJson, onProgress) {
|
|
45
|
+
return binding.encodeRecording(jobJson, onProgress &&
|
|
46
|
+
((err, percent) => {
|
|
47
|
+
if (err == null)
|
|
48
|
+
onProgress(percent);
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
function captureFilmstrip(dir, frames, tileWidth, width, height) {
|
|
52
|
+
return binding.captureFilmstrip(dir, frames, tileWidth, width, height);
|
|
53
|
+
}
|
|
54
|
+
function parseMarkdown(source, streaming) {
|
|
55
|
+
return binding.parseMarkdown(source, streaming);
|
|
56
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import Reconciler from "react-reconciler";
|
|
2
|
+
import { HostOptions, NativeEngine } from "./native";
|
|
3
|
+
import { Color, Style } from "./styles";
|
|
4
|
+
import { Surface } from "./surface";
|
|
5
|
+
export declare const APP_VIEW = 0;
|
|
6
|
+
export declare const DEVTOOLS_VIEW = 1;
|
|
7
|
+
export interface ClickEvent {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
offset?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ScrollEvent {
|
|
13
|
+
offset: number;
|
|
14
|
+
max: number;
|
|
15
|
+
}
|
|
16
|
+
export interface EventMods {
|
|
17
|
+
shift: boolean;
|
|
18
|
+
alt: boolean;
|
|
19
|
+
ctrl: boolean;
|
|
20
|
+
super: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface WheelEvent {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
deltaX: number;
|
|
26
|
+
deltaY: number;
|
|
27
|
+
precise: boolean;
|
|
28
|
+
mods: EventMods;
|
|
29
|
+
}
|
|
30
|
+
export interface PointerEvent {
|
|
31
|
+
kind: "down" | "up" | "move";
|
|
32
|
+
button: "left" | "middle" | "right" | "none";
|
|
33
|
+
mods: {
|
|
34
|
+
shift: boolean;
|
|
35
|
+
alt: boolean;
|
|
36
|
+
ctrl: boolean;
|
|
37
|
+
super: boolean;
|
|
38
|
+
};
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
}
|
|
42
|
+
export interface DragEvent {
|
|
43
|
+
phase: "start" | "move" | "end";
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
mods: EventMods;
|
|
47
|
+
}
|
|
48
|
+
export interface MouseMoveEvent {
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
51
|
+
}
|
|
52
|
+
export interface SelectionPart {
|
|
53
|
+
key: string;
|
|
54
|
+
start: number;
|
|
55
|
+
end: number;
|
|
56
|
+
}
|
|
57
|
+
export interface ContainerSelection {
|
|
58
|
+
text: string;
|
|
59
|
+
x: number;
|
|
60
|
+
y: number;
|
|
61
|
+
w: number;
|
|
62
|
+
h: number;
|
|
63
|
+
parts: SelectionPart[];
|
|
64
|
+
}
|
|
65
|
+
export interface BoxProps {
|
|
66
|
+
style?: Style;
|
|
67
|
+
id?: string;
|
|
68
|
+
/** [placeholder copy: Lays the box out as nothing and paints none of it, keeping its children mounted.] */
|
|
69
|
+
hidden?: boolean;
|
|
70
|
+
onClick?: (event: ClickEvent) => void;
|
|
71
|
+
onClickOutside?: (event: ClickEvent) => void;
|
|
72
|
+
onScroll?: (event: ScrollEvent) => void;
|
|
73
|
+
onWheel?: (event: WheelEvent) => void;
|
|
74
|
+
onPointer?: (event: PointerEvent) => void;
|
|
75
|
+
onMouseEnter?: () => void;
|
|
76
|
+
onMouseLeave?: () => void;
|
|
77
|
+
onMouseMove?: (event: MouseMoveEvent) => void;
|
|
78
|
+
onDrag?: (event: DragEvent) => void;
|
|
79
|
+
onSelection?: (selection: ContainerSelection) => void;
|
|
80
|
+
contentHeight?: number;
|
|
81
|
+
surface?: Surface;
|
|
82
|
+
children?: React.ReactNode;
|
|
83
|
+
}
|
|
84
|
+
export interface ShapeStroke {
|
|
85
|
+
width: number;
|
|
86
|
+
color: Color;
|
|
87
|
+
cap?: "butt" | "round" | "square";
|
|
88
|
+
join?: "miter" | "round" | "bevel";
|
|
89
|
+
}
|
|
90
|
+
export interface PathProps {
|
|
91
|
+
style?: Style;
|
|
92
|
+
id?: string;
|
|
93
|
+
hidden?: boolean;
|
|
94
|
+
d: string;
|
|
95
|
+
stroke: ShapeStroke;
|
|
96
|
+
viewBox?: number;
|
|
97
|
+
onClick?: (event: ClickEvent) => void;
|
|
98
|
+
onMouseEnter?: () => void;
|
|
99
|
+
onMouseLeave?: () => void;
|
|
100
|
+
onDrag?: (event: DragEvent) => void;
|
|
101
|
+
}
|
|
102
|
+
export interface TextSpan {
|
|
103
|
+
start: number;
|
|
104
|
+
end: number;
|
|
105
|
+
color: Color;
|
|
106
|
+
background?: Color;
|
|
107
|
+
bold?: boolean;
|
|
108
|
+
italic?: boolean;
|
|
109
|
+
underline?: boolean;
|
|
110
|
+
strikethrough?: boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface TextProps {
|
|
113
|
+
style?: Style;
|
|
114
|
+
id?: string;
|
|
115
|
+
onClick?: (event: ClickEvent) => void;
|
|
116
|
+
onMouseEnter?: () => void;
|
|
117
|
+
onMouseLeave?: () => void;
|
|
118
|
+
spans?: TextSpan[];
|
|
119
|
+
children?: React.ReactNode;
|
|
120
|
+
}
|
|
121
|
+
export interface MarkRef {
|
|
122
|
+
id: number;
|
|
123
|
+
offset: number;
|
|
124
|
+
/**
|
|
125
|
+
* in the case the engine creates the mark (a paste event where it deserializes the bespoke paste format)
|
|
126
|
+
* the application needs to know about the deserialized data to start internally tracking it
|
|
127
|
+
*/
|
|
128
|
+
data?: string;
|
|
129
|
+
}
|
|
130
|
+
export type PasteSource = "clipboard" | "osc" | "file";
|
|
131
|
+
export interface PastedImage {
|
|
132
|
+
path: string;
|
|
133
|
+
width: number;
|
|
134
|
+
height: number;
|
|
135
|
+
source: PasteSource;
|
|
136
|
+
}
|
|
137
|
+
export interface CaretInfo {
|
|
138
|
+
cursor: number;
|
|
139
|
+
x: number;
|
|
140
|
+
y: number;
|
|
141
|
+
w: number;
|
|
142
|
+
h: number;
|
|
143
|
+
}
|
|
144
|
+
export type ChangeSource = "type" | "paste" | "edit";
|
|
145
|
+
export interface ChangeInfo extends CaretInfo {
|
|
146
|
+
source: ChangeSource;
|
|
147
|
+
marks: MarkRef[];
|
|
148
|
+
}
|
|
149
|
+
export interface InputGutter {
|
|
150
|
+
color: Color;
|
|
151
|
+
activeColor: Color;
|
|
152
|
+
}
|
|
153
|
+
export interface InputProps {
|
|
154
|
+
style?: Style;
|
|
155
|
+
id?: string;
|
|
156
|
+
defaultValue?: string;
|
|
157
|
+
value?: string;
|
|
158
|
+
defaultMarks?: MarkRef[];
|
|
159
|
+
renderMark?: (id: number) => React.ReactNode;
|
|
160
|
+
serializeMark?: (id: number) => string | undefined;
|
|
161
|
+
caretColor?: Style["color"];
|
|
162
|
+
selectionColor?: Style["color"];
|
|
163
|
+
autoFocus?: boolean;
|
|
164
|
+
spans?: TextSpan[];
|
|
165
|
+
gutter?: InputGutter;
|
|
166
|
+
activeLine?: Color;
|
|
167
|
+
onChange?: (text: string, change: ChangeInfo) => void;
|
|
168
|
+
onCaret?: (caret: CaretInfo) => void;
|
|
169
|
+
onSubmit?: (text: string, marks: MarkRef[]) => void;
|
|
170
|
+
onPasteImage?: (image: PastedImage) => void;
|
|
171
|
+
}
|
|
172
|
+
export interface MarkedTextProps {
|
|
173
|
+
style?: Style;
|
|
174
|
+
id?: string;
|
|
175
|
+
text: string;
|
|
176
|
+
marks: MarkRef[];
|
|
177
|
+
renderMark?: (id: number) => React.ReactNode;
|
|
178
|
+
serializeMark?: (id: number) => string | undefined;
|
|
179
|
+
onClick?: (event: ClickEvent) => void;
|
|
180
|
+
}
|
|
181
|
+
export interface ImageAdvancedProps {
|
|
182
|
+
confirmedEqualTo?: string[];
|
|
183
|
+
}
|
|
184
|
+
export interface ImageProps {
|
|
185
|
+
style?: Style;
|
|
186
|
+
id?: string;
|
|
187
|
+
src: string;
|
|
188
|
+
onClick?: (event: ClickEvent) => void;
|
|
189
|
+
placeholder?: React.ReactNode;
|
|
190
|
+
error?: React.ReactNode;
|
|
191
|
+
advanced?: ImageAdvancedProps;
|
|
192
|
+
}
|
|
193
|
+
export type AnyProps = BoxProps & TextProps & InputProps & Partial<ImageProps> & Partial<Omit<MarkedTextProps, "style" | "id" | "onClick">> & Partial<PathProps> & {
|
|
194
|
+
slot?: "placeholder" | "error";
|
|
195
|
+
mark?: number;
|
|
196
|
+
};
|
|
197
|
+
export interface Instance {
|
|
198
|
+
id: number;
|
|
199
|
+
bridge: Bridge;
|
|
200
|
+
view: number;
|
|
201
|
+
type: string;
|
|
202
|
+
props: AnyProps;
|
|
203
|
+
parent: Instance | Container | null;
|
|
204
|
+
children: Instance[];
|
|
205
|
+
mounted: boolean;
|
|
206
|
+
hidden: boolean;
|
|
207
|
+
lastSent: string | null;
|
|
208
|
+
}
|
|
209
|
+
export interface Container {
|
|
210
|
+
bridge: Bridge;
|
|
211
|
+
view: number;
|
|
212
|
+
children: Instance[];
|
|
213
|
+
}
|
|
214
|
+
type Op = Record<string, unknown>;
|
|
215
|
+
export interface FlushSample {
|
|
216
|
+
seq: number;
|
|
217
|
+
view: number;
|
|
218
|
+
ops: number;
|
|
219
|
+
start: number;
|
|
220
|
+
dur: number;
|
|
221
|
+
}
|
|
222
|
+
export declare class Bridge {
|
|
223
|
+
engine: NativeEngine;
|
|
224
|
+
propsById: Array<Map<number, AnyProps>>;
|
|
225
|
+
containers: Array<Container | null>;
|
|
226
|
+
onFlush: ((sample: FlushSample) => void) | null;
|
|
227
|
+
onTreeMutation: ((view: number) => void) | null;
|
|
228
|
+
afterCommit: ((view: number) => void) | null;
|
|
229
|
+
private queues;
|
|
230
|
+
private nextId;
|
|
231
|
+
private seq;
|
|
232
|
+
constructor(tty?: string, wrapper?: string, sessionEnv?: NodeJS.ProcessEnv, host?: HostOptions);
|
|
233
|
+
allocId(): number;
|
|
234
|
+
push(view: number, op: Op): void;
|
|
235
|
+
flush(): void;
|
|
236
|
+
}
|
|
237
|
+
export declare function getBridge(wrapper?: string): Bridge;
|
|
238
|
+
export declare function devtoolsBridge(): Bridge;
|
|
239
|
+
export declare function setDevtoolsBridge(bridge: Bridge): void;
|
|
240
|
+
export declare const reconciler: Reconciler.Reconciler<unknown, unknown, unknown, unknown, unknown>;
|
|
241
|
+
export {};
|