@svelterm/core 0.1.0 → 0.21.0

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 (164) hide show
  1. package/CHANGELOG.md +425 -0
  2. package/README.md +42 -29
  3. package/dist/src/cli/build.d.ts +13 -0
  4. package/dist/src/cli/build.js +119 -0
  5. package/dist/src/cli/bundle.d.ts +25 -0
  6. package/dist/src/cli/bundle.js +61 -0
  7. package/dist/src/cli/dev.d.ts +10 -0
  8. package/dist/src/cli/dev.js +152 -0
  9. package/dist/src/cli/devtools.d.ts +9 -0
  10. package/dist/src/cli/devtools.js +47 -0
  11. package/dist/src/cli/init.d.ts +8 -0
  12. package/dist/src/cli/init.js +153 -0
  13. package/dist/src/cli/main.d.ts +9 -0
  14. package/dist/src/cli/main.js +52 -0
  15. package/dist/src/cli/svt-bin.d.ts +2 -0
  16. package/dist/src/cli/svt-bin.js +6 -0
  17. package/dist/src/cli/svt.d.ts +14 -0
  18. package/dist/src/cli/svt.js +76 -0
  19. package/dist/src/components/text-buffer.js +8 -5
  20. package/dist/src/css/animation-runner.d.ts +15 -6
  21. package/dist/src/css/animation-runner.js +80 -29
  22. package/dist/src/css/animation.d.ts +12 -0
  23. package/dist/src/css/animation.js +21 -0
  24. package/dist/src/css/calc.js +4 -3
  25. package/dist/src/css/color.d.ts +19 -0
  26. package/dist/src/css/color.js +371 -62
  27. package/dist/src/css/compute.d.ts +30 -3
  28. package/dist/src/css/compute.js +272 -33
  29. package/dist/src/css/defaults.d.ts +1 -1
  30. package/dist/src/css/defaults.js +9 -0
  31. package/dist/src/css/easing.d.ts +9 -0
  32. package/dist/src/css/easing.js +95 -0
  33. package/dist/src/css/incremental.d.ts +1 -1
  34. package/dist/src/css/incremental.js +2 -2
  35. package/dist/src/css/interpolate.d.ts +13 -0
  36. package/dist/src/css/interpolate.js +41 -0
  37. package/dist/src/css/parser.js +59 -3
  38. package/dist/src/css/pseudo-elements.d.ts +9 -0
  39. package/dist/src/css/pseudo-elements.js +97 -0
  40. package/dist/src/css/selector.d.ts +17 -2
  41. package/dist/src/css/selector.js +128 -13
  42. package/dist/src/css/specificity.js +17 -6
  43. package/dist/src/css/values.d.ts +6 -1
  44. package/dist/src/css/values.js +13 -6
  45. package/dist/src/debug/context.d.ts +13 -0
  46. package/dist/src/debug/context.js +11 -0
  47. package/dist/src/debug/css.d.ts +12 -0
  48. package/dist/src/debug/css.js +28 -0
  49. package/dist/src/debug/dom.d.ts +17 -0
  50. package/dist/src/debug/dom.js +92 -0
  51. package/dist/src/devtools/DevTools.compiled.js +327 -0
  52. package/dist/src/devtools/DevTools.css.js +1 -0
  53. package/dist/src/devtools/client.d.ts +36 -0
  54. package/dist/src/devtools/client.js +76 -0
  55. package/dist/src/framelog.d.ts +54 -0
  56. package/dist/src/framelog.js +99 -0
  57. package/dist/src/headless.js +12 -4
  58. package/dist/src/index.d.ts +65 -3
  59. package/dist/src/index.js +609 -81
  60. package/dist/src/input/checkable.d.ts +8 -0
  61. package/dist/src/input/checkable.js +66 -0
  62. package/dist/src/input/details.d.ts +6 -0
  63. package/dist/src/input/details.js +34 -0
  64. package/dist/src/input/focus.d.ts +6 -0
  65. package/dist/src/input/focus.js +27 -9
  66. package/dist/src/input/keyboard.d.ts +2 -2
  67. package/dist/src/input/keyboard.js +32 -5
  68. package/dist/src/input/label.d.ts +8 -0
  69. package/dist/src/input/label.js +53 -0
  70. package/dist/src/input/modal.d.ts +9 -0
  71. package/dist/src/input/modal.js +28 -0
  72. package/dist/src/input/mouse.d.ts +2 -2
  73. package/dist/src/input/mouse.js +15 -2
  74. package/dist/src/input/select.d.ts +12 -0
  75. package/dist/src/input/select.js +63 -0
  76. package/dist/src/input/selection.d.ts +48 -0
  77. package/dist/src/input/selection.js +150 -0
  78. package/dist/src/layout/engine.d.ts +2 -0
  79. package/dist/src/layout/engine.js +1084 -142
  80. package/dist/src/layout/flex.js +4 -4
  81. package/dist/src/layout/size.js +3 -2
  82. package/dist/src/layout/text.d.ts +3 -2
  83. package/dist/src/layout/text.js +96 -17
  84. package/dist/src/layout/unicode.d.ts +20 -0
  85. package/dist/src/layout/unicode.js +121 -0
  86. package/dist/src/render/animation-clock.d.ts +51 -0
  87. package/dist/src/render/animation-clock.js +213 -0
  88. package/dist/src/render/ansi-text.d.ts +26 -0
  89. package/dist/src/render/ansi-text.js +131 -0
  90. package/dist/src/render/ansi.d.ts +18 -0
  91. package/dist/src/render/ansi.js +64 -19
  92. package/dist/src/render/border.js +166 -17
  93. package/dist/src/render/buffer.d.ts +1 -0
  94. package/dist/src/render/buffer.js +5 -2
  95. package/dist/src/render/color-depth.d.ts +8 -0
  96. package/dist/src/render/color-depth.js +59 -0
  97. package/dist/src/render/context.d.ts +1 -0
  98. package/dist/src/render/context.js +17 -21
  99. package/dist/src/render/cursor-emit.d.ts +18 -0
  100. package/dist/src/render/cursor-emit.js +50 -0
  101. package/dist/src/render/diff.d.ts +12 -0
  102. package/dist/src/render/diff.js +120 -0
  103. package/dist/src/render/generation.d.ts +9 -0
  104. package/dist/src/render/generation.js +14 -0
  105. package/dist/src/render/graphics-layer.d.ts +27 -0
  106. package/dist/src/render/graphics-layer.js +86 -0
  107. package/dist/src/render/image.d.ts +27 -0
  108. package/dist/src/render/image.js +113 -0
  109. package/dist/src/render/incremental-paint.d.ts +7 -3
  110. package/dist/src/render/incremental-paint.js +52 -79
  111. package/dist/src/render/inline.d.ts +59 -0
  112. package/dist/src/render/inline.js +219 -0
  113. package/dist/src/render/kitty-graphics.d.ts +24 -0
  114. package/dist/src/render/kitty-graphics.js +58 -0
  115. package/dist/src/render/paint-text.js +68 -22
  116. package/dist/src/render/paint.d.ts +8 -1
  117. package/dist/src/render/paint.js +328 -30
  118. package/dist/src/render/png.d.ts +13 -0
  119. package/dist/src/render/png.js +145 -0
  120. package/dist/src/render/scrollbar.d.ts +8 -2
  121. package/dist/src/render/scrollbar.js +71 -14
  122. package/dist/src/render/snapshot.js +3 -1
  123. package/dist/src/renderer/default.d.ts +7 -0
  124. package/dist/src/renderer/default.js +11 -0
  125. package/dist/src/renderer/index.d.ts +8 -2
  126. package/dist/src/renderer/index.js +4 -2
  127. package/dist/src/renderer/node.d.ts +109 -0
  128. package/dist/src/renderer/node.js +165 -1
  129. package/dist/src/terminal/capabilities.d.ts +33 -0
  130. package/dist/src/terminal/capabilities.js +66 -0
  131. package/dist/src/terminal/clipboard.d.ts +9 -0
  132. package/dist/src/terminal/clipboard.js +39 -0
  133. package/dist/src/terminal/io.d.ts +82 -0
  134. package/dist/src/terminal/io.js +155 -0
  135. package/dist/src/terminal/screen.d.ts +3 -10
  136. package/dist/src/terminal/screen.js +5 -28
  137. package/dist/src/terminal/stdin-router.d.ts +8 -5
  138. package/dist/src/terminal/stdin-router.js +22 -11
  139. package/dist/src/utils/node-map.d.ts +24 -0
  140. package/dist/src/utils/node-map.js +75 -0
  141. package/dist/src/vite/config.d.ts +62 -0
  142. package/dist/src/vite/config.js +191 -0
  143. package/docs/compatibility.md +67 -0
  144. package/docs/debug/devtools.md +40 -0
  145. package/docs/debug/svt.md +50 -0
  146. package/docs/distribution.md +106 -0
  147. package/docs/elements.md +120 -0
  148. package/docs/getting-started.md +177 -0
  149. package/docs/guide/css.md +187 -0
  150. package/docs/guide/input.md +143 -0
  151. package/docs/guide/layout.md +171 -0
  152. package/docs/guide/theming.md +94 -0
  153. package/docs/how-it-works.md +115 -0
  154. package/docs/inline-mode.md +77 -0
  155. package/docs/layout.md +106 -0
  156. package/docs/motion.md +91 -0
  157. package/docs/reference/README.md +65 -0
  158. package/docs/reference/css/properties/border-corner.md +82 -0
  159. package/docs/reference/css/properties/border-style.md +168 -0
  160. package/docs/reference.md +226 -0
  161. package/docs/selectors.md +80 -0
  162. package/docs/terminal-css.md +149 -0
  163. package/docs/terminals.md +83 -0
  164. package/package.json +28 -7
