- หน้าแรก
- Documentation
- เนทีฟ
- มีเดีย Native + ยูทิลิตี้ระบบ
มีเดีย Native + ยูทิลิตี้ระบบ
เอกสารนี้เป็นการวิเคราะห์เชิงลึกของระบบย่อยสำหรับชั้น system/media/conversion primitives ที่อธิบายไว้ใน docs/natives-architecture.md: image, html, clipboard และการโปรไฟล์ work
ไฟล์การติดตั้ง
หัวข้อที่มีชื่อว่า “ไฟล์การติดตั้ง”crates/pi-natives/src/image.rscrates/pi-natives/src/html.rscrates/pi-natives/src/clipboard.rscrates/pi-natives/src/prof.rscrates/pi-natives/src/task.rspackages/natives/src/image/index.tspackages/natives/src/image/types.tspackages/natives/src/html/index.tspackages/natives/src/html/types.tspackages/natives/src/clipboard/index.tspackages/natives/src/clipboard/types.tspackages/natives/src/work/index.tspackages/natives/src/work/types.ts
หมายเหตุ: ไม่มี
crates/pi-natives/src/work.rs; การโปรไฟล์งานถูกติดตั้งในprof.rsและป้อนข้อมูลโดยการ instrumentation ในtask.rs
การแมปการส่งออก/โมดูล TS API ↔ Rust
หัวข้อที่มีชื่อว่า “การแมปการส่งออก/โมดูล TS API ↔ Rust”| การส่งออก TS (packages/natives) | การส่งออก Rust N-API | โมดูล Rust |
|---|---|---|
PhotonImage.parse(bytes) | PhotonImage::parse | image.rs |
PhotonImage#resize(width, height, filter) | PhotonImage::resize | image.rs |
PhotonImage#encode(format, quality) | PhotonImage::encode | image.rs |
htmlToMarkdown(html, options) | html_to_markdown | html.rs |
copyToClipboard(text) | copy_to_clipboard + TS fallback logic | clipboard.rs + clipboard/index.ts |
readImageFromClipboard() | read_image_from_clipboard | clipboard.rs |
getWorkProfile(lastSeconds) | get_work_profile | prof.rs |
ขอบเขตรูปแบบข้อมูลและการแปลง
หัวข้อที่มีชื่อว่า “ขอบเขตรูปแบบข้อมูลและการแปลง”รูปภาพ (image)
หัวข้อที่มีชื่อว่า “รูปภาพ (image)”- ขอบเขตอินพุต JS: ไบต์รูปภาพที่เข้ารหัสเป็น
Uint8Array - ขอบเขตการถอดรหัส Rust: ไบต์ถูกคัดลอกไปยัง
Vec<u8>ระบบเดาฟอร์แมตด้วยImageReader::with_guessed_format()จากนั้นถอดรหัสเป็นDynamicImage - สถานะในหน่วยความจำ:
PhotonImageเก็บArc<DynamicImage> - ขอบเขตเอาต์พุต:
encode(format, quality)คืนค่าPromise<Uint8Array>(RustVec<u8>)
รหัสฟอร์แมตเป็นตัวเลข:
0: PNG1: JPEG2: WebP (ตัวเข้ารหัสแบบไม่สูญเสียข้อมูล)3: GIF
ข้อจำกัด:
qualityใช้งานได้เฉพาะกับ JPEG เท่านั้น- PNG/WebP/GIF ไม่สนใจค่า
quality - รหัสฟอร์แมตที่ไม่รองรับจะล้มเหลว (
Invalid image format: <id>)
การแปลง HTML (html)
หัวข้อที่มีชื่อว่า “การแปลง HTML (html)”- ขอบเขตอินพุต JS:
stringของ HTML + ออบเจ็กต์ทางเลือก{ cleanContent?: boolean; skipImages?: boolean } - ขอบเขตการแปลง Rust: อินพุต
Stringถูกแปลงโดยhtml_to_markdown_rs::convert - ขอบเขตเอาต์พุต:
stringของ Markdown
พฤติกรรมการแปลง:
cleanContentค่าเริ่มต้นคือfalse- เมื่อ
cleanContent=trueจะเปิดใช้งานการประมวลผลล่วงหน้าด้วยPreprocessingPreset::Aggressiveและแฟล็กลบอย่างถาวรสำหรับการนำทาง/ฟอร์ม skipImagesค่าเริ่มต้นคือfalse
คลิปบอร์ด (clipboard)
หัวข้อที่มีชื่อว่า “คลิปบอร์ด (clipboard)”- เส้นทางข้อความ:
- TS ปล่อย OSC 52 (
\x1b]52;c;<base64>\x07) ก่อนเมื่อ stdout เป็น TTY - ข้อความเดียวกันจะถูกพยายามผ่าน clipboard API แบบ native (
native.copyToClipboard) ในฐานะ best-effort - บน Termux, TS จะพยายาม
termux-clipboard-setก่อน
- TS ปล่อย OSC 52 (
- เส้นทางอ่านรูปภาพ:
- Rust อ่านรูปภาพดิบจาก
arboard - Rust เข้ารหัสซ้ำเป็นไบต์ PNG (ไลบรารี
image) คืนค่า{ data: Uint8Array, mimeType: "image/png" } - TS คืนค่า
nullก่อนกำหนดบน Termux หรือ Linux sessions ที่ไม่มี display server (DISPLAY/WAYLAND_DISPLAYขาดหายไป)
- Rust อ่านรูปภาพดิบจาก
การโปรไฟล์งาน (work)
หัวข้อที่มีชื่อว่า “การโปรไฟล์งาน (work)”- ขอบเขตการเก็บข้อมูล: ตัวอย่างการโปรไฟล์ถูกสร้างโดย guards
profile_region(tag)ในtask::blockingและtask::future - รูปแบบการจัดเก็บ: บัฟเฟอร์วงกลมขนาดคงที่ (
MAX_SAMPLES = 10_000) เก็บ stack path + duration (μs) + timestamp (μs นับจากการเริ่มต้นกระบวนการ) - ขอบเขตเอาต์พุต:
getWorkProfile(lastSeconds)คืนค่าออบเจ็กต์:folded: ข้อความ folded-stack (อินพุตสำหรับ flamegraph)summary: สรุปตาราง markdownsvg: SVG flamegraph แบบทางเลือกtotalMs,sampleCount
วงจรชีวิตและการเปลี่ยนสถานะ
หัวข้อที่มีชื่อว่า “วงจรชีวิตและการเปลี่ยนสถานะ”วงจรชีวิตของรูปภาพ
หัวข้อที่มีชื่อว่า “วงจรชีวิตของรูปภาพ”PhotonImage.parse(bytes)กำหนดตารางเวลา blocking decode task (image.decode)- เมื่อสำเร็จ จะมี handle
PhotonImageแบบ native ใน JS resize(...)สร้าง handle แบบ native ใหม่ (image.resize) โดย handle เก่าและใหม่สามารถอยู่ร่วมกันได้encode(...)สร้างไบต์จริง (image.encode) โดยไม่เปลี่ยนแปลงขนาดของรูปภาพ
การเปลี่ยนสถานะเมื่อล้มเหลว:
- การตรวจจับฟอร์แมต/การถอดรหัสล้มเหลว จะปฏิเสธ promise การแยกวิเคราะห์
- การเข้ารหัสล้มเหลว จะปฏิเสธ promise การเข้ารหัส
- รหัสฟอร์แมตไม่ถูกต้อง จะปฏิเสธ promise การเข้ารหัส
วงจรชีวิตของ HTML
หัวข้อที่มีชื่อว่า “วงจรชีวิตของ HTML”htmlToMarkdown(html, options)กำหนดตารางเวลา blocking conversion task- การแปลงทำงานด้วยออปชันค่าเริ่มต้น (
cleanContent=false,skipImages=false) หากไม่ได้ระบุ - คืนค่า markdown string หรือปฏิเสธ
การเปลี่ยนสถานะเมื่อล้มเหลว:
- ความล้มเหลวของตัวแปลงคืนค่า rejected promise (
Conversion error: ...)
วงจรชีวิตของคลิปบอร์ด
หัวข้อที่มีชื่อว่า “วงจรชีวิตของคลิปบอร์ด”copyToClipboard(text) ถูกออกแบบมาให้เป็น best-effort และมีหลายเส้นทางโดยเจตนา:
- ถ้าเป็น TTY: พยายามเขียน OSC 52 (payload base64)
- ลอง Termux command เมื่อตั้งค่า
TERMUX_VERSIONไว้ - ลองคัดลอกข้อความแบบ native ด้วย
arboard - กลืนกินข้อผิดพลาดที่ชั้น TS
ความเข้มงวดของ readImageFromClipboard() แตกต่างกันตามขั้นตอน:
- TS ปิดกั้นอย่างเด็ดขาดสำหรับ runtime context ที่ไม่รองรับ (Termux/headless Linux) ให้เป็น
null - Rust
arboardread ทำงานเฉพาะเมื่อ TS อนุญาต ContentNotAvailableแมปเป็นnull- ข้อผิดพลาด Rust อื่นๆ จะปฏิเสธ
วงจรชีวิตของการโปรไฟล์งาน
หัวข้อที่มีชื่อว่า “วงจรชีวิตของการโปรไฟล์งาน”- ไม่มีการเริ่มต้นอย่างชัดเจน: การโปรไฟล์เปิดอยู่เสมอเมื่อ task helpers ทำงาน
- ทุก instrumented task scope บันทึกหนึ่งตัวอย่างเมื่อ guard drop
- ตัวอย่างจะเขียนทับรายการเก่าที่สุดหลังจากถึงความจุของบัฟเฟอร์
getWorkProfile(lastSeconds)อ่านช่วงเวลาหนึ่งและสร้างผลลัพธ์ folded/summary/svg
การเปลี่ยนสถานะเมื่อล้มเหลว:
- การสร้าง SVG ล้มเหลวจะเป็น soft-fail (
svg: null) ในขณะที่ folded และ summary ยังคงคืนค่า - ช่วงเวลาตัวอย่างว่างเปล่าจะคืนค่าข้อมูล folded ว่างเปล่าและ
svg: nullไม่ใช่ข้อผิดพลาด
การดำเนินการที่ไม่รองรับและการส่งต่อข้อผิดพลาด
หัวข้อที่มีชื่อว่า “การดำเนินการที่ไม่รองรับและการส่งต่อข้อผิดพลาด”- อินพุตการถอดรหัสที่ไม่รองรับหรือไบต์เสียหาย: ล้มเหลวอย่างเข้มงวด (promise rejection)
- รหัสฟอร์แมตการเข้ารหัสที่ไม่รองรับ: ล้มเหลวอย่างเข้มงวด
- ไม่มีเส้นทาง best-effort fallback ใน TS wrapper
- ข้อผิดพลาดการแปลงเป็นความล้มเหลวอย่างเข้มงวด (rejection)
- การละเว้นออปชันเป็น best-effort defaulting ไม่ใช่ความล้มเหลว
คลิปบอร์ด
หัวข้อที่มีชื่อว่า “คลิปบอร์ด”- การคัดลอกข้อความเป็น best-effort ที่ชั้น TS: ความล้มเหลวในการดำเนินงานถูกระงับ
- การอ่านรูปภาพแยกแยะ “ไม่มีรูปภาพ” (
null) จากความล้มเหลวในการดำเนินงาน (rejection) - Termux/headless Linux ถูกถือว่าเป็น context ที่ไม่รองรับสำหรับการอ่านรูปภาพ (
null)
การโปรไฟล์งาน
หัวข้อที่มีชื่อว่า “การโปรไฟล์งาน”- การดึงข้อมูลเป็นความเข้มงวดสำหรับการเรียกใช้ฟังก์ชันเอง แต่การสร้าง artifact เป็น best-effort บางส่วน (
svgเป็น nullable) - การตัดทอนบัฟเฟอร์เป็นพฤติกรรมที่คาดหวัง (ring buffer) ไม่ใช่บัคการสูญหายของข้อมูล
ข้อจำกัดของแพลตฟอร์ม
หัวข้อที่มีชื่อว่า “ข้อจำกัดของแพลตฟอร์ม”- ข้อความคลิปบอร์ด: OSC 52 ขึ้นอยู่กับการรองรับของ terminal; การเข้าถึง clipboard แบบ native ขึ้นอยู่กับ desktop environment/session
- การอ่านรูปภาพจากคลิปบอร์ด: ถูกบล็อกใน TS สำหรับ Termux และ Linux ที่ไม่มี display server