@opentui/core 0.4.4 → 0.5.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 (56) hide show
  1. package/README.md +4 -4
  2. package/Renderable.d.ts +3 -0
  3. package/audio.d.ts +202 -1
  4. package/buffer.d.ts +3 -0
  5. package/chunk-bun-ctxxvhwz.js +17416 -0
  6. package/chunk-bun-ctxxvhwz.js.map +62 -0
  7. package/chunk-bun-v3e63tzw.js +10157 -0
  8. package/chunk-bun-v3e63tzw.js.map +32 -0
  9. package/{index-7z5n7k9m.js → chunk-node-1j69hr31.js} +147 -37
  10. package/chunk-node-1j69hr31.js.map +32 -0
  11. package/{index-za1krqsf.js → chunk-node-savhj5rp.js} +1594 -467
  12. package/chunk-node-savhj5rp.js.map +61 -0
  13. package/image.d.ts +105 -0
  14. package/index.bun.js +15128 -0
  15. package/index.bun.js.map +41 -0
  16. package/index.d.ts +2 -0
  17. package/{index.js → index.node.js} +2134 -90
  18. package/{index.js.map → index.node.js.map} +40 -5
  19. package/lib/env.d.ts +1 -0
  20. package/lib/stdin-parser.d.ts +5 -0
  21. package/lib/tree-sitter/default-parser-assets.bun.d.ts +1 -0
  22. package/lib/tree-sitter/default-parsers.d.ts +1 -0
  23. package/lib/tree-sitter/parsers-config.d.ts +2 -2
  24. package/lib/tree-sitter/types.d.ts +1 -0
  25. package/lib/tree-sitter/update-assets.js +124 -58
  26. package/lib/tree-sitter/update-assets.js.map +3 -3
  27. package/node-asset-target.d.ts +12 -0
  28. package/node-assets.d.ts +7 -0
  29. package/node-assets.js +264 -0
  30. package/node-assets.js.map +16 -0
  31. package/package.json +24 -14
  32. package/parser.worker.js +3353 -188
  33. package/parser.worker.js.map +18 -12
  34. package/platform/assets.d.ts +5 -0
  35. package/platform/ffi.d.ts +2 -0
  36. package/platform/runtime-assets.bun.d.ts +4 -0
  37. package/platform/runtime-assets.node.d.ts +4 -0
  38. package/platform/runtime.d.ts +5 -1
  39. package/renderables/Image.d.ts +44 -0
  40. package/renderables/index.d.ts +1 -0
  41. package/renderer.d.ts +14 -0
  42. package/runtime-plugin.js +2 -2
  43. package/runtime-plugin.js.map +1 -1
  44. package/testing.bun.js +1006 -0
  45. package/testing.bun.js.map +18 -0
  46. package/testing.js +4 -3
  47. package/testing.js.map +3 -3
  48. package/text-buffer-view.d.ts +2 -5
  49. package/types.d.ts +8 -0
  50. package/yoga.bun.js +194 -0
  51. package/yoga.bun.js.map +9 -0
  52. package/yoga.js +1 -1
  53. package/zig-structs.d.ts +45 -24
  54. package/zig.d.ts +70 -7
  55. package/index-7z5n7k9m.js.map +0 -32
  56. package/index-za1krqsf.js.map +0 -58
package/README.md CHANGED
@@ -4,11 +4,11 @@ OpenTUI is a native terminal UI core written in Zig with TypeScript bindings. Th
4
4
 
5
5
  ## Documentation
6
6
 