@@ -0,0 +1,99 @@
1
+ /**
2
+ * FrameLog — an append-only log of frames for inline mode. Each frame is
3
+ * a mounted component; archiving hands its rows to the terminal's
4
+ * scrollback and frees the component, so a long session's memory tracks
5
+ * what's live, not the whole history.
6
+ *
7
+ * The host element should be the first content on screen (frames release
8
+ * from the top). To update a frame after append, pass a `$state` object
9
+ * as its props and mutate it — or use `update()`, which assigns onto that
10
+ * same object.
11
+ */
12
+ import { mount, unmount } from 'svelte/renderer';
13
+ import defaultRenderer from './renderer/default.js';
14
+ import { TermNode } from './renderer/node.js';
15
+ const inlineHooksByRoot = new WeakMap();
16
+ /** Called by run() in inline mode so FrameLogs can archive rows. */
17
+ export function registerInlineHooks(root, hooks) {
18
+ inlineHooksByRoot.set(root, hooks);
19
+ }
20
+ export class FrameLog {
21
+ host;
22
+ deps;
23
+ frames = [];
24
+ nextId = 1;
25
+ constructor(host, deps = {
26
+ mount, unmount, renderer: defaultRenderer,
27
+ }) {
28
+ this.host = host;
29
+ this.deps = deps;
30
+ }
31
+ /** Mount a component as a new frame at the bottom of the log. */
32
+ append(component, props) {
33
+ const container = new TermNode('element', 'div');
34
+ container.attributes.set('data-frame', String(this.nextId));
35
+ this.host.insertBefore(container, null);
36
+ const app = this.deps.mount(component, {
37
+ renderer: this.deps.renderer,
38
+ target: container,
39
+ props,
40
+ });
41
+ const id = this.nextId++;
42
+ this.frames.push({ id, container, app, props });
43
+ return id;
44
+ }
45
+ /**
46
+ * Assign new values onto the frame's props object. Reaches the
47
+ * component only when the props were created with `$state`.
48
+ */
49
+ update(id, partial) {
50
+ const frame = this.frames.find(f => f.id === id);
51
+ if (!frame)
52
+ throw new Error(`FrameLog: no live frame ${id}`);
53
+ Object.assign(frame.props, partial);
54
+ }
55
+ /**
56
+ * Archive every frame up to and including `id`: their rows stay on
57
+ * the terminal and scroll into history; their components unmount.
58
+ */
59
+ archive(id) {
60
+ const index = this.frames.findIndex(f => f.id === id);
61
+ if (index < 0)
62
+ throw new Error(`FrameLog: no live frame ${id}`);
63
+ const archived = this.frames.slice(0, index + 1);
64
+ const rows = archived.reduce((sum, frame) => sum + (frame.container.cache.layoutBox?.height ?? 0), 0);
65
+ this.rootHooks()?.releaseTop(rows);
66
+ for (const frame of archived)
67
+ this.dispose(frame);
68
+ this.frames.splice(0, index + 1);
69
+ }
70
+ /** Remove a frame outright — its rows clear and the log reflows. */
71
+ remove(id) {
72
+ const index = this.frames.findIndex(f => f.id === id);
73
+ if (index < 0)
74
+ throw new Error(`FrameLog: no live frame ${id}`);
75
+ this.dispose(this.frames[index]);
76
+ this.frames.splice(index, 1);
77
+ }
78
+ /** IDs of the frames still live, in order. */
79
+ liveFrames() {
80
+ return this.frames.map(f => f.id);
81
+ }
82
+ dispose(frame) {
83
+ this.deps.unmount(frame.app);
84
+ this.host.removeChild(frame.container);
85
+ }
86
+ rootHooks() {
87
+ let node = this.host;
88
+ while (node.parent)
89
+ node = node.parent;
90
+ return inlineHooksByRoot.get(node);
91
+ }
92
+ }
93
+ /**
94
+ * A FrameLog bound to a host element — from a component, grab the node
95
+ * with `bind:this` and create the log once on mount.
96
+ */
97
+ export function createFrameLog(host) {
98
+ return new FrameLog(host);
99
+ }
@@ -1,3 +1,4 @@
1
+ import { mount as svelteMount, unmount as svelteUnmount } from 'svelte/renderer';
1
2
  import { TermNode } from './renderer/index.js';
