JavaScript / TypeScript
حزمة SeekGist للمتصفحات وNode.js.
حزمة JavaScript / TypeScript اسمها @seekgist/sdk. تعمل في المتصفحات وNode 20 أو أحدث وDeno وBun وبيئات الحافة (edge): فهي تستخدم fetch وWeb Crypto فقط. وهي بصيغة ESM فقط ومع أنواع كاملة. دوال الواجهة البرمجية مولّدة من ملف OpenAPI، أما الدوال المساعدة فمكتوبة يدويًا.
بداية سريعة
import { SeekGist } from "@seekgist/sdk";
const client = new SeekGist({ apiKey: process.env.SEEKGIST_API_KEY }); // أو اضبط SEEKGIST_API_KEY
const res = await client.find("فستان سهرة تحت 100", { lang: "ar", per_page: 12 });
res.data.ids; // أرقام المنتجات بترتيب الصلة
res.data.hits; // بطاقات المنتجات
res.usage; // { searches, limit, billed, period } من X-SeekGist-Usage
res.requestId; // اذكره عند التواصل مع الدعمالمفاتيح: المفتاح العام (sg_pub_...) آمن في المتصفح. والمفتاح السري (sg_sec_...) لخادمك فقط: يرفضه العميل داخل المتصفح.
الخيارات: baseUrl (الافتراضي https://api.seekgist.com)، وtimeoutMs (10,000 لكل محاولة)، وmaxRetries (2)، وheaders، وfetch، وkeyInQuery (يرسل المفتاح العام على شكل ?key= في طلبات GET، فيتجاوز المتصفح طلب CORS التمهيدي).
صندوق البحث في المتصفح
ينتظر المقترِح حتى يتوقف المتسوق عن الكتابة (120 ملّي ثانية)، ويلغي الطلبات القديمة، ويحفظ الإجابات الأخيرة. والاقتراحات لا تُحسب في الفاتورة أبدًا.
const s = client.suggester({ lang: "auto", products: 3 });
input.addEventListener("input", async () => render(await s.input(input.value)));مزامنة الكتالوج (على الخادم)
ترسل upsertProducts دفعات حتى 1,000 منتج، مع Idempotency-Key واحد لكل دفعة و5 محاولات إعادة. وتشغيلها مرة أخرى بقيمة keyPrefix نفسها استئناف آمن. ومع replaceAll تصبح مزامنة كاملة: تُحذف المنتجات التي لم ترسلها.
const sum = await client.upsertProducts(products, { replaceAll: true, keyPrefix: `nightly-${date}` });
// sum: { batches, upserted, unchanged, deleted, errors: [{ batch, index, id, code, message }] }كل دوال الواجهة البرمجية
مجال أسماء لكل قسم من الواجهة، ودالة لكل نقطة نهاية: client.search وevents وcatalog وimports وconnectors وjobs وsynonyms وrules وexperiments وtranslation وassistant وanalytics وwebhooks وaccount وbilling وhealth وfiles.
await client.synonyms.create({ body: { kind: "equivalent", terms: ["sneakers", "trainers", "سنيكرز"] } });
await client.catalog.productsGet({ product_id: "42" });
const r = await client.request("search_post", { body: { q: "dress" } }); // أي نقطة نهاية باسم operationIdتقبل كل دالة options في آخرها: { timeoutMs, maxRetries, idempotencyKey, headers, query, signal }.
الدوال المساعدة
| الدالة | ماذا تفعل |
|---|---|
client.find(q, fields) | POST /v1/search؛ وترجع الرد كاملًا مع usage |
client.suggester(options) | اقتراحات مع انتظار توقف الكتابة لصندوق البحث |
client.upsertProducts(products, options) | مزامنة آمنة للكتالوج على دفعات |
client.waitForJob(id) | تنتظر انتهاء مهمة (إعادة فهرسة، استيراد، ترجمة) |
client.pages(cursor => ...) | for await على كل عناصر قائمة |
verifyWebhook({ secret, headers, body }) | تتحقق من توقيع الإشعار ومن وقته (5 دقائق) |
parseUsage(header) | تقرأ X-SeekGist-Usage |
// مستقبِل الإشعارات: مرّر محتوى الطلب الخام كما وصل، لا نسخة أُعيد ترميزها.
const event = await verifyWebhook({ secret: process.env.SEEKGIST_WEBHOOK_SECRET!, headers: req.headers, body: rawBody });الأخطاء وإعادة المحاولة
ApiError: ردت الواجهة البرمجية بخطأ (status،code،requestId،fieldErrors،retryAfterS). استخدمcodeفي برنامجك.TimeoutErrorوConnectionError: لم يصل رد. وWebhookVerificationError: إشعار غير صالح.- إعادة المحاولة (مرتان افتراضيًا، بانتظار 0.5 ثانية ثم ثانية ثم ثانيتين وهكذا، مع قدر عشوائي؛ وتغلب
Retry-After): لطلبات GET والبحث وعمليات الكتابة التي تحملIdempotency-Key(تضيفه الحزمة وتحتفظ به في كل محاولة). أما النقرات والأحداث والمحادثة فلا تُعاد بعد خطأ شبكة أو خطأ 5xx، حتى لا يُحسب شيء مرتين. ويُعاد الطلب عند 429 دائمًا. - في صفحة البحث في متجر، استخدم
timeoutMs: 300, maxRetries: 0واعرض بحث متجرك عند أي خطأ. راجع الرجوع إلى بحث المتجر.
أمثلة
في المستودع: packages/sdk-js/examples/search.mjs (البحث والاقتراحات في Node)، وbrowser-suggest.html (صندوق بحث)، وsync-catalog.mjs (إرسال على دفعات)، وwebhook-receiver.mjs.