feat: refactored PhotonImage API to instance methods with simplified naming
- Refactored PhotonImage API from standalone functions to instance methods with simplified naming conventions. - Renamed PhotonImage.new_from_byteslice() to parse() for a simpler, more intuitive factory method API. - Converted PhotonImage.get_width() and get_height() methods to width and height getter properties. - Consolidated four separate encoding methods (getBytes, getBytesJpeg, getBytesWebp, getBytesGif) into a single encode(format, quality) method. - Moved resize() from a standalone function to a PhotonImage instance method. - Added ImageFormat enum to specify encoding formats (PNG, JPEG, WEBP, GIF) in the encode method. - Removed manual resource management via free() and Symbol.dispose, simplifying PhotonImage lifecycle.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
//! Provides only the subset of functionality needed:
|
||||
//! - Load image from bytes (PNG, JPEG, WebP, GIF)
|
||||
//! - Get dimensions
|
||||
//! - Resize with Lanczos3 filter
|
||||
//! - Resize with configurable filter
|
||||
//! - Export as PNG, JPEG, WebP, or GIF
|
||||
|
||||
use std::{io::Cursor, sync::Arc};
|
||||
@@ -38,7 +38,7 @@ impl From<SamplingFilter> for FilterType {
|
||||
}
|
||||
}
|
||||
|
||||
/// Image container for native interop. Stores image directly (no Arc overhead).
|
||||
/// Image container for native interop.
|
||||
#[napi]
|
||||
pub struct PhotonImage {
|
||||
img: Arc<DynamicImage>,
|
||||
@@ -51,8 +51,8 @@ impl PhotonImage {
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error if the image format cannot be detected or decoded.
|
||||
#[napi(factory, js_name = "newFromByteslice")]
|
||||
pub async fn new_from_byteslice(bytes: Uint8Array) -> Result<Self> {
|
||||
#[napi(factory, js_name = "parse")]
|
||||
pub async fn parse(bytes: Uint8Array) -> Result<Self> {
|
||||
let bytes = bytes.as_ref().to_vec();
|
||||
let img = spawn_blocking(move || -> Result<DynamicImage> {
|
||||
let reader = ImageReader::new(Cursor::new(bytes))
|
||||
@@ -72,92 +72,33 @@ impl PhotonImage {
|
||||
}
|
||||
|
||||
/// Get the width of the image.
|
||||
#[napi(js_name = "getWidth")]
|
||||
#[napi(getter, js_name = "width")]
|
||||
pub fn get_width(&self) -> u32 {
|
||||
self.img.width()
|
||||
}
|
||||
|
||||
/// Get the height of the image.
|
||||
#[napi(js_name = "getHeight")]
|
||||
#[napi(getter, js_name = "height")]
|
||||
pub fn get_height(&self) -> u32 {
|
||||
self.img.height()
|
||||
}
|
||||
|
||||
/// Export image as PNG bytes.
|
||||
/// Encode image to bytes in the specified format.
|
||||
///
|
||||
/// Format values (matching `ImageFormat` enum in TS):
|
||||
/// - 0: PNG (quality ignored)
|
||||
/// - 1: JPEG (quality 0-100)
|
||||
/// - 2: WebP (lossless, quality ignored)
|
||||
/// - 3: GIF (quality ignored)
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error if PNG encoding fails.
|
||||
#[napi(js_name = "getBytes")]
|
||||
pub async fn get_bytes(&self) -> Result<Uint8Array> {
|
||||
/// Returns an error if encoding fails or format is invalid.
|
||||
#[napi(js_name = "encode")]
|
||||
pub async fn encode(&self, format: u8, quality: u8) -> Result<Uint8Array> {
|
||||
let img = Arc::clone(&self.img);
|
||||
let capacity = (img.width() * img.height() * 4) as usize;
|
||||
let buffer = spawn_blocking(move || -> Result<Vec<u8>> {
|
||||
let mut buffer = Vec::with_capacity(capacity);
|
||||
img.write_to(&mut Cursor::new(&mut buffer), ImageFormat::Png)
|
||||
.map_err(|e| Error::from_reason(format!("Failed to encode PNG: {e}")))?;
|
||||
Ok(buffer)
|
||||
})
|
||||
.await
|
||||
.map_err(|e| Error::from_reason(format!("PNG encode task failed: {e}")))??;
|
||||
Ok(Uint8Array::from(buffer))
|
||||
}
|
||||
|
||||
/// Export image as JPEG bytes with specified quality (0-100).
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error if JPEG encoding fails.
|
||||
#[napi(js_name = "getBytesJpeg")]
|
||||
pub async fn get_bytes_jpeg(&self, quality: u8) -> Result<Uint8Array> {
|
||||
let img = Arc::clone(&self.img);
|
||||
let capacity = (img.width() * img.height() * 3) as usize;
|
||||
let buffer = spawn_blocking(move || -> Result<Vec<u8>> {
|
||||
let mut buffer = Vec::with_capacity(capacity);
|
||||
let encoder = JpegEncoder::new_with_quality(&mut buffer, quality);
|
||||
img.write_with_encoder(encoder)
|
||||
.map_err(|e| Error::from_reason(format!("Failed to encode JPEG: {e}")))?;
|
||||
Ok(buffer)
|
||||
})
|
||||
.await
|
||||
.map_err(|e| Error::from_reason(format!("JPEG encode task failed: {e}")))??;
|
||||
Ok(Uint8Array::from(buffer))
|
||||
}
|
||||
|
||||
/// Export image as lossless WebP bytes.
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error if WebP encoding fails.
|
||||
#[napi(js_name = "getBytesWebp")]
|
||||
pub async fn get_bytes_webp(&self) -> Result<Uint8Array> {
|
||||
let img = Arc::clone(&self.img);
|
||||
let capacity = (img.width() * img.height() * 4) as usize;
|
||||
let buffer = spawn_blocking(move || -> Result<Vec<u8>> {
|
||||
let mut buffer = Vec::with_capacity(capacity);
|
||||
let encoder = WebPEncoder::new_lossless(&mut buffer);
|
||||
img.write_with_encoder(encoder)
|
||||
.map_err(|e| Error::from_reason(format!("Failed to encode WebP: {e}")))?;
|
||||
Ok(buffer)
|
||||
})
|
||||
.await
|
||||
.map_err(|e| Error::from_reason(format!("WebP encode task failed: {e}")))??;
|
||||
Ok(Uint8Array::from(buffer))
|
||||
}
|
||||
|
||||
/// Export image as GIF bytes.
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error if GIF encoding fails.
|
||||
#[napi(js_name = "getBytesGif")]
|
||||
pub async fn get_bytes_gif(&self) -> Result<Uint8Array> {
|
||||
let img = Arc::clone(&self.img);
|
||||
let capacity = (img.width() * img.height()) as usize;
|
||||
let buffer = spawn_blocking(move || -> Result<Vec<u8>> {
|
||||
let mut buffer = Vec::with_capacity(capacity);
|
||||
img.write_to(&mut Cursor::new(&mut buffer), ImageFormat::Gif)
|
||||
.map_err(|e| Error::from_reason(format!("Failed to encode GIF: {e}")))?;
|
||||
Ok(buffer)
|
||||
})
|
||||
.await
|
||||
.map_err(|e| Error::from_reason(format!("GIF encode task failed: {e}")))??;
|
||||
let buffer = spawn_blocking(move || encode_image(&img, format, quality))
|
||||
.await
|
||||
.map_err(|e| Error::from_reason(format!("Encode task failed: {e}")))??;
|
||||
Ok(Uint8Array::from(buffer))
|
||||
}
|
||||
|
||||
@@ -171,3 +112,37 @@ impl PhotonImage {
|
||||
Ok(Self { img: Arc::new(resized) })
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_image(img: &DynamicImage, format: u8, quality: u8) -> Result<Vec<u8>> {
|
||||
let (w, h) = (img.width(), img.height());
|
||||
|
||||
match format {
|
||||
0 => {
|
||||
let mut buffer = Vec::with_capacity((w * h * 4) as usize);
|
||||
img.write_to(&mut Cursor::new(&mut buffer), ImageFormat::Png)
|
||||
.map_err(|e| Error::from_reason(format!("Failed to encode PNG: {e}")))?;
|
||||
Ok(buffer)
|
||||
},
|
||||
1 => {
|
||||
let mut buffer = Vec::with_capacity((w * h * 3) as usize);
|
||||
let encoder = JpegEncoder::new_with_quality(&mut buffer, quality);
|
||||
img.write_with_encoder(encoder)
|
||||
.map_err(|e| Error::from_reason(format!("Failed to encode JPEG: {e}")))?;
|
||||
Ok(buffer)
|
||||
},
|
||||
2 => {
|
||||
let mut buffer = Vec::with_capacity((w * h * 4) as usize);
|
||||
let encoder = WebPEncoder::new_lossless(&mut buffer);
|
||||
img.write_with_encoder(encoder)
|
||||
.map_err(|e| Error::from_reason(format!("Failed to encode WebP: {e}")))?;
|
||||
Ok(buffer)
|
||||
},
|
||||
3 => {
|
||||
let mut buffer = Vec::with_capacity((w * h) as usize);
|
||||
img.write_to(&mut Cursor::new(&mut buffer), ImageFormat::Gif)
|
||||
.map_err(|e| Error::from_reason(format!("Failed to encode GIF: {e}")))?;
|
||||
Ok(buffer)
|
||||
},
|
||||
_ => Err(Error::from_reason(format!("Invalid image format: {format}"))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { PhotonImage } from "@oh-my-pi/pi-natives";
|
||||
import { ImageFormat } from "@oh-my-pi/pi-natives/native";
|
||||
|
||||
/**
|
||||
* Convert image to PNG format for terminal display.
|
||||
@@ -14,8 +15,8 @@ export async function convertToPng(
|
||||
}
|
||||
|
||||
try {
|
||||
using image = await PhotonImage.new_from_byteslice(new Uint8Array(Buffer.from(base64Data, "base64")));
|
||||
const pngBuffer = await image.get_bytes();
|
||||
const image = await PhotonImage.parse(new Uint8Array(Buffer.from(base64Data, "base64")));
|
||||
const pngBuffer = await image.encode(ImageFormat.PNG, 100);
|
||||
return {
|
||||
data: Buffer.from(pngBuffer).toString("base64"),
|
||||
mimeType: "image/png",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
||||
import { PhotonImage, resize, SamplingFilter } from "@oh-my-pi/pi-natives";
|
||||
import { PhotonImage, SamplingFilter } from "@oh-my-pi/pi-natives";
|
||||
import { ImageFormat } from "@oh-my-pi/pi-natives/native";
|
||||
|
||||
export interface ImageResizeOptions {
|
||||
maxWidth?: number; // Default: 2000
|
||||
@@ -54,10 +55,10 @@ export async function resizeImage(img: ImageContent, options?: ImageResizeOption
|
||||
const inputBuffer = Buffer.from(img.data, "base64");
|
||||
|
||||
try {
|
||||
using image = await PhotonImage.new_from_byteslice(new Uint8Array(inputBuffer));
|
||||
const image = await PhotonImage.parse(inputBuffer);
|
||||
|
||||
const originalWidth = image.get_width();
|
||||
const originalHeight = image.get_height();
|
||||
const originalWidth = image.width;
|
||||
const originalHeight = image.height;
|
||||
const format = img.mimeType?.split("/")[1] ?? "png";
|
||||
|
||||
// Check if already within all limits (dimensions AND size)
|
||||
@@ -91,11 +92,14 @@ export async function resizeImage(img: ImageContent, options?: ImageResizeOption
|
||||
async function tryBothFormats(
|
||||
width: number,
|
||||
height: number,
|
||||
jpegQuality: number,
|
||||
quality: number,
|
||||
): Promise<{ buffer: Uint8Array; mimeType: string }> {
|
||||
using resized = await resize(image!, width, height, SamplingFilter.Lanczos3);
|
||||
const resized = await image.resize(width, height, SamplingFilter.Lanczos3);
|
||||
|
||||
const [pngBuffer, jpegBuffer] = await Promise.all([resized.get_bytes(), resized.get_bytes_jpeg(jpegQuality)]);
|
||||
const [pngBuffer, jpegBuffer] = await Promise.all([
|
||||
resized.encode(ImageFormat.PNG, quality),
|
||||
resized.encode(ImageFormat.JPEG, quality),
|
||||
]);
|
||||
|
||||
return pickSmaller(
|
||||
{ buffer: pngBuffer, mimeType: "image/png" },
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
### Breaking Changes
|
||||
|
||||
- Removed `resize()` function; use `PhotonImage.resize()` method instead
|
||||
- Removed `terminateImageWorker()` function
|
||||
- Changed `PhotonImage.new_from_byteslice()` to `PhotonImage.parse()`
|
||||
- Changed `PhotonImage.get_bytes()` to `encode(ImageFormat.PNG, 100)`
|
||||
- Changed `PhotonImage.get_bytes_jpeg(quality)` to `encode(ImageFormat.JPEG, quality)`
|
||||
- Removed `get_width()` and `get_height()` methods; use `width` and `height` properties instead
|
||||
- Removed manual resource management via `free()` and `Symbol.dispose`
|
||||
|
||||
### Added
|
||||
|
||||
- Added `sessionEnv` option to `ShellExecuteOptions` for setting environment variables once per session
|
||||
- Added `sessionKey` option to `ShellExecuteOptions` for managing persistent brush shell instances
|
||||
- Added `snapshotPath` option to `ShellExecuteOptions` to source bash session snapshots
|
||||
- Added `ImageFormat` enum for specifying output format (PNG, JPEG, WEBP, GIF) in `encode()` method
|
||||
- Added `SamplingFilter` as exported enum instead of object
|
||||
- Added `Shell` class with persistent session options (`sessionEnv`, `snapshotPath`) and a `run()` command API
|
||||
- Exported `getSystemInfo()` function and `SystemInfo` type for retrieving system information including distro, kernel, CPU, and disk details
|
||||
- Exported `copyToClipboard()` and `readImageFromClipboard()` functions for clipboard operations
|
||||
- Exported `ClipboardImage` type for clipboard image data with MIME type information
|
||||
@@ -15,7 +24,8 @@
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated `env` option documentation in `ShellExecuteOptions` to clarify it applies variables for the current command only
|
||||
- Changed `PhotonImage` API to use instance methods (`resize()`, `encode()`) instead of standalone functions
|
||||
- Changed `PhotonImage` to use property accessors for `width` and `height` instead of getter methods
|
||||
|
||||
## [9.7.0] - 2026-02-01
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Native Rust functionality via N-API.
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
import { grep, find, PhotonImage, resize, SamplingFilter } from "@oh-my-pi/pi-natives";
|
||||
import { grep, find, PhotonImage, SamplingFilter, ImageFormat } from "@oh-my-pi/pi-natives";
|
||||
|
||||
// Grep for a pattern
|
||||
const results = await grep({
|
||||
@@ -29,9 +29,9 @@ const files = await find({
|
||||
});
|
||||
|
||||
// Image processing
|
||||
using image = await PhotonImage.new_from_byteslice(bytes);
|
||||
using resized = await resize(image, 800, 600, SamplingFilter.Lanczos3);
|
||||
const pngBytes = await resized.get_bytes();
|
||||
const image = await PhotonImage.parse(bytes);
|
||||
const resized = await image.resize(800, 600, SamplingFilter.Lanczos3);
|
||||
const pngBytes = await resized.encode(ImageFormat.PNG, 100);
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
@@ -2,112 +2,8 @@
|
||||
* Image processing via native bindings.
|
||||
*/
|
||||
|
||||
import { type NativePhotonImage, native } from "../native";
|
||||
import { native, SamplingFilter } from "../native";
|
||||
|
||||
const images = new Map<number, NativePhotonImage>();
|
||||
let nextHandle = 1;
|
||||
const { PhotonImage } = native;
|
||||
|
||||
function registerImage(image: NativePhotonImage): number {
|
||||
const handle = nextHandle++;
|
||||
images.set(handle, image);
|
||||
return handle;
|
||||
}
|
||||
|
||||
function getImage(handle: number): NativePhotonImage {
|
||||
const image = images.get(handle);
|
||||
if (!image) {
|
||||
throw new Error("Image already freed");
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
export const SamplingFilter = native.SamplingFilter;
|
||||
export type SamplingFilter = (typeof SamplingFilter)[keyof typeof SamplingFilter];
|
||||
|
||||
/**
|
||||
* Image handle for async operations.
|
||||
*/
|
||||
export class PhotonImage {
|
||||
#handle: number;
|
||||
#freed = false;
|
||||
|
||||
private constructor(handle: number) {
|
||||
this.#handle = handle;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
static _create(handle: number): PhotonImage {
|
||||
if (!images.has(handle)) {
|
||||
throw new Error("Invalid image handle");
|
||||
}
|
||||
return new PhotonImage(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an image from encoded bytes (PNG, JPEG, WebP, GIF).
|
||||
*/
|
||||
static async new_from_byteslice(bytes: Uint8Array): Promise<PhotonImage> {
|
||||
const image = await native.PhotonImage.newFromByteslice(bytes);
|
||||
const handle = registerImage(image);
|
||||
return new PhotonImage(handle);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_getHandle(): number {
|
||||
if (this.#freed) throw new Error("Image already freed");
|
||||
return this.#handle;
|
||||
}
|
||||
|
||||
#native(): NativePhotonImage {
|
||||
if (this.#freed) throw new Error("Image already freed");
|
||||
return getImage(this.#handle);
|
||||
}
|
||||
|
||||
/** Get image width in pixels. */
|
||||
get_width(): number {
|
||||
return this.#native().getWidth();
|
||||
}
|
||||
|
||||
/** Get image height in pixels. */
|
||||
get_height(): number {
|
||||
return this.#native().getHeight();
|
||||
}
|
||||
|
||||
/** Export as PNG bytes. */
|
||||
async get_bytes(): Promise<Uint8Array> {
|
||||
return this.#native().getBytes();
|
||||
}
|
||||
|
||||
/** Export as JPEG bytes with specified quality (0-100). */
|
||||
async get_bytes_jpeg(quality: number): Promise<Uint8Array> {
|
||||
return this.#native().getBytesJpeg(quality);
|
||||
}
|
||||
|
||||
/** Release native resources. */
|
||||
free() {
|
||||
if (this.#freed) return;
|
||||
this.#freed = true;
|
||||
images.delete(this.#handle);
|
||||
}
|
||||
|
||||
/** Alias for free() to support using-declarations. */
|
||||
[Symbol.dispose](): void {
|
||||
this.free();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize an image to the specified dimensions.
|
||||
* Returns a new PhotonImage (original is not modified).
|
||||
*/
|
||||
export async function resize(image: PhotonImage, width: number, height: number, filter: number): Promise<PhotonImage> {
|
||||
const nativeImage = getImage(image._getHandle());
|
||||
const resized = await nativeImage.resize(width, height, filter);
|
||||
const handle = registerImage(resized);
|
||||
return PhotonImage._create(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate image resources (no-op for native bindings).
|
||||
*/
|
||||
export function terminate(): void {}
|
||||
export { PhotonImage, SamplingFilter };
|
||||
|
||||
@@ -74,9 +74,7 @@ export async function find(options: FindOptions, onMatch?: (match: FindMatch) =>
|
||||
|
||||
export {
|
||||
PhotonImage,
|
||||
resize,
|
||||
SamplingFilter,
|
||||
terminate as terminateImageWorker,
|
||||
} from "./image/index";
|
||||
|
||||
// =============================================================================
|
||||
|
||||
@@ -36,37 +36,43 @@ export interface ParsedKittyResult {
|
||||
eventType?: KeyEventType;
|
||||
}
|
||||
|
||||
export interface NativePhotonImage {
|
||||
getWidth(): number;
|
||||
getHeight(): number;
|
||||
getBytes(): Promise<Uint8Array>;
|
||||
getBytesJpeg(quality: number): Promise<Uint8Array>;
|
||||
getBytesWebp(): Promise<Uint8Array>;
|
||||
getBytesGif(): Promise<Uint8Array>;
|
||||
resize(width: number, height: number, filter: number): Promise<NativePhotonImage>;
|
||||
export const enum ImageFormat {
|
||||
PNG = 0,
|
||||
JPEG = 1,
|
||||
WEBP = 2,
|
||||
GIF = 3,
|
||||
}
|
||||
|
||||
export interface NativePhotonImageConstructor {
|
||||
newFromByteslice(bytes: Uint8Array): Promise<NativePhotonImage>;
|
||||
prototype: NativePhotonImage;
|
||||
export interface PhotonImage {
|
||||
get width(): number;
|
||||
get height(): number;
|
||||
encode(format: ImageFormat, quality: number): Promise<Uint8Array>;
|
||||
resize(width: number, height: number, filter: number): Promise<PhotonImage>;
|
||||
}
|
||||
|
||||
export interface NativeSamplingFilter {
|
||||
Nearest: 1;
|
||||
Triangle: 2;
|
||||
CatmullRom: 3;
|
||||
Gaussian: 4;
|
||||
Lanczos3: 5;
|
||||
export interface PhotonImageConstructor {
|
||||
parse(bytes: Uint8Array): Promise<PhotonImage>;
|
||||
prototype: PhotonImage;
|
||||
}
|
||||
|
||||
export const enum SamplingFilter {
|
||||
Nearest = 1,
|
||||
Triangle = 2,
|
||||
CatmullRom = 3,
|
||||
Gaussian = 4,
|
||||
Lanczos3 = 5,
|
||||
}
|
||||
|
||||
import type { GrepMatch } from "./grep/types";
|
||||
|
||||
export type TsFunc<T> = (error: Error | null, value: T) => void;
|
||||
|
||||
export interface NativeBindings {
|
||||
copyToClipboard(text: string): Promise<void>;
|
||||
readImageFromClipboard(): Promise<ClipboardImage | null>;
|
||||
find(options: FindOptions, onMatch?: (error: Error | null, match: FindMatch) => void): Promise<FindResult>;
|
||||
find(options: FindOptions, onMatch?: TsFunc<FindMatch>): Promise<FindResult>;
|
||||
fuzzyFind(options: FuzzyFindOptions): Promise<FuzzyFindResult>;
|
||||
grep(options: GrepOptions, onMatch?: (error: Error | null, match: GrepMatch) => void): Promise<GrepResult>;
|
||||
grep(options: GrepOptions, onMatch?: TsFunc<GrepMatch>): Promise<GrepResult>;
|
||||
search(content: string | Uint8Array, options: SearchOptions): SearchResult;
|
||||
hasMatch(
|
||||
content: string | Uint8Array,
|
||||
@@ -78,8 +84,8 @@ export interface NativeBindings {
|
||||
highlightCode(code: string, lang: string | null | undefined, colors: HighlightColors): string;
|
||||
supportsLanguage(lang: string): boolean;
|
||||
getSupportedLanguages(): string[];
|
||||
SamplingFilter: NativeSamplingFilter;
|
||||
PhotonImage: NativePhotonImageConstructor;
|
||||
SamplingFilter: SamplingFilter;
|
||||
PhotonImage: PhotonImageConstructor;
|
||||
truncateToWidth(text: string, maxWidth: number, ellipsisKind: number, pad: boolean): string;
|
||||
wrapTextWithAnsi(text: string, width: number): string[];
|
||||
sliceWithWidth(line: string, startCol: number, length: number, strict: boolean): SliceWithWidthResult;
|
||||
@@ -92,10 +98,7 @@ export interface NativeBindings {
|
||||
strictAfter: boolean,
|
||||
): ExtractSegmentsResult;
|
||||
matchesKittySequence(data: string, expectedCodepoint: number, expectedModifier: number): boolean;
|
||||
executeShell(
|
||||
options: ShellExecuteOptions,
|
||||
onChunk?: (error: Error | null, chunk: string) => void,
|
||||
): Promise<ShellExecuteResult>;
|
||||
executeShell(options: ShellExecuteOptions, onChunk?: TsFunc<string>): Promise<ShellExecuteResult>;
|
||||
abortShellExecution(executionId: string): void;
|
||||
parseKey(data: string, kittyProtocolActive: boolean): string | null;
|
||||
matchesLegacySequence(data: string, keyName: string): boolean;
|
||||
|
||||
Reference in New Issue
Block a user