2
3
  import renderer from './renderer/default.js';
3
4
  import { CellBuffer } from './render/buffer.js';
@@ -5,6 +6,7 @@ import { paint } from './render/paint.js';
5
6
  import { parseCSS } from './css/parser.js';
6
7
  import { resolveStyles } from './css/compute.js';
7
8
  import { computeLayout } from './layout/engine.js';
9
+ import { DEFAULT_STYLESHEET } from './css/defaults.js';
8
10
  /**
9
11
  * Render a Svelte component headlessly (no terminal) for testing.
10
12
  * Returns the cell buffer, virtual tree, and unmount function.
@@ -13,11 +15,17 @@ export function renderHeadless(AppComponent, options = {}) {
13
15
  const width = options.width ?? 80;
14
16
  const height = options.height ?? 24;
15
17
  const root = new TermNode('element', 'root');
16
- const stylesheet = options.css ? parseCSS(options.css) : null;
17
- const { unmount } = renderer.render(AppComponent, { target: root, props: options.props ?? {} });
18
+ const stylesheet = parseCSS(DEFAULT_STYLESHEET + (options.css ?? ''));
19
+ const app = svelteMount(AppComponent, {
20
+ renderer,
21
+ target: root,
22
+ props: options.props ?? {},
23
+ context: new Map([[Symbol.for('@svelterm/target'), 'terminal']]),
24
+ });
25
+ const unmount = () => void svelteUnmount(app);
18
26
  const buffer = new CellBuffer(width, height);
19
- const styles = stylesheet ? resolveStyles(root, stylesheet) : undefined;
20
- const layout = styles ? computeLayout(root, styles, width, height) : undefined;
27
+ const styles = resolveStyles(root, stylesheet);
28
+ const layout = computeLayout(root, styles, width, height);
21
29
  paint(root, buffer, styles, layout);
22
30
  return { buffer, root, unmount };
23
31
  }
@@ -1,18 +1,80 @@
1
1
  import type { Component, ComponentType, SvelteComponent } from 'svelte';
2
- export interface MountOptions {
2
+ import { type ColorDepth } from './terminal/capabilities.js';
3
+ import { type TerminalIO } from './terminal/io.js';
4
+ export interface ConsoleEntry {
5
+ level: 'log' | 'warn' | 'error' | 'info' | 'debug';
6
+ args: string[];
7
+ timestamp: number;
8
+ }
9
+ export interface RunOptions {
3
10
  fullscreen?: boolean;
4
11
  css?: string;
5
12
  mouse?: boolean;
6
13
  debug?: boolean;
7
14
  debugPort?: number;
15
+ io?: TerminalIO;
16
+ onConsole?: (entry: ConsoleEntry) => void;
17
+ /**
18
+ * Override the terminal's color scheme. When set, OSC11 polling is
19
+ * skipped and this value is used directly. Useful for embedded
20
+ * terminals (browser previews) where the OSC channel is meaningless
21
+ * and the host already knows the scheme.
22
+ */
23
+ colorScheme?: 'dark' | 'light';
24
+ /**
25
+ * 'fullscreen' (default) uses the alternate screen buffer. 'inline'
26
+ * renders at the shell cursor in the main buffer: output above the
27
+ * live area scrolls into real scrollback, the live area sizes to its
28
+ * content, and all cursor movement is relative. Mouse events map
29
+ * into the live area via a cursor-position query; clicks on shell
30
+ * history above it are ignored.
31
+ */
32
+ mode?: 'fullscreen' | 'inline';
33
+ /**
34
+ * Key combinations that exit the app. Ctrl+C always exits; add
35
+ * 'ctrl+d' for EOF-style exit. Default: ['ctrl+c'].
36
+ */
37
+ exitOn?: Array<'ctrl+c' | 'ctrl+d'>;
38
+ /**
39
+ * Override colour depth instead of detecting it (NO_COLOR/COLORTERM/
40
+ * XTVERSION). Hex colours quantize to the terminal's palette at emit
41
+ * time; `mono` drops colour output entirely.
42
+ */
43
+ colorDepth?: ColorDepth;
44
+ }
45
+ /** @deprecated Use RunOptions */
46
+ export type MountOptions = RunOptions;
47
+ export interface RunHandle {
48
+ /** Tear down the run — restore stdio, unmount components, stop pollers. */
49
+ cleanup: () => void;
50
+ /**
51
+ * Update the active color scheme on a live run. Triggers a full repaint
52
+ * so default-colored cells render with the new defaults and CSS @media
53
+ * (color-scheme: ...) rules re-resolve. No-op if the scheme is unchanged.
54
+ *
55
+ * Calling this also stops any background OSC-11 polling — the caller is
56
+ * declaring they own the scheme, and we don't want the poller racing to
57
+ * overwrite it 1s later.
58
+ */
59
+ setColorScheme: (scheme: 'dark' | 'light') => void;
8
60
  }
