س3ميني: مكتبة خفيفة وسريعة لمخازن الكائنات المشتركة مع S3 بحجم 14 كيلوبايت ودون أي اعتمادات
ملخص مشروع s3mini: العميل الصغير والمبتكر لتخزين الكائنات المتماشي مع S3 المحتوى الرئيسي (500 كلمة) ما هو s3mini؟ s3mini هو عميل برمجي صغير ومبتكر مكتوب بلغة TypeScript لتخزين الكائنات المتماشية مع خدمة Amazon S3. هذا العميل يتميز بخفته (حوالي 14 كيلوبايت بعد التنقية) وسرعته (يسجل زيادة بنسبة حوالي 15% في عمليات الثانية). يمكن تشغيله على منصات مختلفة مثل Node.js، Bun، و Cloudflare Workers، مما يجعله مثاليًا للمحوطات الحوافية (Edge Computing) والتطبيقات التي تحتاج إلى موارد محدودة. ومع ذلك، لا يدعم المتصفحات بسبب استخدامه لواجهات برمجة تطبيقات Node.js والملحقات. المميزات الرئيسية: - خفيف وسريع: يوفر أداءً أفضل بنسبة 15% ويحتوي على حجم صغير جدًا (حوالي 14 كيلوبايت). - لا يعتمد على أي مكتبات خارجية: يدعم توقيع الطلبات AWS SigV4 بدون الحاجة إلى طلبات موقعة مسبقًا. - يعمل على منصات المحوطات الحوافية: مثالي للتشغيل على Cloudflare Workers، Node.js، و Bun. - يدعم فقط الواجهات الأساسية لـ S3: مثل إدراج الكائنات، الحصول عليها، حذفها، وقائمة الكائنات. - BYOS3 — احمل سلة تخزينك الخاصة المتماشية مع S3: تم اختباره على Cloudflare R2، Backblaze B2، DigitalOcean Spaces، MinIO، وGarage. من المخطط له اختباره على Ceph وAWS في المستقبل. المنصات المدعومة: تم اختبار s3mini وتجربته على منصات متعددة مثل: - MinIO: منصة مفتوحة المصدر لتوفير خدمات تخزين الكائنات المتماشية مع S3. - Cloudflare R2: خدمة تخزين كائنات عالية الأداء من Cloudflare. - Backblaze B2: خدمة تخزين سحابي اقتصادية من Backblaze. - DigitalOcean Spaces: خدمة تخزين كائنات من DigitalOcean. - MinIO و Garage: منصات أخرى لتوفير خدمات تخزين الكائنات. طرق الاستخدام: 1. إنشاء العميل: ```typescript import { s3mini, sanitizeETag } from 's3mini'; const s3client = new s3mini({ accessKeyId: config.accessKeyId, secretAccessKey: config.secretAccessKey, endpoint: config.endpoint, region: config.region, }); ``` العمليات الأساسية للسلال (Buckets): تحقق من وجود السلة: typescript let exists: boolean = false; try { exists = await s3client.bucketExists(); } catch (err) { throw new Error(`فشل في استدعاء bucketExists(), ربما بيانات الاعتماد خاطئة: ${err.message}`); } if (!exists) { await s3client.createBucket(); } العمليات الأساسية للكائنات (Objects): تحقق من وجود الكائن: ```typescript const smallObjectKey: string = 'small-object.txt'; const smallObjectContent: string = 'مرحبًا بالعالم!'; const objectExists: boolean = await s3client.objectExists(smallObjectKey); let etag: string | null = null; if (!objectExists) { const resp: Response = await s3client.putObject(smallObjectKey, smallObjectContent); etag = sanitizeETag(resp.headers.get('etag')); } ``` الحصول على الكائن: typescript const objectData: string | null = await s3client.getObject(smallObjectKey); console.log('بيانات الكائن:', objectData); الحصول على الكائن باستخدام ETag: typescript const response2: Response = await s3client.getObject(smallObjectKey, { 'if-none-match': etag }); if (response2) { const etag2: string = sanitizeETag(response2.headers.get('etag')); console.log('بيانات الكائن مع ETag:', response2.body, 'ETag:', etag2); } else { console.log('لم يتم العثور على الكائن أو أن ETag متطابقة.'); } قائمة الكائنات في السلة: typescript const list: object[] | null = await s3client.listObjects(); if (list) { console.log('قائمة الكائنات:', list); } else { console.log('لم يتم العثور على كائنات في السلة.'); } حذف الكائن: typescript const wasDeleted: boolean = await s3client.deleteObject(smallObjectKey); تحميل متعدد الأجزاء (Multipart Upload): بدء التحميل: typescript const multipartKey = 'multipart-object.txt'; const large_buffer = new Uint8Array(1024 * 1024 * 15); // ملف بحجم 15 ميجابايت const partSize = 8 * 1024 * 1024; // كل جزء بحجم 8 ميجابايت const totalParts = Math.ceil(large_buffer.length / partSize); const uploadId = await s3client.getMultipartUploadId(multipartKey); تحميل الأجزاء: typescript const uploadPromises = []; for (let i = 0; i < totalParts; i++) { const partBuffer = large_buffer.subarray(i * partSize, (i + 1) * partSize); uploadPromises.push(s3client.uploadPart(multipartKey, uploadId, partBuffer, i + 1)); } const uploadResponses = await Promise.all(uploadPromises); const parts = uploadResponses.map((response, index) => ({ partNumber: index + 1, etag: response.etag, })); إكمال التحميل: typescript const completeResponse = await s3client.completeMultipartUpload(multipartKey, uploadId, parts); const completeEtag = completeResponse.etag; إلغاء تحميل متعدد الأجزاء: typescript const abortResponse = await s3client.abortMultipartUpload(multipartKey, uploadId); تحميل متعدد الأجزاء (Multipart Download): تنزيل جزء من الكائن: typescript const rangeStart = 2048 * 1024; // 2 ميجابايت const rangeEnd = 8 * 1024 * 1024 * 2; // 16 ميجابايت const rangeResponse = await s3client.getObjectRaw(multipartKey, false, rangeStart, rangeEnd); const rangeData = await rangeResponse.arrayBuffer(); ملاحظات حول الأمن: - المساهمات مرحَّب بها: يمكن للمطورين المساهمة في المشروع عبر تقديم تقارير عن المشكلات وطلبات الميزات الجديدة. - تقديم تقارير المشكلات: إذا واجهت مشكلة أو لديك طلب ميزات جديد، يرجى فتح قضية على GitHub مع تفاصيل كافية. - طلبات السحب (Pull Requests): يمكن تقديم طلبات السحب لتنفيذ ميزات جديدة أو تصحيح الأخطاء. - فلسفة الخفة: عند المساهمة، يجب الاحتفاظ بخفة المكتبة وعدم إضافة مكتبات ثقيلة. - سلوك المجتمع: يجب التعامل باحترام وبناء في التواصل مع المساهمين الآخرين. الترخيص: يتم ترخيص المشروع بموجب رخصة MIT. يمكنك الاطلاع على تفاصيل الرخصة في الملف LICENSE.md. دعم المشروع: تطوير وصيانة s3mini يتطلب وقتًا وجهدًا. إذا كنت تجد هذه المكتبة مفيدة، يمكنك دعم تطويرها من خلال الرعاية. دعمك يساعد في ضمان استمراريتي في تحسين s3mini وغيرها من المشاريع المفتوحة المصدر. المعلومات الإضافية (100 كلمة) s3mini هو مشروع مفتوح المصدر يسعى إلى توفير حلول فعالة وخالية من التعقيدات في مجال تخزين الكائنات المتماشية مع S3. تم تطويره بواسطة مجتمع المطورين ويعمل على تحسين الأداء والخفة دون التضحية بالميزات الأساسية. هذا يجعله خيارًا ممتازًا للمشاريع التي تتطلب تشغيلًا على منصات المحوطات الحوافية وأجهزة ذات موارد محدودة. يُشجع المطورون على المساهمة والمشاركة في تطوير المشروع من أجل تحقيق أهدافه وتوفير قيمة مضافة للمجتمع التقني.