الوضع المباشر والوضع بدون واجهة
في كل استدعاء، يبحث الخادم عن محرر يحتفظ بالمستند، عبر ملفات القفل التي تُبقيها المحررات في ~/.erd-editor/ide/.
تُبقي كل نافذة VS Code وكل نافذة خزنة Obsidian فيها ERD Editor ملفًا واحدًا، وتُبقي بيئة تطوير JetBrains ملفًا واحدًا لبيئة التطوير كلها، يسرد كل مشروع مفتوح فيها.
يزيل المحرر ملف القفل الخاص به عند إغلاقه.
ما يجده الخادم يحدد أين يذهب التعديل.
| ما يجده | ما يفعله التعديل |
|---|---|
| محرر تحتوي مساحة عمله أو خزنته أو مشروعه المفتوح على المستند، أو يكون المستند مفتوحًا فيه | مباشر. يفتح المستند في ERD Editor عند الحاجة، وينضم إلى جلسة التحرير، ويطبّق التغيير هناك. تظهر التعديلات فورًا وتُحفظ كما يحفظ المحرر تعديلاتك، راجع الحفظ. |
| لا يوجد محرر | بدون واجهة. يحمّل الملف، ويطبّق التغيير، ويستبدل الملف. ليس للأداة erd_save ما تفعله. |
| محرر محوره معطّل | مرفوض. تظل القراءات تعمل، من القرص. التغيير الذي يُكتب في الملف وهو مفتوح في محرر قد يكتب فوقه الحفظ التالي لذلك المحرر، لذا لا يكتب الخادم شيئًا. |
محرر محوره مفعّل لكنه يستخدم بروتوكولًا غير بروتوكول الخادم: مع الخادم بالإصدار 1.0.0، إضافة VS Code بالإصدار 3.x أو مكوّن Obsidian الإضافي بالإصدار 0.x أو مكوّن JetBrains الإضافي بالإصدار 0.9.0 أو 0.10.0؛ ومع خادم قبل الإصدار 1.0.0، الإضافة بالإصدار 4.0.0 أو أحدث، أو مكوّن إضافي بالإصدار 1.0.0 أو أحدث | مرفوض، بما في ذلك القراءات، بالرمز protocolMismatch. تذكر الرسالة الطرف الذي يجب تحديثه: الإضافة أو المكوّن الإضافي، أو الخادم، راجع التحديث. |
على Windows، محرر يحتفظ بالمستند تحت مسار آخر إلى الملف نفسه: سمّاه الوكيل عبر مشاركة شبكة أو محرك أقراص معيّن يشيران إلى هذا الكمبيوتر، مثل \\localhost\C$\…، ويحتفظ به المحرر بمساره على محرك الأقراص، أو العكس | مرفوض، بما في ذلك القراءات، بالرمز invalidPath. تذكر الرسالة المسار الذي يحتفظ به المحرر بالمستند؛ أعد الاستدعاء بذلك المسار. |
| على Windows، محرر يمنع Windows الوكيلَ من الوصول إليه: محرر شُغّل بصفة مسؤول بينما لم يُشغَّل الوكيل كذلك، أو أي محرر حين يعمل الوكيل في بيئة معزولة | مرفوض، بما في ذلك القراءات، بالرمز hubUnreachable ورسالة تذكر السبب. شغّل المحرر والوكيل بالصلاحيات نفسها، على سبيل المثال بتشغيل المحرر مرة أخرى دون صلاحيات المسؤول. |
تذكر نتيجة التعديل الوضع الذي عمل فيه، live أو headless، ويذكر التعديل المرفوض السبب.
يُعاد البحث في كل استدعاء، لذا فإن فتح محرر أو إغلاقه ينقل الاستدعاء التالي معه.
حين يحتفظ بالمستند أكثر من محرر واحد، يتقدّم المحرر الذي يفتحه على محرر لا يخدم سوى مجلد يحتويه، ومن بين المحررات التي تخدم مجلدًا، يتقدّم المحرر الذي يقع مجلده في أعمق مستوى. ويُحسم التعادل، كأن يفتحه محرران كلاهما، لصالح المحرر صاحب ملف القفل الأحدث تغييرًا. لذا فإن المستند الموجود في خزنة Obsidian داخل مجلد مساحة عمل VS Code يذهب إلى Obsidian، ما لم يكن مفتوحًا في VS Code وغير مفتوح في Obsidian.
تعمل الاستدعاءات على مستند واحد واحدًا تلو الآخر، بالترتيب الذي وصلت به إلى الخادم. وتعمل الاستدعاءات على مستندات مختلفة بالتوازي.
الوضع المباشر
ينضم الوكيل إلى المحرر كأنه متعاون إضافي. تصل تعديلاته فورًا إلى كل محرر مفتوح على المستند، ويُرسم تركيزه على الجدول والخلية اللذين يحررهما، كما يُرسم تركيز أي متعاون، راجع focusTracker.
لا تفتح القراءة محررًا أبدًا. يفتح التعديل المستند في ERD Editor إن لم يكن مفتوحًا بعد، دون أن يأخذ تركيز لوحة المفاتيح.
الحفظ
يحفظ كل محرر تعديلات الوكيل بالطريقة التي يحفظ بها تعديلاتك.
في VS Code، تُعلِّم تعديلات الوكيل علامة التبويب بأنها غير محفوظة كما تفعل تعديلاتك، ولا تصل إلى القرص إلا عند حفظ المستند.
تحفظ erd_save المستند عبر VS Code، كما يفعل أمر الحفظ فيه. ويمكنك الحفظ بنفسك بدلًا من ذلك، باستخدام Ctrl + S (Windows/Linux) أو ⌘ + S (Mac).
يؤدي إغلاق المحرر وفيه تعديلات للوكيل غير محفوظة إلى سؤالك عما إذا كنت تريد حفظها، كما في أي تغيير آخر غير محفوظ.
يحفظ Obsidian تعديلات الوكيل بعد نحو ثانيتين من توقف التحرير، ويحفظها إغلاق علامة التبويب دون سؤال.
تكتبها بيئة تطوير JetBrains بعد جزء من الثانية من توقف التحرير، ويكتب إغلاق علامة التبويب ما لا يزال معلّقًا؛ ولا تظهر علامة التبويب أبدًا بوصفها معدّلة.
في الحالتين، تكتبها erd_save فورًا.
تنتظر erd_save أولًا مدة تصل إلى ثانيتين حتى يحتفظ المحرر بكل تعديل أجراه الوكيل.
وتُرفض بالرمز notSaved حين لم يتمكن المحرر من تأكيد ذلك، أو لم يكتب الملف: يُبقي VS Code علامة التبويب غير محفوظة حين يكون الملف قد تغيّر على القرص، وقد يتعذّر على بيئة تطوير JetBrains كتابته، كأن يكون مربع حوار مفتوحًا حينها أو يكون الملف غير قابل للكتابة.
في VS Code وبيئة تطوير JetBrains، تنجح erd_save على مستند لم يبقَ فيه ما يُحفظ وتترك الملف كما هو.
وتكون هذه هي الحال بمجرد حفظ كل تعديل، وهو ما تفعله بيئة تطوير JetBrains من تلقاء نفسها، وتبقى كذلك ما دام كل تغيير لاحق تغييرًا يُبقيه قفل خارج الملف، مثل التمرير أو تغيير مستوى التكبير مع قفل Viewport، أو التبديل بين علامات التبويب مع قفل Canvas Type. كل الأقفال مفعّلة افتراضيًا.
ويُرفض الملف الذي لا تستطيع بيئة تطوير JetBrains كتابته حتى في هذه الحالة.
حين يغلق المحرر المستند بعد آخر تعديل أجراه الوكيل، يحمل الاستدعاء التالي للوكيل تنويهًا بأن تلك التعديلات لا توجد في الملف إلا إذا حُفظت قبل إغلاق المحرر.
التراجع
تتراجع erd_undo عن آخر تعديل أجراه الوكيل، لا عن تعديلاتك أبدًا، وتعيد erd_redo تطبيقه.
أما التراجع الخاص بالمحرر فيعمل بالعكس: يتراجع عن تعديلاتك ولا يتراجع أبدًا عن تعديلات الوكيل، لأن التغييرات الواردة من محرر آخر لا تُسجَّل في سجلك.
لا تُنشئ بعض التعديلات إدخال تراجع في المحرر: erd_set_database وerd_set_database_name من بين أدوات الإعدادات، وerd_resize_memo.
ولا يُنشئه كذلك استدعاء erd_move_table_group ينقل المجموعة أقل من 20 بكسلًا إجمالًا، بجمع الإزاحتين الأفقية والرأسية، وإن بقيت المجموعة حيث انتقلت.
ولا يُنشئ الاستدعاء الذي لا يغيّر شيئًا إدخالًا أيضًا: erd_set_column_primary_key أو erd_set_column_unique أو erd_set_column_not_null أو erd_set_column_auto_increment أو erd_set_index_unique أو erd_set_index_column_order حين تضبط قيمة يحملها المستند بالفعل؛ erd_add_index_column مع عمود موجود بالفعل في الفهرس؛ erd_set_table_group مع جداول موجودة بالفعل في تلك المجموعة (أو ليست في أي مجموعة بالفعل، مع groupId بالقيمة null)؛ erd_move_table_group إلى النقطة التي تقف فيها المجموعة بالفعل؛ erd_resize_table_group إلى المستطيل الذي تشغله المجموعة بالفعل؛ erd_sort_tables على مستند لا جدول فيه؛ أو استيراد تكون فيه mode بالقيمة append ولا يجلب أي جدول (وفي حالة erd_import_json، لا جدول ولا ملاحظة).
تتخطى erd_undo هذه الاستدعاءات وتذكر أسماءها في نتيجتها.
أما التعديلات الأخرى، مثل erd_change_relationship_type وerd_change_relationship_on_delete وerd_change_relationship_on_update وerd_change_table_group_name وerd_change_table_group_color وerd_set_ddl_script، فتُنشئ إدخالًا حتى حين تضبط قيمة يحملها المستند بالفعل.
ينتهي سجل التراجع الخاص بالوكيل، مع تنويه في النتيجة، عندما:
- ينضم الوكيل إلى المستند مرة أخرى، على سبيل المثال بعد أن أخرجه المحرر منه.
- ينتهي تشغيل المحرر، أو يغلق المستند ويتوقف عن خدمته، ويواصل الوكيل تحرير الملف على القرص.
- يتولى محرر مستندًا كان الوكيل يحرره على القرص.
ويغلق الخادم أيضًا المستند الذي لم يُجرِ عليه الوكيل أي استدعاء منذ 30 دقيقة، ويزول معه سجل التراجع، دون تنويه.
عندما يختفي المحرر
ما دام محرر يحتفظ بمستند، لا يلجأ الخادم أبدًا إلى الملف من تلقاء نفسه. إذا انقطع الاتصال، يعيد الاتصال. ولا يحرر الخادم الملف إلا حين يكون تشغيل المحرر قد انتهى، أو يكون المحرر قد أغلق المستند ولم يعد يسرده ولا يسرد مجلدًا يحتويه، ويذكر ذلك في النتيجة. ويحدث ذلك حين تغلق مخططًا يقع خارج كل المجلدات التي يخدمها المحرر (في VS Code، مخططًا فُتح من خارج مساحة العمل)، وحين تعطّل المكوّن الإضافي ERD Editor في Obsidian، وحين تغلق المشروع الذي يحتوي على المستند في بيئة تطوير JetBrains أو تعطّل المكوّن الإضافي فيها. أما المخطط المغلق داخل مجلد يخدمه المحرر فيبقى مع المحرر، ويعيد التعديل التالي للوكيل فتحه.
المحرر الذي لا يزال يعمل، لكن ملف القفل الخاص به اختفى وانقطع اتصاله دون أن يغلق المستند، يرفض التعديل التالي بالرمز hubGone.
تذكر الرسالة ما يُفرج عن المستند: في VS Code، أعد تحميل تلك النافذة، أو أغلقها ليتمكن الوكيل من تحرير الملف مباشرةً؛ في Obsidian، أعد تفعيل المكوّن الإضافي ERD Editor، أو أغلق تلك النافذة؛ في بيئة تطوير JetBrains، أعد تفعيل المكوّن الإضافي، أو أغلق بيئة التطوير.
وتتجه القراءة إلى الملف على القرص بدلًا من ذلك، مع تنويه بأن التعديلات التي لم تُحفظ بعد في المحرر غير موجودة، في حالتين: حين يكون محور المحرر الذي يحتفظ بالمستند معطّلًا، وفي حالة hubGone المذكورة أعلاه.
وتُرفض القراءة التي لا تستطيع الاتصال بمحور محرر بالرمز hubUnreachable، كما يُرفض التعديل.
الوضع بدون واجهة
حين لا يخدم أي محرر المستند، يحمّل كل تعديل الملف، ويطبّق التغيير، ويكتب الملف من جديد.
تذهب الكتابة إلى ملف مؤقت بجوار المستند، اسمه .<name>.<id>.tmp، يحل بعد ذلك محله، لذا لا يُترك المستند أبدًا مكتوبًا جزئيًا، إلا على Windows في حالة الكتابة في الموضع، الموضّحة أدناه.
قبل تلك الخطوة الأخيرة، يتحقق الخادم مما إذا كان الملف قد تغيّر على القرص أثناء الاستدعاء.
إن كان قد تغيّر، لا يُكتب شيء، ويُحمَّل الملف من جديد، ويُرفض الاستدعاء بالرمز conflict. ويعيد الوكيل الاستدعاء.
أما الملف الذي تغيّر بين استدعاءين فيُحمَّل من جديد فحسب، ويُسقَط سجل تراجع الوكيل السابق لذلك.
يُترك الملف الذي للقراءة فقط كما هو، ويُرفض التعديل بالرمز readonly: ملف بلا إذن كتابة لمالكه، أو بسمة القراءة فقط على Windows، مثل ملف Perforce أو TFVC لم يُسحب للتحرير.
اجعله قابلًا للكتابة، ثم أعد الاستدعاء. تظل القراءات تعمل.
إذا بدأ محرر في خدمة المستند بينما يحرره الوكيل على القرص، يُرفض ذلك التعديل وحده بالرمز hubAppeared ولا يُكتب شيء. ويحرر الاستدعاء التالي عبر المحرر.
على Windows، تنطبق قاعدتان إضافيتان:
- يُكتب المستند الذي له أذونات خاصة به، تختلف عن أذونات مجلده، في موضعه بدلًا من استبداله، لكي يحتفظ بها، ويُزال الملف المؤقت بعد ذلك. قد يجد البرنامج الذي يقرأ المستند أثناء تلك الكتابة نصًا لا يمكن تحليله.
- لا يمكن استبدال ملف يُبقيه برنامج آخر مفتوحًا، لذا يعيد الخادم المحاولة لمدة تصل إلى ثانيتين. تبحث كل محاولة أولًا عن محرر من جديد، والمحرر الذي بدأ في خدمة المستند في هذه الأثناء يرفض الكتابة بالرمز
hubAppeared، أو بالرمزblockedحين يكون محوره معطّلًا. إذا ظل الملف محجوزًا بعد ثانيتين، لا يُكتب شيء، ويُحمَّل الملف من جديد، ويفشل الاستدعاء برسالة تقتبس خطأ النظام.
الرفض
تحتفظ نافذة VS Code بملف القفل الخاص بها حتى حين يكون محورها معطّلًا: حين يكون dineug.erd-editor.agentHub.enabled معطّلًا، أو حين لا تكون مساحة العمل موثوقة، أو حين تعذّر على محورها الاستماع.
وتحتفظ نافذة خزنة Obsidian بملف القفل الخاص بها ومحورها معطّل حين يكون Coding agents معطّلًا، وحين تعذّر على محورها الاستماع.
وتحتفظ بيئة تطوير JetBrains بملف القفل الخاص بها ومحورها معطّل حين يكون Coding agents معطّلًا، وحين تعذّر على محورها الاستماع، وأثناء إنهاء بيئة التطوير.
يُرفض تعديل مثل هذا المستند بالرمز blocked، لأن المحرر المفتوح قد يكتب فوق التغيير المكتوب في الملف عند حفظه التالي.
تظل القراءات تعمل، من الملف على القرص.
لتمكين الوكيل من التحرير، أعد تفعيل المحور، كما تذكر الرسالة لذلك المحرر: في VS Code، ثق بمساحة العمل وفعّل الإعداد، أو أعد تحميل النافذة؛ في Obsidian، فعّل Coding agents، أو أعد تحميل Obsidian؛ في بيئة تطوير JetBrains، فعّل Coding agents، أو أعد تشغيل بيئة التطوير إن كان مفعّلًا بالفعل.
وترفض بيئة تطوير JetBrains أيضًا، بالرمز hubDisabled، تغيير مستند لا تحتفظ به إلا مشاريع لا تثق بها.
يظل بإمكان الوكلاء قراءة مثل هذا المستند، وتسرده erd_list_documents بوصفه readonly. ثق بالمشروع، ثم أعد الاستدعاء.
المحرر الذي لا يحتفظ بملف قفل لا يحمي شيئًا، ويحرر الوكيل الملف على القرص حتى أثناء فتح المخطط فيه.
وهذه هي الحال مع Obsidian أو بيئة تطوير JetBrains المثبّتين عبر Flatpak على Linux، وبيئة تطوير JetBrains دون JCEF، وبيئة تطوير JetBrains تعذّر بدء تشغيل محورها، راجع إعداد Obsidian وإعداد بيئة تطوير JetBrains.
ولا تحتفظ إضافة VS Code قبل الإصدار 3.0.0 ولا مكوّن JetBrains الإضافي قبل الإصدار 0.9.0 بأي ملف قفل كذلك، إذ لا محور لهما.
المستندات
يُسمّى المستند عبر path، بمسار مطلق أو نسبي إلى مجلد عمل الخادم.
- تكون المستندات الجديدة بصيغة
.erd.json. تنشئerd_open_documentمعcreateالملف، وتضيف.erd.jsonإلى الاسم الذي لا امتداد له. وكما في المخطط الجديد في المحرر، تكون كل الأقفال مفعّلة في المستند الجديد، لذا فإن التمرير أو تغيير مستوى التكبير أو التبديل بين علامات التبويب أو اختيار لغة أخرى لمنشئ التعليمات البرمجية أو نمط تسمية آخر أو نوع آخر من علامات الاقتباس في محرر لا يغيّر الملف أبدًا. لا توجد أداة تفعّل قفلًا واحدًا أو تعطّله: تفعل ذلك في علامة تبويب الإعدادات في المحرر. تستبدلerd_import_jsonفي الوضعreplaceالأقفال كلها بأقفال المستند الذي تحمّله، راجع الاستيراد. - تُفتح أيضًا ملفات
.erdو.vuerdو.vuerd.jsonالموجودة. ويُرفض المسار ذو أي امتداد آخر بالرمزinvalidPath. - على Windows، يُرفض بالرمز
invalidPathالمسار الذي يحتوي على اسم لا يخزنه Windows كما كُتب، قبل قراءة المستند أو كتابته، بما في ذلك القراءات: اسم فيه نقطتان رأسيتان أو حرف آخر يرفضه Windows، مثلorders:v2.erd؛ أو اسم جهاز مثلNUL.erdأوCON.erd، بأي حالة أحرف؛ أو اسم ينتهي بنقطة أو مسافة. أعد تسميته، على سبيل المثال باستخدام-بدلًا من:. - يُرفض بالرمز
invalidDocumentالملف الذي ليس مستندًا يستطيع المحرر قراءته، مثل ملف بقيت فيه علامات تعارض الدمج، ويُترك كما هو. ولا يُحمَّل أبدًا بوصفه مخططًا فارغًا ليُكتب من جديد.
لا يغيّر الوكيل المستند إلا عبر الأدوات، ويُطلب منه ألا يكتب الملف بنفسه أبدًا.
تسرد erd_list_documents المستندات مع path وopen وactive وdirty وreadonly.
وتسأل المحرر الذي يخدم مجلد العمل، المختار كما يُختار لمستند، وتسرد المخططات المفتوحة فيه، ثم ملفات ERD التي يخدمها: تلك الموجودة في مجلدات مساحة العمل لنافذة VS Code، أو في خزنة Obsidian، أو في كل مشروع مفتوح في بيئة تطوير JetBrains.
وإلا فإنها تسرد ملفات ERD الموجودة ضمن مجلد العمل، حيث يحمل الملف الذي للقراءة فقط العلامة readonly، ويُستبعد على Windows الاسم الذي لا يخزنه Windows كما كُتب.