ویرایش همزمان در Wordgard؛ OT روی یه سند درختی
خلاصهٔ کاملتر
نویسنده که یازده سال پیش ویرایش همزمان رو توی ProseMirror و بعد توی CodeMirror پیاده کرده بود، اینبار سراغ ویرایشگر جدیدش Wordgard رفته. رویکرد پایه همونه: operational transformation با یه سرور مرکزی که ترتیب نهاییِ تغییرهای همزمان رو تعیین میکنه. ولی یه چالش تازه اضافه شده.
چالش اینه که سند Wordgard یه درخته، نه یه دنبالهی سادهی کاراکتر. نویسنده میگه بعضی سیستمها (مثل Quill و Peritext) سند رو یه دنبالهی تخت از بلوکها با متادیتا نگه میدارن، ولی این مدل برای ساختارهای تودرتو مثل لیستِ توی نقلقولِ توی لیست یا جدولها خیلی زود شلوغ یا ناکارآمد میشه. برای همین تصمیم گرفته سند رو درختی نگه داره.
ترفندش اینه که درخت رو بهشکل یه دنبالهی تخت از توکنها میبینه: کاراکترهای متن، نودهای برگ، و توکنهای باز/بسته برای نودهای داخلی. اونوقت یه تغییر یعنی جایگزینیِ بازههایی از این دنبالهی توکن با دنبالههای جدید، خیلی نزدیک به کاری که CodeMirror با مدل متن تختش میکنه. مشکل اینجاست که در یه مدل سلسلهمراتبی، توکنهای باز و بسته باید بالانس باشن و nesting باید مجاز باشه؛ پس ترنسفورمِ دو تغییر معتبر ممکنه یه تغییر نامعتبر بسازه.
راهحلش اینه که سند شروع رو هم به تابع ترنسفورم بده تا خروجی رو چک کنه، و اگه نامعتبر بود یه تغییر اصلاحیِ اضافه بسازه که معتبرش کنه. نکتهی ظریف اینه که اگه این کد اصلاح برای «ترنسفورم A روی B» همون اصلاحِ «ترنسفورم B روی A» رو تولید کنه، همگرایی (convergence) حفظ میشه و همه به یه سند معتبر میرسن. برای markها (استایلهایی مثل bold یا ترازبندی) هم فرمت تغییر میتونه بازهها رو «تغییریافته» علامت بزنه نه حذفودرج، تا مکان کرسر و هویت محتوا حفظ بمونه.
بخش شبکه هم نکتههای خودش رو داره. چون در ارتباط شبکهای هیچکدوم از دو طرف مطمئن نیستن پیامشون رسیده (همون مسئلهی Two Generals)، Wordgard همهی تغییرها—از جمله تغییر خود کلاینت—رو به همهی کلاینتها میفرسته؛ کلاینت صبر میکنه تغییر خودش برگرده و تازه اونوقت از فهرست pending حذفش میکنه. نویسنده همچنین ترنسفورم رو به سمت سرور برده، چون در روش قدیمی که سرور فقط تغییرِ مبتنیبر نسخهی فعلی رو میپذیرفت، یه کلاینت کُند یا پرتأخیر عملاً هیچوقت نوبت نمیگرفت.
برای اینکه هزینهی ترنسفورم درجهدو نشه، کلاینتها از گروهبندی تغییر استفاده میکنن: هر کلاینت حداکثر یه دسته تغییرِ in-flight داره و تغییرهای جدید با هم compose میشن، طوری که همیشه حداکثر دو دسته برای ترنسفورم بمونه. در نهایت انتزاعی به اسم correction برای اعمال محدودیتهای شکلیِ سند (مثل مستطیلموندن جدول) داره که فقط موقع ترنسفورم و توسط یه طرف اجرا میشه تا از حلقههای بیپایانِ اصلاح جلوگیری شه؛ همین باعث میشه ویرایش همزمانِ امن و آگاهبهساختار به دست بیاد.
نکات کلیدی:
- Wordgard از operational transformation با یه سرور مرکزی استفاده میکنه، ولی سندش درخته نه رشتهی کاراکتر.
- درخت به یه دنبالهی توکن (متن، برگ، توکن باز/بسته) تبدیل میشه تا OT سبک CodeMirror جواب بده.
- ترنسفورم ممکنه سند نامعتبر بسازه؛ یه اصلاحِ متقارن ساخته میشه تا همگرایی به یه نتیجهی معتبر حفظ شه.
- تغییرها به همه اکو میشن (برای مقابله با Two Generals)، ترنسفورم سمت سرور انجام میشه و correctionها فقط موقع ترنسفورم اعمال میشن.




