चल दर।
रस्ट में WebAssembly (WASM) मॉड्यूल के लिए टाइपस्क्रिप्ट प्रकार बनाना सीधा नहीं है।
मैं समस्या में भाग गया जब मैं वासम में एक वेक्टर समानता खोज इंजन पर काम कर रहा था जिसे वॉय कहा जाता था। मैंने सिमेंटिक खोज के लिए स्विस चाकू के साथ जावास्क्रिप्ट और टाइपस्क्रिप्ट इंजीनियरों को प्रदान करने के लिए रस्ट में वासम इंजन का निर्माण किया। यहाँ वेब के लिए एक डेमो है:
आप गिटहब पर वॉय की रिपॉजिटरी पा सकते हैं! इसे ट्राय करने के लिए स्वतंत्र महसूस करें।
रिपॉजिटरी में ऐसे उदाहरण शामिल हैं जिन्हें आप देख सकते हैं कि विभिन्न रूपरेखाओं में वॉय का उपयोग कैसे करें।
मैंने वास-पैक और वास-बाइंडजेन का उपयोग वास कोड को बनाने और संकलित करने के लिए किया था। उत्पन्न टाइपस्क्रिप्ट परिभाषाएँ इस तरह दिखती हैं:
/* tslint:disable */ /* eslint-disable */ /** * @param {any} input * @returns {string} */ export function index(resource: any): string /** * @param {string} index * @param {any} query * @param {number} k * @returns {any} */ export function search(index: string, query: any, k: number): any
जैसा कि आप देख सकते हैं, बहुत सारे "कोई भी" प्रकार हैं, जो डेवलपर अनुभव के लिए बहुत उपयोगी नहीं हैं। क्या हुआ यह जानने के लिए आइए रस्ट कोड देखें।
type NumberOfResult = usize; type Embeddings = Vec<f32>; type SerializedIndex = String; #[derive(Serialize, Deserialize, Debug)] pub struct EmbeddedResource { id: String, title: String, url: String, embeddings: Embeddings, } #[derive(Serialize, Deserialize, Debug)] pub struct Resource { pub embeddings: Vec<EmbeddedResource>, } #[wasm_bindgen] pub fn index(resource: JsValue) -> SerializedIndex { /* snip */ } #[wasm_bindgen] pub fn search(index: &str, query: JsValue, k: NumberOfResult) -> JsValue { // snip }
स्ट्रिंग, स्लाइस और अहस्ताक्षरित पूर्णांक ने टाइपस्क्रिप्ट में सही प्रकार उत्पन्न किए, लेकिन " wasm_bindgen::JsValue " नहीं किया। JsValue एक JavaScript वस्तु का wasm-bindgen का प्रतिनिधित्व है।
हम JsValue को क्रमबद्ध और deserialize करते हैं ताकि इसे जावास्क्रिप्ट और जंग के बीच वासम के माध्यम से आगे और पीछे पारित किया जा सके।
#[wasm_bindgen] pub fn index(resource: JsValue) -> String { // 💡 Deserialize JsValue in to Resource struct in Rust let resource: Resource = serde_wasm_bindgen:from_value(input).unwrap(); // snip } #[wasm_bindgen] pub fn search(index: &str, query: JsValue, k: usize) -> JsValue { // snip // 💡 Serialize search result into JsValue and pass it to WebAssembly let result = engine::search(&index, &query, k).unwrap(); serde_wasm_bindgen:to_value(&result).unwrap() }
डेटा प्रकारों को परिवर्तित करने के लिए यह आधिकारिक दृष्टिकोण है, लेकिन जाहिर है, हमें टाइपस्क्रिप्ट का समर्थन करने के लिए अतिरिक्त मील जाने की जरूरत है।
डेटा प्रकारों को एक भाषा से दूसरी भाषा में परिवर्तित करना वास्तव में एक सामान्य पैटर्न है जिसे विदेशी फ़ंक्शन इंटरफ़ेस (FFI) कहा जाता है। मैंने रस्ट स्ट्रक्चर्स से टाइपस्क्रिप्ट परिभाषाओं को ऑटो-जेनरेट करने के लिए टाइपशेयर जैसे एफएफआई टूल्स की खोज की, लेकिन यह समाधान का केवल आधा था।
हमें जो चाहिए वह वासम संकलन में टैप करने और वासम मॉड्यूल के एपीआई के लिए प्रकार की परिभाषा उत्पन्न करने का एक तरीका है। इस कदर:
#[wasm_bindgen] pub fn index(resource: Resource) -> SerializedIndex { /* snip */ } #[wasm_bindgen] pub fn search(index: SerializedIndex, query: Embeddings, k: NumberOfResult) -> SearchResult { // snip }
सौभाग्य से, Tsify उपयोग के मामले के लिए एक अद्भुत ओपन-सोर्स लाइब्रेरी है। हमें केवल "Tsify" विशेषता से प्राप्त करना है, और #[tsify] मैक्रो को structs में जोड़ना है:
type NumberOfResult = usize; type Embeddings = Vec<f32>; type SerializedIndex = String; #[derive(Serialize, Deserialize, Debug, Clone, Tsify)] #[tsify(from_wasm_abi)] pub struct EmbeddedResource { pub id: String, pub title: String, pub url: String, pub embeddings: Embeddings, } #[derive(Serialize, Deserialize, Debug, Tsify)] #[tsify(from_wasm_abi)] pub struct Resource { pub embeddings: Vec<EmbeddedResource>, } #[derive(Serialize, Deserialize, Debug, Clone, Tsify)] #[tsify(into_wasm_abi)] pub struct Neighbor { pub id: String, pub title: String, pub url: String, } #[derive(Serialize, Deserialize, Debug, Clone, Tsify)] #[tsify(into_wasm_abi)] pub struct SearchResult { neighbors: Vec<Neighbor>, } #[wasm_bindgen] pub fn index(resource: Resource) -> SerializedIndex { /* snip */ } #[wasm_bindgen] pub fn search(index: SerializedIndex, query: Embeddings, k: NumberOfResult) -> SearchResult { // snip }
इतना ही! आइए "from_wasm_abi" और "into_wasm_abi" विशेषताओं पर एक नज़र डालें।
दोनों विशेषताएँ रस्ट डेटा प्रकार को टाइपस्क्रिप्ट परिभाषा में बदल देती हैं। वे जो अलग तरीके से करते हैं वह वास के एप्लिकेशन बाइनरी इंटरफेस (एबीआई) के साथ डेटा प्रवाह की दिशा है।
जंग और जावास्क्रिप्ट के बीच डेटा रूपांतरण को लागू करने के लिए दोनों विशेषताएँ सर्द-वासम-बाइंडजेन का उपयोग करती हैं।
हम वासम मॉड्यूल बनाने के लिए तैयार हैं। एक बार जब आप "wasm-pack बिल्ड" चलाते हैं, तो ऑटो-जेनरेट की गई टाइपस्क्रिप्ट परिभाषा:
/* tslint:disable */ /* eslint-disable */ /** * @param {Resource} resource * @returns {string} */ export function index(resource: Resource): string /** * @param {string} index * @param {Float32Array} query * @param {number} k * @returns {SearchResult} */ export function search( index: string, query: Float32Array, k: number ): SearchResult export interface EmbeddedResource { id: string title: string url: string embeddings: number[] } export interface Resource { embeddings: EmbeddedResource[] } export interface Neighbor { id: string title: string url: string } export interface SearchResult { neighbors: Neighbor[] }
सभी "किसी भी" प्रकारों को उन इंटरफेस से बदल दिया जाता है जिन्हें हमने रस्ट कोड✨ में परिभाषित किया था
उत्पन्न प्रकार अच्छे लगते हैं, लेकिन कुछ विसंगतियाँ हैं। यदि आप बारीकी से देखते हैं, तो आप देखेंगे कि खोज फ़ंक्शन में क्वेरी पैरामीटर को फ़्लोट32एरे के रूप में परिभाषित किया गया है।
क्वेरी पैरामीटर को एंबेडेड रिसोर्स में "एम्बेडिंग" के समान प्रकार के रूप में परिभाषित किया गया है, इसलिए मैं उनसे टाइपस्क्रिप्ट में समान प्रकार की अपेक्षा करता हूं।
यदि आप जानते हैं कि वे विभिन्न प्रकारों में क्यों परिवर्तित होते हैं, तो कृपया गिटहब पर Voy में पहुंचने या पुल अनुरोध खोलने में संकोच न करें।
वॉय WebAssembly में एक ओपन-सोर्स सिमेंटिक सर्च इंजन है। मैंने इसे दुनिया भर के लोगों के लिए सिमेंटिक सुविधाओं के निर्माण और बेहतर उपयोगकर्ता अनुभव बनाने के लिए और अधिक परियोजनाओं को सशक्त बनाने के लिए बनाया है। वॉय कई डिजाइन सिद्धांतों का पालन करता है:
यह एनपीएम पर उपलब्ध है। आप बस इसे अपने पसंदीदा पैकेज मैनेजर से स्थापित कर सकते हैं, और आप जाने के लिए तैयार हैं।
# with npm npm i voy-search # with Yarn yarn add voy-search # with pnpm pnpm add voy-search
इसे आज़माएं और मुझे आपकी बात सुनकर खुशी हुई!
कनेक्ट करना चाहते हैं?
यह लेख मूल रूप से Daw-Chih की वेबसाइट पर पोस्ट किया गया था।