التخزين
يخزن AISCouncil جميع البيانات محليًا في متصفحك. لا يتم رفع أي شيء لأي خادم. يستخدم نظام التخزين طبقتين -- localStorage للقراءات الصغيرة المتزامنة المطلوبة عند التشغيل، و IndexedDB للبيانات الكبيرة غير المتزامنة مثل ملفات البوت التعريفية وسجلات المحادثات.
بنية التخزين ثنائية الطبقات
| الطبقة | API | السعة | حالة الاستخدام |
|---|---|---|---|
| localStorage | متزامن | ~5-10 ميجابايت | السمة، مفاتيح API، الإعدادات -- بيانات مطلوبة فورًا عند تحميل الصفحة |
| IndexedDB | غير متزامن | ~100 ميجابايت - 1 جيجابايت+ | ملفات البوت التعريفية، سجلات المحادثات، بيانات الإضافات -- بيانات كبيرة |
الانقسام موجود لأن localStorage سريع لكن محدود الحجم، بينما IndexedDB غير محدود فعليًا لكن يتطلب وصولاً غير متزامن. القيم الحرجة وقت التشغيل (السمة، مفاتيح API، حالة تسجيل الدخول) تعيش في localStorage حتى يمكن للتطبيق التصيير فورًا دون انتظار القراءات غير المتزامنة.
مفاتيح localStorage
جميع مفاتيح localStorage تستخدم البادئة ais-:
| المفتاح | النوع | الوصف |
|---|---|---|
ais-theme | نص | السمة الحالية (light، dark، أو system) |
ais-apikey-anthropic | نص | مفتاح Anthropic API |
ais-apikey-openai | نص | مفتاح OpenAI API |
ais-apikey-xai | نص | مفتاح xAI API |
ais-apikey-gemini | نص | مفتاح Google Gemini API |
ais-apikey-openrouter | نص | مفتاح OpenRouter API |
ais-apikey-deepseek | نص | مفتاح DeepSeek API |
ais-apikey-groq | نص | مفتاح Groq API |
ais-apikey-mistral | نص | مفتاح Mistral API |
ais-user | JSON | معلومات المستخدم المسجل (الاسم، البريد، الصورة، المزود) |
ais-idb-migrated | نص | علامة تشير لاكتمال ترحيل localStorage إلى IndexedDB |
ais-ollama-endpoint | نص | URL نقطة نهاية Ollama المخصصة (الافتراضي: http://localhost:11434) |
ais-custom-providers | JSON | مصفوفة من تكوينات المزود المخصص المعرفة من المستخدم |
aiscouncil-settings | JSON | الإعدادات العامة (السمة، حجم الخط، القدرات، إلخ) |
aiscouncil-usage | JSON | بيانات تتبع الاستخدام (الرموز، التكاليف لكل مزود) |
مفاتيح API في localStorage قابلة للوصول لأي جافاسكريبت يعمل على نفس الأصل. هذا معياري لتطبيقات المتصفح، لكن يعني أنه لا يجب تثبيت إضافات متصفح غير موثوقة. المفاتيح لا تُضمّن أبدًا في صادرات URL أو نسخ البيانات الاحتياطية.
مفاتيح IndexedDB
يخزن IndexedDB البيانات في مخزن كائنات مفتاح-قيمة داخل قاعدة بيانات باسم ais-db (أو قاعدة بيانات لكل مستخدم عند تسجيل الدخول):
| نمط المفتاح | النوع | الوصف |
|---|---|---|
ais-bots | مصفوفة | جميع بيانات جلسات البوت الوصفية (المعرف، الاسم، الإعدادات، تاريخ الإنشاء) |
ais-profiles | مصفوفة | جميع الملفات التعريفية المحفوظة (الفردية والمجالس) |
ais-chat-{botId} | مصفوفة | سجل رسائل المحادثة لجلسة بوت محددة |
ais-addon-manifests | مصفوفة | بيانات الإضافات/البرامج المساعدة المثبتة |
ais-miniprogram-* | متنوع | بيانات البرامج المصغرة المثبتة |
لكل جلسة بوت مفتاح محادثة خاص بها (ais-chat-abc123)، لذا سجلات المحادثات معزولة ويمكن تحميلها بشكل مستقل.
الترحيل التلقائي
عند أول تشغيل، يتحقق AIS.Storage.init() مما إذا كانت بيانات موجودة في localStorage من إصدار أقدم ويرحلها تلقائيًا لـ IndexedDB. علامة ais-idb-migrated تمنع إعادة الترحيل عند التحميلات اللاحقة.
إذا كان IndexedDB غير متاح (بعض متصفحات الخصوصية تحظره)، تعود طبقة التخزين لـ localStorage بشفافية. يستمر التطبيق في العمل، لكن مع حد التخزين ~5-10 ميجابايت.
طبقة SQLite WASM الاختيارية
لحالات الاستخدام المتقدمة التي تتضمن بيانات ثنائية كبيرة (صور، مرفقات)، يمكن لنظام التخزين تحميل وحدة SQLite WASM اختيارية. يعمل SQLite بالتزامن مع IndexedDB ويخزن البيانات في نظام الملفات الخاص بالأصل (OPFS) للمتصفح.
يُحمّل SQLite عند الطلب -- لا يُحمّل أبدًا إلا إذا طُلب صراحةً أو احُتيج لتخزين blob. لتفعيله، انتقل لـ الإعدادات > عام > خلفية التخزين واختر SQLite.
| الميزة | IndexedDB | SQLite WASM |
|---|---|---|
| تخزين مفتاح-قيمة | نعم | نعم |
| تخزين blobs الثنائية | محدود | محسّن |
| استعلامات SQL | لا | نعم |
| الاستمرار | يُدار من المتصفح | OPFS (قائم على الملفات) |
| التحميل | فوري | كسول (عند أول استخدام) |
AIS.Storage API
توفر وحدة AIS.Storage واجهة برمجة موحدة تعمل بغض النظر عن الخلفية النشطة:
العمليات الأساسية
// تهيئة التخزين (تُستدعى مرة عند التشغيل)
await AIS.Storage.init();
// الحصول على قيمة
const bots = await AIS.Storage.get("ais-bots");
// ضبط قيمة
await AIS.Storage.set("ais-bots", updatedBots);
// حذف مفتاح
await AIS.Storage.delete("ais-chat-abc123");
// قائمة جميع المفاتيح
const allKeys = await AIS.Storage.keys();
// الحصول على جميع أزواج المفتاح-القيمة
const everything = await AIS.Storage.getAll();
// مسح جميع البيانات
await AIS.Storage.clear();
تخزين Blob (SQLite)
// تخزين blob ثنائي
await AIS.Storage.putBlob("image-001", arrayBuffer, "image/png");
// استرجاع blob
const blob = await AIS.Storage.getBlob("image-001");
// { data: Uint8Array, mime: 'image/png', size: 12345 }
دوال المساعدة
// مساعدات localStorage المتزامنة (للقراءات وقت التشغيل)
const theme = AIS.Storage.loadJSON("ais-theme");
AIS.Storage.saveJSON("ais-theme", "dark");
// مصنع ذاكرة تخزين مؤقت TTL (لتخزين السجل المؤقت)
const cache = AIS.Storage.cache("ais-models-cache", "ais-models-ts", 86400000); // TTL 24س
const data = cache.load(); // قراءة البيانات المخزنة مؤقتًا
cache.save(newData); // تحديث الذاكرة المؤقتة
const stale = cache.isStale(); // التحقق مما إذا كانت الذاكرة المؤقتة منتهية
خصائص الحالة
AIS.Storage.isIDB; // true إذا كان IndexedDB نشطًا
AIS.Storage.hasSQLite; // true إذا كان SQLite WASM محمّلاً
التصدير والاستيراد
تصدير البيانات
انتقل لـ الإعدادات > الخصوصية > تصدير جميع البيانات أو استخدم API:
const backup = await AIS.Storage.exportData();
// Returns: { bcz_version: "1.0.0", exported: "2026-02-19T...", data: {...} }
يتضمن التصدير جميع ملفات البوت التعريفية وسجلات المحادثات والإعدادات وبيانات الإضافات. يستثني صراحةً:
- مفاتيح API (لا تُصدّر أبدًا)
- مفاتيح API لكل عضو في الملفات التعريفية (تُجرد لتصبح مزود/نموذج فقط)
يُحفظ التصدير كـ ais-backup-YYYY-MM-DD.json.
إذا كان لديك تخزين blob من SQLite نشط، يُولّد التصدير أيضًا ملف ais-blobs-YYYY-MM-DD.db منفصل يحتوي على قاعدة بيانات SQLite.
استيراد البيانات
انتقل لـ الإعدادات > الخصوصية > استيراد البيانات أو استخدم API:
const count = await AIS.Storage.importData(jsonBackup);
// Returns: number of items imported
يقبل الاستيراد:
- ملفات
.json(تنسيق النسخة الاحتياطية القياسي) - ملفات
.db(قاعدة بيانات SQLite)
مفاتيح API لا تُستورد أبدًا حتى لو كانت موجودة في الملف.
حصص التخزين
تختلف حصص تخزين المتصفح حسب المنصة:
| المتصفح | حصة IndexedDB | مع التخزين المستمر |
|---|---|---|
| Chrome/Edge | ~60% من مساحة القرص | نفسه، لكن لا يُحذف |
| Firefox | ~50% من مساحة القرص | يطلب إذن المستخدم |
| Safari | ~1 جيجابايت مبدئي، يمكن منح المزيد | نفسه |
يطلب AISCouncil التخزين المستمر عند التهيئة عبر navigator.storage.persist(). عند الموافقة، لن يحذف المتصفح بياناتك تلقائيًا عندما يكون التخزين منخفضًا.
افتح DevTools لمتصفحك، انتقل لـ Application > Storage، وابحث عن الأصل aiscouncil.net لرؤية استخدام التخزين الحالي والحصة.
الخصوصية
جميع البيانات تبقى على جهازك:
- لا رفع للخادم -- إعدادات البوت، سجلات المحادثات، والإعدادات لا تُرسل أبدًا لأي خادم
- لا تحليلات -- لا تُنقل بيانات الاستخدام لأي مكان
- لا ملفات تعريف ارتباط -- التطبيق يستخدم
localStorageو IndexedDB، وليس ملفات تعريف ارتباط التتبع (ملف تعريف الارتباطais-authيُستخدم فقط للكشف عن المصادقة عبر النطاقات الفرعية) - لا تخزين طرف ثالث -- البيانات مخزنة فقط تحت أصل
aiscouncil.net
مسح البيانات
لمسح جميع البيانات المخزنة:
- الإعدادات > الخصوصية > مسح جميع البيانات -- يزيل جميع بيانات IndexedDB والملفات التعريفية وسجلات المحادثات
- DevTools المتصفح > Application > Clear Storage -- خيار نووي، يزيل كل شيء بما في ذلك localStorage
- حذف محادثة فردية -- انقر بزر أيمن على بوت في الشريط الجانبي واختر حذف
مسح جميع البيانات لا يمكن التراجع عنه. صدّر بياناتك أولًا إذا كنت تريد نسخة احتياطية. مفاتيح API المخزنة في localStorage تُزال أيضًا عند المسح عبر DevTools المتصفح.
تخزين لكل بوت للبرامج المصغرة
كل برنامج مصغر مثبت يحصل على مساحة اسم تخزين معزولة خاصة به. تصل البرامج المصغرة للتخزين عبر واجهة برمجة SDK ais.storage، التي ترسم لمفاتيح مسبوقة لكل تطبيق في IndexedDB. لا يمكن لبرنامج مصغر واحد الوصول لبيانات آخر.
// داخل برنامج مصغر
await ais.storage.set("my-key", "my-value");
const val = await ais.storage.get("my-key");
const keys = await ais.storage.keys();
await ais.storage.remove("my-key");
يُحذف تخزين البرنامج المصغر عند إلغاء تثبيت البرنامج المصغر.