চলো যাই.
মরিচায় WebAssembly(Wasm) মডিউলগুলির জন্য TypeScript প্রকারগুলি তৈরি করা সহজ নয়।
আমি সমস্যায় পড়েছিলাম যখন আমি Wasm-এ Voy নামক একটি ভেক্টর মিল সার্চ ইঞ্জিনে কাজ করছিলাম। আমি জাভাস্ক্রিপ্ট এবং টাইপস্ক্রিপ্ট ইঞ্জিনিয়ারদের শব্দার্থিক অনুসন্ধানের জন্য একটি সুইস ছুরি প্রদান করার জন্য মরিচা-এ Wasm ইঞ্জিন তৈরি করেছি। এখানে ওয়েবের জন্য একটি ডেমো আছে:
আপনি GitHub এ Voy এর সংগ্রহস্থল খুঁজে পেতে পারেন! নির্দ্বিধায় এটি চেষ্টা করে দেখুন।
রিপোজিটরিতে এমন উদাহরণ রয়েছে যা আপনি দেখতে পাচ্ছেন কিভাবে বিভিন্ন ফ্রেমওয়ার্কে Voy ব্যবহার করতে হয়।
আমি Wasm-এ মরিচা কোড তৈরি এবং কম্পাইল করতে wasm-pack এবং wasm-bindgen ব্যবহার করেছি। উত্পন্ন টাইপস্ক্রিপ্ট সংজ্ঞা এই মত দেখায়:
/* 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 হল একটি জাভাস্ক্রিপ্ট অবজেক্টের wasm-bindgen এর উপস্থাপনা।
আমরা JsValue কে সিরিয়ালাইজ এবং ডিসিরিয়ালাইজ করি যাতে এটি জাভাস্ক্রিপ্ট এবং রাস্ট এর মাধ্যমে Wasm এর মধ্যে যায়।
#[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 সংকলনে ট্যাপ করার এবং Wasm মডিউলের API-এর জন্য টাইপ সংজ্ঞা তৈরি করার একটি উপায়। এটার মত:
#[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] ম্যাক্রো যুক্ত করা:
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 এর অ্যাপ্লিকেশন বাইনারি ইন্টারফেস (ABI) এর সাথে ডেটা প্রবাহের দিক।
উভয় বৈশিষ্ট্যই জং এবং জাভাস্ক্রিপ্টের মধ্যে ডেটা রূপান্তর বাস্তবায়নের জন্য serde-wasm-bindgen ব্যবহার করে।
আমরা Wasm মডিউল তৈরি করতে প্রস্তুত। একবার আপনি "ওয়াসম-প্যাক বিল্ড" চালান, স্বয়ংক্রিয়ভাবে তৈরি টাইপস্ক্রিপ্ট সংজ্ঞা:
/* 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[] }
সমস্ত "যেকোন" প্রকারের ইন্টারফেসের সাথে প্রতিস্থাপিত হয় যা আমরা রাস্ট কোডে সংজ্ঞায়িত করেছি✨
উত্পন্ন ধরনের দেখতে ভাল, কিন্তু কিছু অসঙ্গতি আছে. আপনি যদি ঘনিষ্ঠভাবে লক্ষ্য করেন, আপনি লক্ষ্য করবেন অনুসন্ধান ফাংশনে ক্যোয়ারী প্যারামিটারটিকে একটি Float32Array হিসাবে সংজ্ঞায়িত করা হয়েছে।
ক্যোয়ারী প্যারামিটারটি EmbeddedResource-এ "এম্বেডিং" হিসাবে একই প্রকার হিসাবে সংজ্ঞায়িত করা হয়েছে, তাই আমি আশা করি যে তাদের TypeScript-এ একই প্রকার থাকবে।
আপনি যদি জানেন কেন সেগুলি বিভিন্ন প্রকারে রূপান্তরিত হয়, তাহলে অনুগ্রহ করে গিটহাব-এ Voy- এ পৌঁছাতে বা একটি পুল অনুরোধ খুলতে দ্বিধা করবেন না।
Voy হল WebAssembly-এ একটি ওপেন-সোর্স শব্দার্থিক সার্চ ইঞ্জিন। শব্দার্থিক বৈশিষ্ট্যগুলি তৈরি করতে এবং বিশ্বজুড়ে মানুষের জন্য আরও ভাল ব্যবহারকারীর অভিজ্ঞতা তৈরি করতে আরও প্রকল্পগুলিকে শক্তিশালী করার জন্য আমি এটি তৈরি করেছি৷ Voy বিভিন্ন নকশা নীতি অনুসরণ করে:
এটি npm-এ উপলব্ধ। আপনি কেবল আপনার প্রিয় প্যাকেজ পরিচালকের সাথে এটি ইনস্টল করতে পারেন এবং আপনি যেতে প্রস্তুত৷
# with npm npm i voy-search # with Yarn yarn add voy-search # with pnpm pnpm add voy-search
এটি একবার চেষ্টা করে দেখুন, এবং আমি আপনার কাছ থেকে শুনতে খুশি!
সংযোগ করতে চান?
এই নিবন্ধটি মূলত Daw-Chih এর ওয়েবসাইটে পোস্ট করা হয়েছিল।