7
- - [Getting Started](docs/getting-started.md) - API and usage guide
7
+ - [Getting Started](https://opentui.com/docs/getting-started) - API and usage guide
8
8
  - [Development Guide](docs/development.md) - Building, testing, and contributing
9
- - [Tree-Sitter](docs/tree-sitter.md) - Syntax highlighting integration
10
- - [Renderables vs Constructs](docs/renderables-vs-constructs.md) - Understanding the component model
11
- - [Environment Variables](docs/env-vars.md) - Configuration options
9
+ - [Tree-Sitter](https://opentui.com/docs/reference/tree-sitter) - Syntax highlighting integration
10
+ - [Renderables vs Constructs](https://opentui.com/docs/core-concepts/renderables-vs-constructs) - Understanding the component model
11
+ - [Environment Variables](https://opentui.com/docs/reference/env-vars) - Configuration options
12
12
 
13
13
  ## Install
14
14
 
package/Renderable.d.ts CHANGED
@@ -332,10 +332,13 @@ interface RenderCommandPopOpacity extends RenderCommandBase {
332
332
  export type RenderCommand = RenderCommandPushScissorRect | RenderCommandPopScissorRect | RenderCommandRender | RenderCommandPushOpacity | RenderCommandPopOpacity;
333
333
  export declare class RootRenderable extends Renderable {
334
334
  private renderList;
335
+ private _currentRenderable;
335
336
  private appliedLayoutGeneration;
336
337
  private appliedRenderListRevision;
337
338
  private renderListReusable;
338
339
  constructor(ctx: RenderContext);
340
+ get currentRenderable(): Renderable | undefined;
341
+ takeCurrentRenderable(): Renderable | undefined;
339
342
  render(buffer: OptimizedBuffer, deltaTime: number): void;
340
343
  protected propagateLiveCount(delta: number): void;
341
344
  calculateLayout(): void;
package/audio.d.ts CHANGED
@@ -151,7 +151,68 @@ export interface AudioPlaybackDevice {
151
151
  name: string;
152
152
  isDefault: boolean;
153
153
  }
154
- export type AudioAction = "createAudioEngine" | "start" | "startMixer" | "stop" | "loadSound" | "loadSoundFile" | "unloadSound" | "group" | "play" | "stopVoice" | "setVoiceGroup" | "setGroupVolume" | "setMasterVolume" | "mixFrames" | "enableTap" | "readTapFrames" | "listPlaybackDevices" | "selectPlaybackDevice" | "clearPlaybackDeviceSelection" | "getStats";
154
+ export interface AudioCaptureDevice {
155
+ index: number;
156
+ name: string;
157
+ isDefault: boolean;
158
+ }
159
+ export interface AudioCaptureOptions {
160
+ channels?: number;
161
+ capacityFrames?: number;
162
+ startOptions?: AudioStartOptions;
163
+ }
164
+ export interface AudioCaptureStreamOptions extends AudioCaptureOptions {
165
+ chunkFrames?: number;
166
+ signal?: AbortSignal;
167
+ }
168
+ export type AudioCaptureStreamState = "initializing" | "capturing" | "stopping" | "stopped" | "errored" | "disposed";
169
+ export type AudioCaptureStreamAction = "start" | "read" | "stop" | "stats" | "destroy";
170
+ export interface AudioCaptureStreamErrorContext {
171
+ action: AudioCaptureStreamAction;
172
+ status?: number;
173
+ }
174
+ export interface AudioCaptureStreamEvents {
175
+ stopped: [];
176
+ error: [error: AudioCaptureStreamError, context: AudioCaptureStreamErrorContext];
177
+ disposed: [];
178
+ }
179
+ export interface AudioCaptureStats {
180
+ sampleRate: number;
181
+ channels: number;
182
+ capacityFrames: number;
183
+ bufferedFrames: number;
184
+ framesReceived: bigint;
185
+ framesRead: bigint;
186
+ framesDropped: bigint;
187
+ }
188
+ export interface AudioCaptureStreamStats extends AudioCaptureStats {
189
+ state: AudioCaptureStreamState;
190
+ bufferedDurationMs: number;
191
+ }
192
+ export interface AudioCaptureReadResult {
193
+ frames: Float32Array;
194
+ framesRead: number;
195
+ }
196
+ export type AudioRecordToFileOptions = AudioCaptureStreamOptions;
197
+ export type AudioRecorderState = "initializing" | "recording" | "stopping" | "stopped" | "errored" | "disposed";
198
+ export type AudioRecorderAction = "open" | "start" | "read" | "write" | "stop" | "finalize" | "publish" | "stats" | "destroy";
199
+ export interface AudioRecorderErrorContext {
200
+ action: AudioRecorderAction;
201
+ status?: number;
202
+ }
203
+ export interface AudioRecorderEvents {
204
+ stopped: [];
205
+ error: [error: AudioRecorderError, context: AudioRecorderErrorContext];
206
+ disposed: [];
207
+ }
208
+ export interface AudioRecorderStats extends AudioCaptureStats {
209
+ state: AudioRecorderState;
210
+ bufferedDurationMs: number;
211
+ framesWritten: bigint;
212
+ dataBytesWritten: bigint;
213
+ durationMs: number;
214
+ }
215
+ export type AudioAction = "createAudioEngine" | "start" | "startMixer" | "stop" | "loadSound" | "loadSoundFile" | "unloadSound" | "group" | "play" | "stopVoice" | "setVoiceGroup" | "setGroupVolume" | "setMasterVolume" | "mixFrames" | "enableTap" | "readTapFrames" | "listPlaybackDevices" | "selectPlaybackDevice" | "clearPlaybackDeviceSelection" | "listCaptureDevices" | "selectCaptureDevice" | "clearCaptureDeviceSelection" | "startCapture" | "readCaptureFrames" | "getCaptureStats" | "stopCapture" | "getStats";
155
216
  export interface AudioErrorContext {
156
217
  action: AudioAction;
157
218
  status?: number;
@@ -160,6 +221,8 @@ export interface AudioEvents {
160
221
  error: [error: Error, context: AudioErrorContext];
161
222
  started: [];
162
223
  mixerStarted: [];
224
+ captureStarted: [];
225
+ captureStopped: [];
163
226
  stopped: [];
164
227
  disposed: [];
165
228
  }
@@ -169,6 +232,14 @@ export declare class AudioInitializationError extends Error {
169
232
  readonly status?: number;
170
233
  constructor(action: AudioInitializationAction, message: string, status?: number, cause?: unknown);
171
234
  }
235
+ export declare class AudioCaptureStreamError extends Error {
236
+ readonly context: AudioCaptureStreamErrorContext;
237
+ constructor(message: string, context: AudioCaptureStreamErrorContext, cause?: unknown);
238
+ }
239
+ export declare class AudioRecorderError extends Error {
240
+ readonly context: AudioRecorderErrorContext;
241
+ constructor(message: string, context: AudioRecorderErrorContext, cause?: unknown);
242
+ }
172
243
  export declare class AudioStreamError extends Error {
173
244
  readonly context: AudioStreamErrorContext;
174
245
  constructor(message: string, context: AudioStreamErrorContext, cause?: unknown);
@@ -241,6 +312,113 @@ export declare class AudioStream<M = AudioStreamMetadata> extends EventEmitter<A
241
312
  private toPublicStats;
242
313
  private removeOwner;
243
314
  }
315
+ export declare class AudioCaptureStream extends EventEmitter<AudioCaptureStreamEvents> {
316
+ readonly readable: ReadableStream<Float32Array>;
317
+ readonly sampleRate: number;
318
+ readonly channels: number;
319
+ readonly chunkFrames: number;
320
+ readonly closed: Promise<void>;
321
+ private readonly init;
322
+ private readonly lifecycleController;
323
+ private streamController;
324
+ private nativeStats;
325
+ private currentState;
326
+ private pendingFrames;
327
+ private readonly pendingSamples;
328
+ private producerStopAttempted;
329
+ private producerStopped;
330
+ private producerMayBeRunning;
331
+ private ownerRemoved;
332
+ private exposed;
333
+ private terminal;
334
+ private discardRequested;
335
+ private discardDecisionScheduled;
336
+ private pumpPromise;
337
+ private producerCleanupPromise;
338
+ private lastCleanupFailure;
339
+ private terminalCompletionPromise;
340
+ private closedResolve;
341
+ private readonly signalAbortListener;
342
+ private constructor();
343
+ get state(): AudioCaptureStreamState;
344
+ private open;
345
+ getStats(): AudioCaptureStreamStats;
346
+ stop(): void;
347
+ dispose(): void;
348
+ private disposeInternal;
349
+ private pull;
350
+ private pump;
351
+ private pumpSource;
352
+ private discardNativeRing;
353
+ private requestDiscardDrain;
354
+ private scheduleDiscardIfIdle;
355
+ private refreshStats;
356
+ private observeProducer;
357
+ private stopProducer;
358
+ private finishStopped;
359
+ private fail;
360
+ private operationError;
361
+ private cleanupProducer;
362
+ private retryTerminalCleanup;
363
+ private publicStats;
364
+ private refreshFinalStats;
365
+ private removeOwner;
366
+ private emitTerminal;
367
+ }
368
+ export declare class AudioRecorder extends EventEmitter<AudioRecorderEvents> {
369
+ private static readonly fileSystem;
370
+ readonly filePath: string;
371
+ readonly format: "wav";
372
+ readonly sampleRate: number;
373
+ readonly channels: number;
374
+ readonly closed: Promise<void>;
375
+ private readonly init;
376
+ private currentState;
377
+ private capture;
378
+ private reader;
379
+ private fileHandle;
380
+ private tempPath;
381
+ private captureStats;
382
+ private framesWritten;
383
+ private dataBytesWritten;
384
+ private stopRequested;
385
+ private terminal;
386
+ private terminationRequest;
387
+ private publicationStarted;
388
+ private exposed;
389
+ private ownerRemoved;
390
+ private cleanupPromise;
391
+ private resourceCleanupPromise;
392
+ private retainedCleanupScheduled;
393
+ private lifecyclePromise;
394
+ private closedResolve;
395
+ private readonly signalAbortListener;
396
+ private readonly captureErrorListener;
397
+ private constructor();
398
+ get state(): AudioRecorderState;
399
+ private open;
400
+ getStats(): AudioRecorderStats;
401
+ stop(): void;
402
+ dispose(): void;
403
+ private consume;
404
+ private writeSamples;
405
+ private readWithStats;
406
+ private complete;
407
+ private publish;
408
+ private fail;
409
+ private requestTermination;
410
+ private finishCleanup;
411
+ private cleanupOwnedResources;
412
+ private retryRetainedCleanup;
413
+ private scheduleRetainedCleanup;
414
+ private hasRetainedResources;
415
+ private openTemporaryFile;
416
+ private writeFully;
417
+ private ensureOpening;
418
+ private fromCaptureError;
419
+ private removeOwner;
420
+ private emitTerminal;
421
+ }
244
422
  export declare class Audio extends EventEmitter<AudioEvents> {
245
423
  static create(options?: AudioSetupOptions): Audio;
246
424
  readonly sampleRate: number;
@@ -251,6 +429,13 @@ export declare class Audio extends EventEmitter<AudioEvents> {
251
429
  private readonly streams;
252
430
  private playbackStarted;
253
431
  private mixerStarted;
432
+ private captureStarted;
433
+ private captureDeviceOpen;
434
+ private captureBufferAvailable;
435
+ private captureChannels;
436
+ private captureCapacityFrames;
437
+ private captureOwner;
438
+ private captureStream;
254
439
  private disposing;
255
440
  private constructor();
256
441
  private throwAfterInitializationCleanup;
@@ -283,6 +468,22 @@ export declare class Audio extends EventEmitter<AudioEvents> {
283
468
  listPlaybackDevices(): AudioPlaybackDevice[] | null;
284
469
  selectPlaybackDevice(index: number): boolean;
285
470
  clearPlaybackDeviceSelection(): void;
471
+ openCapture(options?: AudioCaptureStreamOptions): Promise<AudioCaptureStream>;
472
+ recordToFile(filePath: string, options?: AudioRecordToFileOptions): Promise<AudioRecorder>;
473
+ listCaptureDevices(): AudioCaptureDevice[] | null;
474
+ selectCaptureDevice(index: number): boolean;
475
+ clearCaptureDeviceSelection(): void;
476
+ startCapture(options?: AudioCaptureOptions): boolean;
477
+ isCapturing(): boolean;
478
+ private isCapturingInternal;
479
+ readCaptureFrames(frameCount: number): AudioCaptureReadResult | null;
480
+ getCaptureStats(): AudioCaptureStats | null;
481
+ stopCapture(): boolean;
482
+ private emitCaptureOwnershipError;
483
+ private startCaptureInternal;
484
+ private readCaptureInternal;
485
+ private getCaptureStatsInternal;
486
+ private stopCaptureInternal;
286
487
  getStats(): AudioStats | null;
287
488
  dispose(): void;
288
489
  }
package/buffer.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { RGBA } from "./lib/index.js";
2
2
  import { type OptimizedBufferHandle, type RenderLib } from "./zig.js";
3
3
  import { type Pointer, type PointerInput } from "./platform/ffi.js";
4
+ import type { NativeImage } from "./image.js";
5
+ import type { ImageRenderProtocol } from "./types.js";
4
6
  import { type BorderStyle, type BorderSides } from "./lib/index.js";
5
7
  import { TargetChannel, type WidthMethod, type CapturedLine } from "./types.js";
6
8
  import type { TextBufferView } from "./text-buffer-view.js";
@@ -58,6 +60,7 @@ export declare class OptimizedBuffer {
58
60
  drawTextBuffer(textBufferView: TextBufferView, x: number, y: number): void;
59
61
  drawEditorView(editorView: EditorView, x: number, y: number): void;
60
62
  drawSuperSampleBuffer(x: number, y: number, pixelDataPtr: PointerInput, pixelDataLength: number, format: "bgra8unorm" | "rgba8unorm", alignedBytesPerRow: number): void;
63
+ drawImage(image: NativeImage, x: number, y: number, width: number, height: number, pixelWidth?: number, pixelHeight?: number, sourceX?: number, sourceY?: number, sourceWidth?: number, sourceHeight?: number, protocol?: ImageRenderProtocol): boolean;
61
64
  drawPackedBuffer(dataPtr: PointerInput, dataLen: number, posX: number, posY: number, terminalWidthCells: number, terminalHeightCells: number): void;
62
65
  drawGrayscaleBuffer(posX: number, posY: number, intensities: Float32Array, srcWidth: number, srcHeight: number, fg?: RGBA | null, bg?: RGBA | null): void;
63
66
  drawGrayscaleBufferSupersampled(posX: number, posY: number, intensities: Float32Array, srcWidth: number, srcHeight: number, fg?: RGBA | null, bg?: RGBA | null): void;