8.8 KiB
8.8 KiB
Natives media + system utilities
This document covers the media/system/conversion exports in @oh-my-pi/pi-natives: image processing, HTML conversion, clipboard access, token counting, macOS appearance/power helpers, ProjFS helpers, and work profiling.
Implementation files
crates/pi-natives/src/image.rscrates/pi-natives/src/html.rscrates/pi-natives/src/clipboard.rscrates/pi-natives/src/tokens.rscrates/pi-natives/src/appearance.rscrates/pi-natives/src/power.rscrates/pi-natives/src/projfs_overlay.rscrates/pi-natives/src/prof.rscrates/pi-natives/src/task.rspackages/natives/native/index.d.ts
Note: there is no
crates/pi-natives/src/work.rs; work profiling is implemented inprof.rsand fed by instrumentation intask.rs.
JS API ↔ Rust export/module mapping
| JS export | Rust N-API export | Rust module |
|---|---|---|
PhotonImage.parse(bytes) |
PhotonImage::parse |
image.rs |
PhotonImage#resize(width, height, filter) |
PhotonImage::resize |
image.rs |
PhotonImage#encode(format, quality) |
PhotonImage::encode |
image.rs |
encodeSixel(bytes, targetWidthPx, targetHeightPx) |
encode_sixel |
image.rs |
htmlToMarkdown(html, options?) |
html_to_markdown |
html.rs |
copyToClipboard(text) |
copy_to_clipboard |
clipboard.rs |
readImageFromClipboard() |
read_image_from_clipboard |
clipboard.rs |
countTokens(input, encoding?) |
count_tokens |
tokens.rs |
detectMacOSAppearance() |
detect_mac_os_appearance |
appearance.rs |
MacAppearanceObserver.start(callback) |
MacAppearanceObserver::start |
appearance.rs |
MacOSPowerAssertion.start(options?) |
MacOSPowerAssertion::start |
power.rs |
projfsOverlayProbe/start/stop |
ProjFS exports | projfs_overlay.rs |
getWorkProfile(lastSeconds) |
get_work_profile |
prof.rs |
Data format boundaries and conversions
Image (image)
- JS input boundary:
Uint8Arrayencoded image bytes forPhotonImage.parseandencodeSixel. - Rust decode boundary: bytes are copied/read, format is guessed with
ImageReader::with_guessed_format(), then decoded toDynamicImage. - In-memory state:
PhotonImagestoresArc<DynamicImage>. - Output boundary:
PhotonImage#encode(format, quality)returns a promise for encoded bytes (Vec<u8>in Rust; generated TS currently declaresPromise<Array<number>>).encodeSixel(...)returns a SIXEL escape string synchronously.
Format IDs:
0: PNG1: JPEG2: WebP3: GIF
Encoding behavior:
- JPEG uses the provided
qualitywithJpegEncoder::new_with_quality. - WebP uses the
webpcrate encoder withqualityasf32in the same 0..=100 range. - PNG/GIF ignore
quality. - Invalid dimensions for SIXEL (
0width or height) fail withTarget SIXEL dimensions must be greater than zero.
HTML conversion (html)
- JS input boundary: HTML
string+ optional{ cleanContent?: boolean; skipImages?: boolean }. - Rust conversion boundary: conversion is scheduled through
task::blocking("html_to_markdown", (), ...). - Output boundary: Markdown
stringpromise.
Conversion behavior:
cleanContentdefaults tofalse.- When
cleanContent=true, preprocessing usesPreprocessingPreset::Aggressiveand hard-removal flags for navigation/forms. skipImagesdefaults tofalse.
Clipboard (clipboard)
copyToClipboard(text)is a synchronous native call usingarboard::Clipboard::set_text.readImageFromClipboard()runs intask::blocking("clipboard.read_image", (), ...).- Image read returns
null/undefinedwhenarboardreportsContentNotAvailable. - Successful image read re-encodes clipboard RGBA data as PNG and returns
{ data: Uint8Array, mimeType: "image/png" }. - Clipboard access or image encoding failures reject/throw as native errors.
There is no current packages/natives TS wrapper that emits OSC52, handles Termux, or suppresses native clipboard failures. Any best-effort clipboard policy must live in consumers.
Tokens (tokens)
countTokens(input, encoding?)accepts a single string or an array of strings.- Arrays return one aggregate token count; encoding work is parallelized in Rust.
- Default encoding is
O200kBase;Cl100kBaseis also exported. - The implementation uses ordinary encoding, not special-token handling.
macOS appearance and power helpers
detectMacOSAppearance()returns"dark","light", ornullon non-macOS.MacAppearanceObserver.start(callback)returns a handle withstop(); on macOS it uses distributed notifications plus a 2-second polling fallback, and on non-macOS it is a no-op observer.MacOSPowerAssertion.start(options?)returns a handle withstop(); on macOS it acquires an IOKit assertion, and on other platforms it is a no-op handle.
Windows ProjFS helpers
projfsOverlayProbe()reports whether ProjFS APIs are available.projfsOverlayStart(lowerRoot, projectionRoot)starts an overlay.projfsOverlayStop(projectionRoot)stops an overlay session.
These helpers are platform-specific; availability must be checked before relying on overlay behavior.
Work profiling (work)
- Collection boundary: profiling samples are produced by
profile_region(tag)guards intask::blockingandtask::future. - Storage format: fixed-size circular buffer (
MAX_SAMPLES = 10_000) storing stack path, duration, and timestamp. - Output boundary:
getWorkProfile(lastSeconds)returns:folded: folded-stack text (flamegraph input)summary: markdown table summarysvg: optional flamegraph SVGtotalMs,sampleCount
Lifecycle and state transitions
Image lifecycle
PhotonImage.parse(bytes)schedules a blocking decode task (image.decode).- On success, a native
PhotonImagehandle exists in JS. resize(...)creates a new native handle (image.resize); old and new handles can coexist.encode(...)schedulesimage.encodeand materializes bytes without mutating image dimensions.encodeSixel(...)decodes, optionally resizes to exact target dimensions with Lanczos3, and returns SIXEL text synchronously.
Failure transitions:
- Format detection/decode failure rejects parse promise or throws from SIXEL encoding.
- Encode failure rejects encode promise.
- Invalid SIXEL dimensions throw.
HTML lifecycle
htmlToMarkdown(html, options)schedules a blocking conversion task.- Conversion runs with defaulted options (
cleanContent=false,skipImages=false) unless specified. - Returns markdown string or rejects.
Clipboard lifecycle
- Text copy constructs an
arboard::Clipboardand callsset_textsynchronously. - Image read constructs an
arboard::Clipboard, callsget_image, encodes PNG on success, mapsContentNotAvailabletoNone, and rejects other errors.
Work profiling lifecycle
- No explicit start: profiling is active when task helpers execute.
- Every instrumented task scope records one sample on guard drop.
- Samples overwrite oldest entries after buffer capacity is reached.
getWorkProfile(lastSeconds)reads a time window and derives folded/summary/svg artifacts.
Failure transitions:
- SVG generation failure is soft (
svgomitted/undefined), while folded and summary still return. - Empty sample windows return empty folded data and no SVG, not an error.
Unsupported operations and error propagation
Image
- Unsupported decode input or corrupted bytes: strict failure.
- Invalid SIXEL target dimensions: strict failure.
- No JS fallback path in the natives package.
HTML
- Conversion errors are strict failures.
- Option omission is defaulting, not failure.
Clipboard
- Text copy is strict at the native API surface.
- Image read distinguishes "no image" (
null/undefined) from operational failure (rejection).
Work profiling
- Retrieval is strict for the function call itself.
- Flamegraph SVG generation is nullable/optional.
- Buffer truncation is expected ring-buffer behavior.
Platform caveats
- Clipboard access depends on OS/session support exposed through
arboard. - macOS appearance and power helpers intentionally return no-op/null behavior on unsupported platforms.
- ProjFS helpers are Windows-specific and should be gated by
projfsOverlayProbe().