9
- export declare function run<Props extends Record<string, any>>(AppComponent: ComponentType<SvelteComponent<Props>> | Component<Props>, options?: MountOptions & ({} extends Props ? {
61
+ /**
62
+ * Register a component's extracted CSS before run() is called. Bundled
63
+ * builds (`svelterm build`) and the dev-mode transform append a
64
+ * registration call to each compiled component so it carries its styles;
65
+ * run() falls back to the registry when no `css` option is given.
66
+ */
67
+ export declare function registerComponentCss(css: string): void;
68
+ export declare function run<Props extends Record<string, any>>(AppComponent: ComponentType<SvelteComponent<Props>> | Component<Props>, options?: RunOptions & ({} extends Props ? {
10
69
  props?: Props;
11
70
  } : {
12
71
  props: Props;
13
- })): () => void;
72
+ })): RunHandle;
14
73
  export { TermNode } from './renderer/node.js';
15
74
  export { CellBuffer } from './render/buffer.js';
16
75
  export { parseCSS } from './css/parser.js';
17
76
  export { resolveStyles } from './css/compute.js';
18
77
  export { StdinRouter } from './terminal/stdin-router.js';
78
+ export { type TerminalIO, ProcessIO, InProcessIO } from './terminal/io.js';
79
+ export { copyToClipboard, osc52Copy } from './terminal/clipboard.js';
80
+ export { FrameLog, createFrameLog } from './framelog.js';