ویرایش مشارکتی
getSharedStore() یک ویرایشگر را به یک گره در یک نشست مشارکتی تبدیل میکند.
هر تغییر را بهصورت دنبالهای از کنشها ارسال میکند و کنشهایی را که ویرایشگرهای دیگر بازمیفرستند اعمال میکند — لایهٔ انتقال میان آنها را شما فراهم میکنید (WebSocket، WebRTC یا هر چیز دیگری که بتواند JSON را منتقل کند).
این متد یکی از متدهای ErdEditorElement است و وقتی تغییرات بازارسالشده باید ذخیره هم شوند، همراه با ذخیرهسازی راه دور به کار میرود.
از نسخهٔ 5.1.0، برای بهاشتراکگذاری یک نمودار از طریق یک سند Yjs و هر یک از فراهمکنندههای آن، بهجای اینکه خودتان لایهٔ انتقال را برقرار کنید، ویرایشگر را با @dineug/erd-editor-yjs متصل کنید؛ Yjs را ببینید.
interface ErdEditorElement extends HTMLElement {
// ...
getSharedStore: (
config?: SharedStoreConfig & {
mouseTracker?: boolean;
focusTracker?: boolean;
}
) => SharedStore;
}
type SharedStoreConfig = {
getNickname?: () => string;
};
type SharedStore = {
connection: () => void;
disconnect: () => void;
dispatch: (actions: Array<AnyAction> | AnyAction) => void;
dispatchSync: (actions: Array<AnyAction> | AnyAction) => void;
subscribe: (fn: (value: AnyAction[]) => void) => Unsubscribe;
flushStreamBuffers: () => void;
getLWW: () => SharedRegisters;
mergeLWW: (lww: SharedRegisters, version: number) => void;
getVersion: () => number;
forgetPeer: (editorId: string) => void;
reseed: (value: string, options: ReseedOptions) => void;
destroy: () => void;
};
// a JSON object whose shape is the editor's own: hand it on as it is
type SharedRegisters = Record<string, unknown> & {
readonly [registersBrand]: true;
};
type ReseedOptions = {
lww: SharedRegisters;
version: number;
keepScreen?: boolean; // default false
};
// example
const sharedStore = editor.getSharedStore();
@dineug/erd-editor هیچیک از این نوعها را با نام صادر نمیکند. کد TypeScript از طریق ErdEditorElement به آنها میرسد، مانند ReturnType<ErdEditorElement['getSharedStore']>.
هر کنش یک شیء سادهٔ قابل سریالسازی است که یک تغییر در سند را توصیف میکند، بنابراین در مسیر رسیدن به لایهٔ انتقال، از JSON.stringify سالم عبور میکند.
کنشها بهصورت دستهای میرسند: subscribe یک آرایه به شما میدهد و آن آرایه یک واحد است — آن را یکجا بازارسال کنید و در سمت دیگر نیز یکجا به dispatch بدهید.
با هر کنش مانند دادهای غیرشفاف رفتار کنید و بهجای خواندن یا بازنویسی آن، آن را عیناً عبور دهید، زیرا اطلاعات کنترلیای که با خود دارد، مانند نسخهٔ آن، همان چیزی است که ویرایشگرها را همگام نگه میدارد.
بخشی از کارهایی که یک ویرایشگر انجام میدهد فقط روی همان ویرایشگر میماند.
آوردن یک جدول، یادداشت یا گروه جدول به جلو، که با انتخاب آن نیز رخ میدهد، ارسال نمیشود.
گزینههای Statements، Header، Write logical names into empty comments (از نسخهٔ 4.2.0) و Tables در زبانهٔ طرحواره SQL نیز ارسال نمیشوند، چون به پنجرهای تعلق دارند که در آن انجام شدهاند.
از نسخهٔ 4.1.0، کاوشگر نیز روی ویرایشگر خودش میماند: باز بودن یا نبودن آن، عرض آن، ردیفهای جمعشده، ردیفی که فوکوس صفحهکلید روی آن است، موقعیت پیمایش درخت و جستوجو و گزینههای آن ارسال نمیشوند.
برجستهسازیای هم که رفتن به یک کلید خارجی روی خط اتصال رابطهٔ آن ایجاد میکند ارسال نمیشود.
از نسخهٔ 4.2.0، زبانهٔ واژهنامه نیز روی ویرایشگر خودش میماند: اینکه کدام برگه نمایش داده میشود و جستوجو، انتخاب، موقعیت پیمایش و عرض ستونهای هر برگه ارسال نمیشوند. اما ویرایشها، مرتبسازیها و وارد کردن فایلهای CSV در آن ارسال میشوند.
پیمایش، بزرگنمایی یا تعویض زبانه ارسال میشود، اما هرگز نما یا زبانهٔ کاربر دیگری را جابهجا نمیکند. این شامل پیمایشی که پرش از کاوشگر ایجاد میکند، رفتن به زبانهٔ ERD هنگام باز شدن کاوشگر از زبانهای دیگر، و تعویض زبانه و پیمایشی که پرش از برگهٔ Checks در زبانهٔ واژهنامه به یک جدول یا ستون ایجاد میکند نیز میشود. پرش از آن برگه به یک واژه، اصطلاح یا دامنه در زبانهٔ واژهنامه میماند، بنابراین هیچ بخشی از آن ارسال نمیشود.
از نسخهٔ 4.2.0، تغییر نمایش نامها نیز ارسال میشود و قفل آن تعیین میکند که ویرایشگرهای دیگر با آن چه کنند. قفل Name View در نمودار جدید و در هر سندی از پیش از نسخهٔ 4.2.0 روشن است.
تا وقتی قفل روشن است، تغییر نما فقط در ویرایشگری که آن را انجام داده است دیده میشود: همچنان ارسال میشود، اما همهٔ ویرایشگرهای دیگر و همهٔ رونوشتها آن را دور میریزند، بنابراین هر کاربر میتواند به نمای متفاوتی نگاه کند، در حالی که value نمای قفلشده را نگه میدارد.
تا وقتی قفل خاموش است، تغییری که در ویرایشگری با امکان ویرایش انجام شود، نمایش نامها را در همهٔ ویرایشگرها و رونوشتها تغییر میدهد، آخرین تغییر ملاک است و همهٔ آنها آن را ذخیره میکنند.
تغییری که خود یک ویرایشگر فقط خواندنی انجام میدهد همیشه روی همان ویرایشگر میماند و این ویرایشگر همچنان از تغییرهای مشترک ویرایشگرهای دیگر پیروی میکند.
از نسخهٔ 5.1.0، تغییر زبان مولد کد، شیوهٔ نگارش نام جدول، شیوهٔ نگارش نام ستون یا نوع علامت نقلقول نیز از قفل خودش (Language، Table Name Case، Column Name Case یا Bracket Type) به همین شیوه پیروی میکند، با یک تفاوت: تا وقتی قفل روشن است، تغییر اصلاً ارسال نمیشود.
این تغییر فقط در ویرایشگری دیده میشود که آن را انجام داده است و زبانههای مولد کد و طرحواره SQL آن از آن پیروی میکنند؛ هیچ ویرایشگر یا رونوشت دیگری آن را نمیبیند. value و runtimeValue مقدار قفلشده را نگه میدارند، بنابراین ویرایشگر تازهواردی که از هر ویرایشگری مقداردهی اولیه شود نیز آن را نمیبیند، و تا وقتی قفل روشن است هر کاربر میتواند به زبان، شیوهٔ نگارش نام یا نوع علامت نقلقول متفاوتی نگاه کند.
تا وقتی قفل خاموش است، تغییری که در ویرایشگری با امکان ویرایش انجام شود با نشانهٔ مشترک (shared: true در محتوای آن) ارسال میشود. این تغییر تنظیم را در همهٔ ویرایشگرها و رونوشتها عوض میکند، آخرین تغییر ملاک است و همهٔ آنها آن را ذخیره میکنند. ویرایشگر یا رونوشت نسخهٔ 5.1.0 تغییر نشانهدار را صرفنظر از وضعیت قفل خودش اعمال میکند، بنابراین تغییری که درست پس از باز کردن قفل انجام شود، حتی جایی که پیش از باز کردن قفل برسد، در همهجا مینشیند.
پیش از نسخهٔ 5.1.0، چنین تغییری چه قفل روشن بود چه نه به همهٔ ویرایشگرها و رونوشتها میرسید، در حالی که فایل مقدار قفلشده را نگه میداشت.
از نسخهٔ 5.0.0، یک ویرایشگر فقط خواندنی هیچ تغییری ارسال نمیکند. پیمایش، بزرگنمایی، زبانه، نمایش نامها، پایگاه داده، زبان Code Generator، شیوهٔ نگارش نامها، نوع علامت نقلقول و ردیفهای View Option که خوانندهٔ آن تغییر میدهد، هر قفلی که داشته باشند، روی صفحهٔ همان ویرایشگر میمانند؛ پیش از 5.0.0، پیمایشها، بزرگنماییها، تعویض زبانهها، پایگاه داده و تنظیمات کد آن مانند ویرایشگر قابلویرایش ارسال میشدند.
مخزن آن همچنان آنچه ردیابهایش از نشانگر ماوس، فوکوس، انتخاب و مستطیل انتخاب خواننده میفرستند ارسال میکند، به ثباتهایی که ویرایشگر تازهواردشده میخواهد پاسخ میدهد و همهٔ تغییرهایی را که دیگران میفرستند اعمال میکند. تغییر پایگاه داده، یک تنظیم مولد کد یا یک ردیف View Option به سند آن میرسد، و به صفحهٔ آن هم میرسد مگر اینکه خوانندهٔ آن همان تنظیم را همانجا تغییر داده باشد، و تغییر مشترک نمایش نامها در هر دو حالت روی صفحهٔ آن دیده میشود. از نسخهٔ 5.1.0، یک تنظیم مولد کد را فقط وقتی دریافت میکند که آن تنظیم با قفل خاموش تغییر کرده باشد یا یک باز کردن قفل آن را با خود داشته باشد.
وقتی ویرایشگر فقط خواندنی میشود، ابتدا آنچه مخزن هنوز از یک کشیدن یا پیمایش نگه داشته است را ارسال میکند، همانطور که flushStreamBuffers انجام میدهد، تا دیگران آخرین بخش آن را داشته باشند.
قفلها مشترکاند: آخرین قفل کردن یا باز کردن قفل یک تنظیم در همهٔ ویرایشگرها ملاک است و هر قفل مقادیر ویرایشگری را که آن را روشن کرده است با خود دارد، بنابراین همهٔ ویرایشگرها و رونوشتها مقدار یکسانی را ذخیره میکنند.
به همین دلیل قفل Viewport نمای ویرایشگری را ذخیره میکند که آن را روشن کرده است و قفل Canvas Type آخرین زبانهای را ذخیره میکند که آن ویرایشگر پیش از زبانهٔ تنظیمات، یعنی جایی که قفلها روشن میشوند، روی آن بوده است.
خاموش کردن قفل Language، Table Name Case، Column Name Case، Bracket Type یا از نسخهٔ 4.2.0، Name View همچنین آن تنظیم را در همهٔ ویرایشگرها روی مقداری قرار میدهد که در ویرایشگری که قفل را خاموش کرده است نمایش داده میشود، از جمله تغییری که خود آن ویرایشگر زیر قفل انجام داده است، تا همه همچنان یک مقدار را ذخیره کنند. خاموش کردن قفل Viewport یا Canvas Type نما یا زبانهٔ هیچکس را جابهجا نمیکند.
ویرایش اسکریپت Before tables یا After tables هنگامی که فیلد آن فوکوس را از دست میدهد، بهطور کامل ارسال میشود. دو اسکریپت جداگانه حلوفصل میشوند، بنابراین ویرایش یک همکار در یکی هرگز دیگری را بازنویسی نمیکند.
هیچ کاری که در حالت جریان زبانهٔ مصورسازی انجام میشود تغییری در سند نیست، بنابراین ویرایشگری که در حالت جریان است هیچ تغییری برای دیگران ارسال نمیکند و تغییراتی که دیگران ارسال میکنند تا زمانی که در آنجاست همچنان اعمال میشوند.
دو استثنا وجود دارد. ترک حالت جریان و رفتن به زبانهای دیگر یک تعویض زبانه است که مانند هر تعویض زبانهٔ دیگری ارسال میشود. از نسخهٔ 4.2.0، انتخاب یک گزینه در فهرست نمایش نامها در نوار ابزار حالت جریان یک تغییر نمایش نامهاست که مانند تغییری که روی بوم انجام شود، ارسال و اعمال میشود.
Previous table، Next table و کلیدهای واگرد و ازنو، که در حالت جریان گامبهگام میان نماها حرکت میکنند، ارسال نمیشوند.
دکمهٔ پیوند خارجی کارت، نتیجهای از جستوجوی سریع که پس از #، @ یا : انتخاب شود و باز کردن کاوشگر همگی حالت جریان را ترک میکنند و به زبانهٔ ERD میروند. پیمایشی که دکمهٔ کارت یا نتیجهٔ جستوجوی سریع در آنجا ایجاد میکند نیز ارسال میشود.
دو ویرایشگر در یک صفحه
اتصال subscribe به dispatch در اینجا جای شبکه را میگیرد تا بتوانید شکل یک نشست را بدون اینکه لایهٔ انتقالی در میان باشد ببینید.
import '@dineug/erd-editor/erd-editor.js';
const editor1 = document.createElement('erd-editor');
const editor2 = document.createElement('erd-editor');
const sharedStore1 = editor1.getSharedStore({
getNickname: () => 'editor1',
});
const sharedStore2 = editor2.getSharedStore({
getNickname: () => 'editor2',
});
sharedStore1.subscribe(actions => {
sharedStore2.dispatch(actions);
});
sharedStore2.subscribe(actions => {
sharedStore1.dispatch(actions);
});
هر دو ویرایشگر در اینجا از یک سند جدید و خالی یکسان شروع میکنند، بنابراین هیچکدام نیازی به مقداردهی اولیه ندارد.
با سه ویرایشگر یا بیشتر، دستههای هر ویرایشگر را به همهٔ ویرایشگرهای دیگر بفرستید: یک ویرایشگر هرگز آنچه را دریافت کرده است به دیگران نمیفرستد.
مقداردهی اولیهٔ یک همکار
مخزن مشترک تغییرات را همانطور که انجام میشوند بازارسال میکند و هرگز سند را در وضعیت فعلیاش به ویرایشگر تازهوارد تحویل نمیدهد، بنابراین به ویرایشگری که به نشستی در حال اجرا میپیوندد باید ابتدا سند داده شود.
از نسخهٔ 4.0.0، آن را با runtimeValue از ویرایشگری که از قبل در نشست است مقداردهی اولیه کنید، نه با value یا فایل ذخیرهشده.
اتاقی که با @dineug/erd-editor-yjs متصل شده باشد، بهمحض اینکه یک کلاینت آن را مقداردهی اولیه کند، خودش سند را نگه میدارد، بنابراین هر ویرایشگر متصل به آن بدون اینکه runtimeValue تحویل داده شود آن سند را باز میکند.
editor2.setInitialValue(editor1.runtimeValue);
const sharedStore2 = editor2.getSharedStore();
مقدار زمان اجرا هنوز آنچه را از زمان باز شدن سند حذف شده است در خود دارد، بنابراین وقتی ویرایشگر دیگری بعداً یک حذف را واگرد میکند، ویرایشگر تازهوارد جدول را با نام و ستونهایش برمیگرداند.
value شکلی است که یک فایل نگه میدارد، بدون موجودیتهای حذفشده، بنابراین ویرایشگر تازهواردی که از آن یا از فایل مقداردهی اولیه شده باشد، بهجای آن یک جدول خالی و بینام برمیگرداند.
از نسخهٔ 4.2.0، همین موضوع دربارهٔ واژه، اصطلاح یا دامنهای که از یکی از برگههای واژهنامه حذف شده باشد نیز صدق میکند: وقتی ویرایشگر دیگری آن حذف را واگرد کند، ویرایشگر تازهواردی که از runtimeValue مقداردهی اولیه شده باشد ردیف را دوباره بهطور کامل فهرست میکند و ویرایشگری که از value مقداردهی اولیه شده باشد یک ردیف خالی فهرست میکند که سپس value خود آن ویرایشگر آن را کنار میگذارد.
همچنان value را در محل ذخیرهسازی بنویسید: runtimeValue فقط برای مقداردهی اولیهٔ ویرایشگری دیگر، نمای دوم یا یک replicationStore است.
ویرایشگرهای VS Code، Obsidian، یک IDE از JetBrains و برنامهٔ وب، نمای دوم یک سند باز را به همین روش مقداردهی اولیه میکنند.
setInitialValue بازارسال نمیشود، بنابراین مقداردهی اولیهٔ ویرایشگر تازهوارد چیزی را در دیگران تغییر نمیدهد.
از نسخهٔ 4.0.0، این متد ثباتهای همکاری ویرایشگر را نیز، که ویرایشهای همزمان را حلوفصل میکنند، دور میریزد. اگر مخزن مشترک ویرایشگر قبلاً مشترکی داشته باشد، مخزن مانند نخستین subscribe خود، دوباره ثباتهای ویرایشگرهای دیگر را از آنها درخواست میکند تا ویرایشگری که در میانهٔ یک نشست دوباره بارگذاری شده است، ویرایشها را به همان شیوهٔ دیگران حلوفصل کند.
انتساب value ثباتها را نگه میدارد، اما برخلاف setInitialValue بازارسال میشود: وقتی ویرایشگر مخزن مشترکی داشته باشد، همهٔ ویرایشگرهای نشست سند انتسابیافته را بارگذاری میکنند، پس هرگز ویرایشگر تازهوارد را اینگونه مقداردهی اولیه نکنید.
نه value و نه runtimeValue ثباتها و نسخهای را که ساعت ویرایشگر به آن رسیده است در خود ندارند، بنابراین ویرایشگر تازهواردی که فقط از runtimeValue مقداردهی اولیه شده باشد، آنها را از پاسخی میگیرد که ویرایشگرهای نشست به نخستین subscribe آن میفرستند.
تا رسیدن آن پاسخ، ویرایشی که ویرایشگر تازهوارد انجام میدهد میتواند نسخهای پایینتر از نسخهٔ دیگران داشته باشد، پس آنها آن را رد میکنند در حالی که روی ویرایشگر تازهوارد میماند، و نوشتهٔ قدیمیتری که هنوز در راه است روی نوشتهٔ جدیدتری که مقدار اولیه نگه میدارد مینشیند. جایی که هیچ ویرایشگر در حال اجرایی پاسخ نمیدهد، مانند وقتی که سند نشست را یک سرور یا یک مخزن سند نگه میدارد، ویرایشگر تازهوارد هرگز آنها را به دست نمیآورد.
از نسخهٔ 5.1.0، آنها را همراه مقدار تحویل دهید. روی یکی از ویرایشگرهای نشست flushStreamBuffers() را فراخوانی کنید تا کشیدن یا تغییر رنگی که هنوز نگه داشته است ابتدا ارسال شود، سپس runtimeValue و getLWW() و getVersion() مخزن آن را در یک لحظه بخوانید. ویرایشگر تازهوارد مقدار را با setInitialValue بارگذاری میکند و سپس بقیه را با mergeLWW مخزن خودش، به همین ترتیب، میگیرد، چون هر setInitialValue ثباتها را دور میریزد. ویرایش بعدی آن سپس نسخهای فراتر از همهٔ نسخههایی که مقدار اولیه نگه میدارد خواهد داشت، پس بدون انتظار برای پاسخی مینشیند. روی مخزنی که از قبل وجود دارد، reseed هر دو را در یک فراخوانی انجام میدهد.
// on an editor already in the session
sharedStore1.flushStreamBuffers();
const seed = {
value: editor1.runtimeValue,
lww: sharedStore1.getLWW(),
version: sharedStore1.getVersion(),
};
// on the joiner
editor2.setInitialValue(seed.value);
const sharedStore2 = editor2.getSharedStore();
sharedStore2.mergeLWW(seed.lww, seed.version);
مقدار اولیهای که به این شکل برای باز کردن ویرایشگرهای تازهوارد بعدی نگه داشته شود، هر سه را با هم دارد. فایل نیست: همچنان value چیزی است که باید در محل ذخیرهسازی نوشته شود.
replicationStore هیچ ثباتی تحویل نمیدهد، بنابراین ویرایشگر تازهواردی که از runtimeValue آن مقداردهی اولیه شده باشد همچنان آنها را از پاسخ ویرایشگرها میگیرد.
ویرایشهای همزمان
هر ویرایشگر و هر رونوشت، برای هر نام و تقریباً هر فیلد دیگر، نسخهٔ نوشتهای را که آن را تعیین کرده است نگه میدارد: اینها ثباتهای همکاری آن هستند. یک نوشته فقط وقتی مینشیند که نسخهٔ آن پایینتر از نسخهٔ نگهداشتهشده نباشد، بنابراین ویرایشگرهایی که همان تغییرها را با ترتیبهای متفاوت میشنوند به یک سند یکسان میرسند.
از نسخهٔ 5.1.0 هر نسخه، زیر شمارندهاش، جایگاهی از خود ویرایشگر نویسنده دارد که از شناسهٔ آن گرفته میشود. بنابراین نسخهها با گامهای 4,194,304 رشد میکنند و وقتی شمارنده به 512 برسد از عدد صحیح 32 بیتی فراتر میروند. JSON.stringify و JSON.parse آنها را سالم منتقل میکنند، اما بازارسالکننده یا مخزنی که آنها را در زبانی دیگر تجزیه میکند باید آنها را بهصورت عدد 64 بیتی نگه دارد، نه عدد صحیح 32 بیتی.
از نسخهٔ 5.1.0، دو ویرایشگری که یک نام یا فیلد را در یک لحظه تغییر میدهند، جز استثناهای زیر، در همهٔ ویرایشگرها و رونوشتها با مقدار یکسانی تمام میشوند: چون با شمارندهٔ یکسانی مینویسند، دو نسخهٔ متفاوت ثبت میکنند و نسخهٔ بزرگتر در همهجا برنده است. پیش از نسخهٔ 5.1.0 هر دو میتوانستند یک نسخه ثبت کنند و هر ویرایشگر آخرین نسخهای را که شنیده بود نگه میداشت، بنابراین میتوانستند ناهمسان تمام شوند. دو ویرایشگر با احتمال 1 در 4,194,304 برای هر جفت، جایگاه یکسانی دارند و آنگاه مانند قبل مساوی میشوند.
از نسخهٔ 5.1.0، موقعیت یک جدول، موقعیت و اندازهٔ یک یادداشت یا گروه جدول، و مبدأ و سطح بزرگنمایی نما به همین شیوه نسخهدار هستند و آنچه آنها را جابهجا میکند بهصورت جایی که پایان مییابد ارسال میشود:
- یک کشیدن بهصورت یک
table.moveTo،memo.moveToیاtableGroup.moveToبرای هر موجودیت جابهجاشده، در یک دسته، بنابراین کشیدن یک گروه نقطههای جدولهایش را همراه نقطهٔ گروه میبرد؛ - واگرد یا ازنوی یک کشیدن بهصورت نقطهای که هر موجودیت را در آن قرار میدهد؛
- یک جابهجایی نما بهصورت
settings.scrollToو یک بزرگنمایی بهصورتsettings.changeZoomLevel؛ - تغییر اندازهٔ یک یادداشت یا گروه جدول بهصورت موقعیت و اندازهٔ آن با هم.
بنابراین دو کاربری که یک جدول، یادداشت یا گروه جدول را در یک لحظه جابهجا میکنند، یا جابهجا و تغییر اندازه میدهند، در همهٔ ویرایشگرها و رونوشتها با یک نقطه و یک اندازه تمام میشوند. نقطه به نوشتهای با نسخهٔ بزرگتر میرسد، هر دو محور با هم. جابهجایی اندازهای نمینویسد، بنابراین تغییر اندازه اندازهٔ خود را نگه میدارد، حتی جایی که جابهجایی همزمان نقطه را بگیرد.
پیش از نسخهٔ 5.1.0 یک کشیدن بهصورت فاصلهٔ طیشده ارسال میشد، بنابراین دو کشیدن یک جدول با هم جمع میشدند و جابهجایی و تغییر اندازهٔ همزمان یک یادداشت یا گروه جدول میتوانست ناهمسان تمام شود.
کشیدنی کمتر از 20 px، که هیچ ورودی واگردی باقی نمیگذارد، مانند هر کشیدن دیگر ارسال میشود، بنابراین بهصورت یک نقطه میتواند بر کشیدن همان موجودیت که کاربر دیگری در همان لحظه انجام داده است غلبه کند. دستهای از کشیدن، جابهجایی نما یا بزرگنمایی که یک لایهٔ انتقال دو بار تحویل دهد، هیچ چیز را دو بار جابهجا نمیکند.
تغییر رنگ یک استثنا است. بدون نسخه ارسال میشود و هر ویرایشگر و رونوشت آن را با نسخهٔ خودش ثبت میکند و رنگی را نگه میدارد که آخر شنیده است، بنابراین دو کاربری که یک جدول، یادداشت یا گروه جدول را در یک لحظه رنگ میکنند میتوانند با رنگهای متفاوت تمام شوند.
چند تغییر اصلاً نسخه ندارند، بنابراین هر ویرایشگر و رونوشت آنها را به ترتیبی که میشنود اعمال میکند و دو تغییر همزمان نیز میتوانند ناهمسان تمام شوند: جابهجا کردن یک ستون درون جدول یا شاخص خودش (column.move، indexColumn.move) و تغییر پایگاه داده، یک ردیف View Option یا Relationship DataType Sync، Maximum comment width یا Column Order در زبانهٔ تنظیمات.
موجودیتهایی که دو کاربر در یک لحظه اضافه میکنند، مانند دو جدول یا دو ستون از یک جدول، نیز میتوانند در هر ویرایشگر و رونوشت به ترتیبی متفاوت قرار بگیرند و value هر یک ترتیب خودش را ذخیره میکند.
همهٔ اینها میان ویرایشگرها و رونوشتهای نسخهٔ 5.1.0 یا بالاتر برقرار است؛ ترکیب نسخهها میگوید نسخهای قدیمیتر چه چیزی را تغییر میدهد.
ترکیب نسخهها
هر ویرایشگر فقط انواع کنشی را اعمال میکند که نسخهٔ خودش میشناسد، بنابراین در نشستی که نسخههای مختلف را با هم ترکیب میکند، ویرایشگرهای قدیمیتر هر آنچه را که با نوع جدیدتری منتقل میشود از دست میدهند.
از نسخهٔ 3.10.0، تغییر ON DELETE یا ON UPDATE یک رابطه بهصورت یکی از دو نوع کنش جدید، relationship.changeOnDelete و relationship.changeOnUpdate، منتقل میشود و relationship.add میتواند هر دو را با خود داشته باشد. بازارسالکنندهای که کنشها را عیناً عبور میدهد برای آنها به چیز تازهای نیاز ندارد.
ویرایشگری متعلق به پیش از نسخهٔ 3.10.0 این انواع کنش و فیلدها را نادیده میگیرد: هرگز از ON DELETE یا ON UPDATE یک رابطه آگاه نمیشود و سندی که از آن ذخیره شود هیچکدام را ندارد. رابطهای که ویرایشگری قدیمیتر اضافه کند بدون آنها میرسد، بنابراین هر دو با Not set شروع میشوند.
هر تغییر دیگری که ویرایشگری با نسخهٔ 3.10.0 ارسال میکند با انواع کنشی منتقل میشود که ویرایشگرهای قدیمیتر از قبل میشناسند.
Replace All در یافتن و جایگزینی ویرایشهایش را بهصورت یک دسته از همان کنشهای تغییر نام، توضیح و یادداشت ارسال میکند که یک ویرایش دستی ارسال میکند. گزینههای نمایش Alternate Key و Referential Actions با کنش موجود settings.changeShow منتقل میشوند.
از نسخهٔ 4.0.0، این تغییرات با انواع کنش جدید منتقل میشوند و بازارسالکنندهای که کنشها را عیناً عبور میدهد برای آنها به چیز تازهای نیاز ندارد:
- افزودن، جابهجایی، تغییر اندازه، تغییر نام، تغییر رنگ یا حذف یک گروه جدول:
tableGroup.add،tableGroup.move،tableGroup.moveTo،tableGroup.resize،tableGroup.changeName،tableGroup.changeColorوtableGroup.remove؛ پیوستن یک جدول به گروه یا خارج شدن آن از گروه:table.changeGroup؛ Saveدر نگاشت ستونها برای یک رابطهٔ موجود، که هر دو فهرست ستون آن را یکجا تعیین میکند:relationship.changeColumns؛- روشن یا خاموش کردن یک قفل:
settings.changeLockSettings؛ - ویرایش اسکریپت
Before tablesیاAfter tablesدر زبانهٔ طرحواره SQL:settings.changeDDLScript.
گزینههای نمایش Table Groups و Memos با کنش موجود settings.changeShow منتقل میشوند.
settings.changeIgnoreSaveSettings، که کلیدهای روشن/خاموش Save Scroll Information و Save Zoom Information پیش از آنکه قفلها جایگزینشان شوند ارسال میکردند، دیگر ارسال نمیشود و settings.changeRelationshipOptimization حذف شده است. ویرایشگری با نسخهٔ 4.0.0 که هر یک از این دو را دریافت کند چیزی را تغییر نمیدهد.
ویرایشگری متعلق به پیش از نسخهٔ 4.0.0 انواع کنش جدید را نادیده میگیرد: هیچگاه گروه جدول یا جدولهایی را که در آن قرار دارند نمیبیند، هرچند کشیدن یک گروه همچنان جدولهای آن گروه را در آنجا جابهجا میکند، زیرا جابهجایی هر یک از آن جدولها را نیز ارسال میکند.
این ویرایشگر پس از Save در نگاشت ستونها، ستونهای قدیمی رابطه را نگه میدارد و وقتی ستونی از آن نگاشت قدیمی در این ویرایشگر حذف شود، رابطه در همهٔ ویرایشگرها از بین میرود. نه قفلی دارد و نه اسکریپتی.
سندی که از چنین ویرایشگری ذخیره شود هیچیک از اینها را ندارد و ویرایشگری با نسخهٔ 4.0.0 آن را با همهٔ قفلها در حالت روشن باز میکند.
همهٔ ویرایشگرهای یک نشست و هر replicationStore را که سند آن را ذخیره میکند، روی نسخهٔ 4.0.0 یا بالاتر نگه دارید.
ویرایشگری با نسخهٔ 4.1.0 هیچ نوع کنش جدیدی ارسال نمیکند، بنابراین ویرایشگرها و رونوشتهای نسخهٔ 4.0.0 و 4.1.0 بدون اینکه چیزی از دست برود با هم در یک نشست شرکت میکنند.
یافتن و جایگزینی در این نسخه نام شاخصها و نام گروههای جدول را نیز جستوجو میکند و Replace و Replace All آنها را با کنشهای index.changeName و tableGroup.changeName تغییر نام میدهند که ویرایشگری با نسخهٔ 4.0.0 از قبل اعمال میکند.
از نسخهٔ 4.2.0، این تغییرات با انواع کنش جدید منتقل میشوند و بازارسالکنندهای که کنشها را عیناً عبور میدهد برای آنها به چیز تازهای نیاز ندارد:
- نام منطقی یک جدول یا ستون:
table.changeLogicalNameوcolumn.changeLogicalName؛ اینکه نام آن از واژهنامهها استخراج شده است یا نه:table.changeNameDerivedوcolumn.changeNameDerived؛ - پیوند دادن یک ستون به یک دامنه یا قطع پیوند آن:
column.changeDomain؛ - افزودن، تغییر (از جمله جای آن در برگه، آنگونه که مرتبسازی تعیین میکند) یا حذف یک واژه، اصطلاح یا دامنه در زبانهٔ واژهنامه:
dictionary.add،dictionary.updateوdictionary.remove؛ - تغییر نمایش نامها:
settings.changeNameViewMode.
قفل Name View با کنش موجود settings.changeLockSettings، گزینهٔ نمایش Domain با settings.changeShow و جابهجایی Logical Name یا Domain در ترتیب ستونها با settings.changeColumnOrder منتقل میشود.
کنشهای editor.clear و editor.loadJson یک وارد کردن طرحواره SQL، GraphQL، DBML یا AML از طریق Import، keepDictionaries: true را با خود دارند که واژهها، اصطلاحات و دامنهها را در همهٔ ویرایشگرها نگه میدارد. کنشهای setSchemaSQL، setSchemaGraphQL، setSchemaDBML یا setSchemaAML در حالت جایگزینی نیز همینطورند.
نام فیزیکیای که واژهنامهها استخراج میکنند با table.changeName یا column.changeName و نوع دادهای که یک دامنه به ستونهایش میدهد با column.changeDataType منتقل میشود، یعنی همان کنشهایی که یک ویرایش دستی ارسال میکند.
ویرایشگری از پیش از نسخهٔ 4.2.0 انواع کنش جدید را نادیده میگیرد: نه نام منطقی دارد، نه پیوند دامنه، نه واژهنامه و نه نمایش نامها. قفل کردن یا باز کردن قفل Name View در آنجا چیزی را تغییر نمیدهد و جابهجایی Logical Name یا Domain در ترتیب ستونها، یا جابهجایی ردیف دیگری روی یکی از آن دو، نیز همینطور. قفل Canvas Type هم که ویرایشگری روشن کرده باشد که از زبانهٔ واژهنامه به زبانهٔ تنظیمات آمده است، چیزی را تغییر نمیدهد: ویرایشگر قدیمیتر آن زبانه را نمیشناسد، بنابراین Canvas Type را بدون قفل نگه میدارد. این ویرایشگر همچنان نامهای فیزیکیای را که واژهنامهها استخراج میکنند و انواع دادهای را که دامنهها میدهند نشان میدهد.
ویرایشهای خود آن چیزی از نامهای منطقی، دامنهها یا واژهنامهها نمیدانند و این اثرها را بر ویرایشگرهای جدیدتر دارند:
- جدول یا ستونی که این ویرایشگر بهصورت دستی تغییر نام دهد، نشانهٔ استخراجشده بودن نامش را حفظ میکند، بنابراین نام منطقیای که بعدها در ویرایشگری جدیدتر برای آن نوشته شود، میتواند نام را دوباره استخراج کند و جایگزین نامی کند که این ویرایشگر تایپ کرده بود.
- نوع دادهای که این ویرایشگر به ستونی پیوندخورده به یک دامنه بدهد، پیوند را باقی میگذارد، بنابراین برگهٔ
ChecksبررسیDomain type mismatchرا فهرست میکند و تغییر بعدی نوع دامنه، نوع دامنه را دوباره به ستون میدهد. - ستونهای کلید خارجی رابطهای که این ویرایشگر اضافه کند، هیچ نام منطقی یا دامنهای از کلید خود نمیگیرند.
- جدولی که این ویرایشگر جایگذاری یا تکثیر کند، بدون نام منطقی یا پیوند دامنه میرسد.
- وارد کردن طرحواره SQL، GraphQL، DBML یا AML در این ویرایشگر هیچ
keepDictionariesارسال نمیکند، بنابراین واژهها، اصطلاحات و دامنهها را در همهٔ ویرایشگرها خالی میکند. - واگرد یک بارگذاری، یک وارد کردن یا
clear()در این ویرایشگر، کپی خود آن از سند را در همهٔ ویرایشگرها بارگذاری میکند و آن کپی هیچ نام منطقی، پیوند دامنه یا واژهنامهای ندارد. - آن کپی و سندی که وارد کردن طرحواره SQL، GraphQL، DBML یا AML در این ویرایشگر بارگذاری میکند، قفل
Name Viewرا نیز در همهٔ ویرایشگرها به همان وضعیتی برمیگردانند که این ویرایشگر آن را یافته بود. سپس همهٔ ویرایشگرها نمایPhysical Namesرا در نمایش نامها ذخیره میکنند و اگر قفل خاموش باشد، آن را نشان هم میدهند.
سندی که از چنین ویرایشگری ذخیره شود هیچ نام منطقی، پیوند دامنه، واژهنامه یا نمایش نامهایی ندارد، بنابراین ویرایشگری با نسخهٔ 4.2.0 آن را در نمای Physical Names باز میکند. با این حال ویرایشگر قدیمیتر قفل Name View را همانطور که یافته بود ذخیره میکند، بنابراین سندی که قفل آن در ویرایشگری با نسخهٔ 4.2.0 باز شده باشد، بدون قفل میماند.
همهٔ ویرایشگرهای یک نشست و هر replicationStore را که سند آن را ذخیره میکند، روی نسخهٔ 4.2.0 یا بالاتر نگه دارید.
ویرایشگری با نسخهٔ 5.1.0 هیچ نوع کنش جدیدی ارسال نمیکند، بنابراین ویرایشگرها و رونوشتهای پیش از نسخهٔ 5.1.0 همچنان با آن در یک نشست شرکت میکنند و بازارسالکنندهای که کنشها را عیناً عبور میدهد به چیز تازهای نیاز ندارد. با این حال آنچه ویرایشهای همزمان توصیف میکند فقط میان ویرایشگرها و رونوشتهای 5.1.0 برقرار است:
- کشیدنهای ویرایشگری با نسخهٔ
5.1.0بهصورت نقطه رویtable.moveTo،memo.moveToوtableGroup.moveToمنتقل میشوند که ویرایشگرهای قدیمیتر از قبل اعمال میکنند، و جابهجاییهای نما و بزرگنماییهای آن بهصورت نقطه رویsettings.scrollToوsettings.changeZoomLevelکه، مانند هر جابهجایی نما و بزرگنمایی، هیچ ویرایشگر دیگری اعمال نمیکند و فقط رونوشتها میگیرند. ویرایشگر قدیمیتر هر نقطهٔ یک کشیدن را به ترتیب رسیدنش، خارج از هر ثبات، اعمال میکند و رونوشت قدیمیتر همین کار را با هر نقطهٔ یک کشیدن، جابهجایی نما یا بزرگنمایی میکند، بنابراین دو نقطهٔ همزمان برای یک موجودیت یا برای نما میتوانند آنجا ناهمسان تمام شوند. - کشیدن ویرایشگر قدیمیتر همچنان بهصورت فاصلهٔ طیشده منتقل میشود که هر ویرایشگر و رونوشت خارج از ثباتهای خود جمع میکند، و جابهجایی نما یا بزرگنمایی آن نیز بهصورت فاصله است که هر رونوشت به همان شیوه جمع میکند. فاصله و نقطهای که همزمان برای یک موجودیت انجام شوند میتوانند روی ویرایشگرها و رونوشتهایی که آنها را با ترتیبهای متفاوت میشنوند ناهمسان تمام شوند، و فاصلهای که یک لایهٔ انتقال دو بار تحویل دهد دو بار جمع میشود.
- خارج از استثناهایی که ویرایشهای همزمان نام میبرد، نوشتهٔ ویرایشگری با نسخهٔ
5.1.0از یک نام یا فیلد که همزمان با نوشتهٔ ویرایشگر قدیمیتری از آن انجام شود تقریباً همیشه برنده است، با پاسخ یکسان در هر ویرایشگر و رونوشت. دو ویرایشگر قدیمیتر همچنان میتوانند بر سر یک فیلد که همزمان نوشته شود ناهمسان تمام شوند. - ویرایشگری با نسخهٔ
5.1.0تغییر زبان مولد کد، شیوهٔ نگارش نام یا نوع علامت نقلقول را فقط وقتی قفل آن خاموش است ارسال میکند، با نشانهٔshared: trueکه ویرایشگر قدیمیتر نادیده میگیرد و تغییر را مانند قبل اعمال میکند. ویرایشگر قدیمیتر همچنان تغییری را که زیر قفل انجام میدهد، بدون نشانه، ارسال میکند: ویرایشگر یا رونوشت5.1.0تا وقتی آن تنظیم آنجا قفل است آن را دور میریزد و ویرایشگرهای قدیمیتر آن را اعمال میکنند. بنابراین زیر قفل، ویرایشگرهای قدیمیتر از انتخاب یکدیگر پیروی میکنند در حالی که ویرایشگرهای5.1.0انتخاب خودشان را نگه میدارند، و فایل در هر دو حال مقدار قفلشده را نگه میدارد. باز کردن قفل در هر یک از دو نسخه، مقدار کسی را که قفل را باز میکند به همهٔ ویرایشگرها و رونوشتها میرساند. - بارگذاریای که سند را جایگزین میکند، مانند
valueانتسابیافته،clear()یا یک وارد کردن جایگزینکننده، به رابطهای که در حال کشیده شدن است در هر ویرایشگر نسخهٔ5.1.0پایان میدهد، هم در ویرایشگری که آن را انجام داده و هم در هر ویرایشگری که آن را دریافت میکند. ویرایشگر قدیمیتر کشیدن رابطهٔ خود را در طول آن بارگذاری فعال نگه میدارد.
همهٔ ویرایشگرهای یک نشست و هر replicationStore را که سند آن را ذخیره میکند روی نسخهٔ 5.1.0 یا بالاتر نگه دارید تا ویرایشهایی که در یک لحظه انجام میشوند در همهجا یکسان تمام شوند، جز استثناهایی که ویرایشهای همزمان نام میبرد؛ 4.2.0 یا بالاتر همچنان چیزی است که نامهای منطقی و واژهنامهها را نگه میدارد. یک سرور MCP پیش از نسخهٔ 1.2.0 در اینجا ویرایشگری پیش از نسخهٔ 5.1.0 به حساب میآید و ویرایشگری پیش از نسخهٔ 5.1.0 را اصلاً نمیتوان به اتاق Yjs متصل کرد.
SharedStoreConfig
getNickname
نام مستعاری را تعیین میکند که در ویرایشگرهای دیگر کنار نشانگر ماوس این کاربر نمایش داده میشود.
وقتی نام مستعار وجود ندارد یا خالی است، کاربران دیگر user را میبینند.
editor.getSharedStore({
getNickname: () => 'nickname...',
});
mouseTracker
نشانگر ماوس این کاربر را برای ویرایشگرهای دیگر پخش میکند. مقدار پیشفرض true است.
نشانگرهایی که کاربران دیگر ارسال میکنند همیشه روی بوم ERD نمایش داده میشوند.
editor.getSharedStore({ mouseTracker: false });
focusTracker
آنچه را که این کاربر روی آن کار میکند پخش میکند. مقدار پیشفرض true است.
جدول و خانهای که روی آن فوکوس کردهاید، جدولها، یادداشتها و گروههای جدولی که انتخاب کردهاید و مستطیلی که روی بوم میکشید، به ویرایشگرهای دیگر ارسال و در آنجا رسم میشوند.
هر کاربر رنگ مخصوص به خود را دارد تا بتوانید آنها را از هم تشخیص دهید: حاشیهای روی جدول دارای فوکوس، خطی زیر خانهٔ دارای فوکوس، حلقهای دور جدولها، یادداشتها و گروههای جدول انتخابشده و مستطیلی خطچین برای مستطیل انتخاب.
از نسخهٔ 4.2.0، کاربران میتوانند هر کدام به نمای متفاوتی از نمایش نامها نگاه کنند، تا وقتی قفل آن روشن است یا پس از تغییری که خود یک ویرایشگر فقط خواندنی انجام داده است. خانهٔ دارای فوکوسی که نمای شما آن را نشان نمیدهد، با خطی زیر خانهای مشخص میشود که نمای شما بهجای آن نشان میدهد: نام و نام منطقی بهجای یکدیگر نشان داده میشوند، همانطور که نوع داده و دامنه.
اطلاعات حضوری که از کاربران دیگر میرسد، چه این گزینه روشن باشد چه نباشد، همیشه روی بوم شما رسم میشود.
در حالت جریان زبانهٔ مصورسازی، فوکوس و انتخاب کاربران دیگر روی کارتهای جدول رسم میشود، اما مستطیلهای انتخاب آنها رسم نمیشود. جدولهایی که در آنجا انتخاب میکنید همچنان ارسال میشوند؛ مستطیلی که در آنجا میکشید ارسال نمیشود.
editor.getSharedStore({ focusTracker: false });
هر دو ردیاب را خاموش کنید تا از مخزن مشترک بهعنوان یک بازارسالکنندهٔ ساده استفاده کنید که هیچ اطلاعات حضوری از خودش منتشر نمیکند.
اطلاعات حضوری که ویرایشگرهای دیگر ارسال میکنند همچنان دریافت و رسم میشود.
ویرایشگرهای VS Code، Obsidian، یک IDE از JetBrains و Google Drive همین کار را انجام میدهند.
editor.getSharedStore({ mouseTracker: false, focusTracker: false });
نشانگر ماوس، فوکوس، انتخاب و مستطیل انتخاب در همان دنبالهٔ تغییرات سند منتقل میشوند، اما گذرا هستند.
آنها هرگز وارد سند، تاریخچهٔ واگرد یا editor.value نمیشوند، بنابراین لایهٔ انتقال میتواند آنها را دور بریزد و replicationStore آنها را نادیده میگیرد.
SharedStore
connection, disconnect
این متدها وضعیت فعلی اتصال را تعیین میکنند.
تا زمانی که اتصال قطع است، تغییرات بهصورت داخلی در بافر نگه داشته میشوند.
تغییرات بافرشده بهمحض اینکه انتقال دوباره ممکن شود، برای مشترکان ارسال میشوند.
وضعیت پیشفرض، متصل (connection) است.
sharedStore.connection();
sharedStore.disconnect();
dispatch, dispatchSync
تغییرات نمونههای دیگر ویرایشگر را روی نمونهٔ فعلی ویرایشگر اعمال میکند.
وقتی دستهای درخواست ثباتهای ویرایشگر دیگری را در خود دارد، مانند آنچه نخستین subscribe یک ویرایشگر تازهوارد میفرستد، مخزن از طریق مشترکانش با ثباتها و نسخهٔ خود پاسخ میدهد، مگر اینکه هیچ ثباتی نداشته باشد.
از نسخهٔ 5.1.0، ابتدا هر دستهٔ دنبالهای را که هنوز نگه داشته است ارسال میکند، همانطور که flushStreamBuffers انجام میدهد، تا هر نسخهای که پاسخ آن با خود دارد بر نوشتهای استوار باشد که برای دیگران ارسال شده است. بنابراین رسیدن یک ویرایشگر تازهوارد باعث میشود هر ویرایشگر نشست یک کشیدن، جابهجایی نما، بزرگنمایی، تغییر رنگ یا تغییر اندازهٔ یادداشت را که هنوز نگه داشته است، یکباره ارسال کند.
sharedStore.dispatch(actions); // async
sharedStore.dispatchSync(actions); // sync
subscribe
مشترک تغییرات ویرایشگر میشود.
تا زمانی که دستکم یک مشترک وجود نداشته باشد، هیچ چیزی از ویرایشگر خارج نمیشود و تغییراتی که پیش از آن انجام شوند در بافر نگه داشته میشوند.
نخستین subscribe همچنین ثباتهای همکاری ویرایشگرهای دیگر را، که ویرایشهای همزمان را حلوفصل میکنند، از آنها درخواست میکند تا ویرایشگری که دیرتر میپیوندد این ویرایشها را به همان شیوه حلوفصل کند.
این کار سند را با خود نمیآورد، پس ابتدا ویرایشگری را که دیرتر میپیوندد مقداردهی اولیه کنید؛ از نسخهٔ 5.1.0 مقدار اولیه میتواند ثباتها را هم با خود داشته باشد.
از نسخهٔ 4.0.0، مخزن هر بار که setInitialValue، یا از نسخهٔ 5.1.0 reseed، پس از آن نخستین subscribe سندی را در ویرایشگرش بارگذاری کند، دوباره درخواست میکند.
const unsubscribe = sharedStore.subscribe(actions => {
// send...
});
flushStreamBuffers
دستههایی از دنبالهها را که این مخزن هنوز نگه داشته است، بهجای ارسال پس از دورهٔ سکوتشان، همین حالا ارسال میکند.
از نسخهٔ 3.9.2، این متد روی مخزنی که از getSharedStore به دست میآید کار میکند؛ در 3.9.1 این متد در تعریف نوع وجود دارد اما کاری انجام نمیدهد.
جابهجا کردن یک جدول، یادداشت یا گروه جدول، تغییر رنگ آن، تغییر اندازهٔ یک یادداشت و پیمایش یا بزرگنمایی نما، هر یک بهصورت دنبالهای از تغییرات کوچک انجام میشوند. تغییر اندازهٔ گروه جدول چنین نیست: یک بار، هنگام پایان کشیدن، ارسال میشود.
مخزن هر دنباله را در یک دسته جمع میکند و آن را نگه میدارد تا دنباله به مدت 200 میلیثانیه ساکت بماند، در دو مرحله. تغییر رنگ یا تغییر اندازهٔ یادداشت از هر دو مرحله میگذرد، بنابراین حدود 400 میلیثانیه پس از آخرین تغییر ارسال میشود، همانطور که پیش از نسخهٔ 5.1.0 هر دنباله چنین بود. از نسخهٔ 5.1.0 یک کشیدن، جابهجایی نما یا بزرگنمایی پس از مرحلهٔ اول، حدود 200 میلیثانیه پس از آخرین گامش، بهصورت جایی که پایان مییابد ارسال میشود (ویرایشهای همزمان را ببینید).
فراخوانی این متد آن انتظار را در هر دو مرحله پایان میدهد. تا وقتی مخزن متصل است، مشترک دسته را پیش از بازگشت فراخوانی دریافت میکند. اگر چیزی نگه داشته نشده باشد، فراخوانی چیزی ارسال نمیکند.
destroy، چه متد خود مخزن و چه متد ویرایشگر، دستهای را که هنوز نگه داشته شده است دور میریزد، پس وقتی مخزنی را رها میکنید و دیگران باید آخرین تغییر را داشته باشند، مانند هنگام بسته شدن یک زبانه، ابتدا این متد را فراخوانی کنید.
sharedStore.flushStreamBuffers();
sharedStore.destroy();
getLWW
از نسخهٔ 5.1.0، یک کپی از ثباتهای همکاری ویرایشگر را برمیگرداند (ویرایشهای همزمان را ببینید).
این کپی از طریق JSON ساخته میشود، بنابراین یک شیء ساده و آمادهٔ JSON.stringify است و تغییر دادن آن ثباتهای مخزن را همانطور که بودند باقی میگذارد.
آن را عیناً به mergeLWW یا reseed مخزن دیگری بدهید. شکل آن به خود ویرایشگر مربوط است، پس هیچ فیلدی از آن را نخوانید.
آن را همراه getVersion و runtimeValue ویرایشگر در یک لحظه بخوانید تا ویرایشگر تازهوارد را مقداردهی اولیه کنید.
const lww = sharedStore.getLWW();
mergeLWW
از نسخهٔ 5.1.0، ثباتهایی را که مخزن دیگری با getLWW تحویل داده است، با نگه داشتن نسخهٔ بزرگتر هر کدام، به ثباتهای این مخزن وارد میکند و version را وارد ساعت ویرایشگر میکند، که از میان نسخهٔ خودش و نسخهٔ دادهشده، بزرگتر را نگه میدارد.
هیچ چیز را در سند تغییر نمیدهد: نه یک بایت از value یا runtimeValue، نه ورودی واگرد و نه رویداد change. فقط نسخههایی را بالا میبرد که یک نوشتهٔ بعدی باید از آنها بگذرد، بنابراین پس از آن نوشتهای قدیمیتر از ثباتهای دادهشده رد میشود و ویرایش بعدی ویرایشگر نسخهای فراتر از version دارد.
چیزی ارسال نمیکند و به چیزی پاسخ نمیدهد. همان چیزی است که نخستین subscribe یک ویرایشگر تازهوارد از پاسخ دیگران میگیرد، اینجا مستقیماً گرفته میشود.
آن را پس از setInitialValue فراخوانی کنید، نه پیش از آن: هر setInitialValue و هر reseed ثباتهای نگهداشتهشده را دور میریزد و با آنها آنچه یک mergeLWW پیش از آن گرفته بود.
sharedStore.mergeLWW(lww, version);
getVersion
از نسخهٔ 5.1.0، بالاترین نسخهای را برمیگرداند که ساعت ویرایشگر با خود ادغام کرده است: بزرگترین نسخه میان تغییرهایی که انجام داده یا گرفته است، درخواستهای ثباتها و پاسخهایی که یک پیوستن رد و بدل میکند، و هر version که به mergeLWW یا reseed داده شده است.
نشانگرهای ماوس، فوکوسها، انتخابها و مستطیلهای انتخاب، چه از خود ویرایشگر و چه از ویرایشگری دیگر، آن را جابهجا نمیکنند.
آن را همراه getLWW() که در یک لحظه خوانده شده است به mergeLWW یا reseed ویرایشگر تازهوارد تحویل دهید. این یک نسخه است، مانند نسخههایی که کنشهای آن با خود دارند.
const version = sharedStore.getVersion();
forgetPeer
از نسخهٔ 5.1.0، نشانگر ماوس، فوکوس، انتخاب و مستطیل انتخابی را که ویرایشگری با شناسهٔ دادهشده ارسال کرده است، و انقضای در انتظار هر یک را، بلافاصله حذف میکند. موارد هر ویرایشگر دیگر میمانند.
شناسه همان meta.editorId است که هر کنش ارسالی از مخزن مشترک آن ویرایشگر با خود دارد. شناسهای که این ویرایشگر چیزی از آن ندارد، چیزی را تغییر نمیدهد.
آن را وقتی فراخوانی کنید که لایهٔ انتقال شما متوجه رفتن یک همتا میشود. در غیر این صورت آنچه همتا فرستاده است تا انقضا رسمشده میماند: نشانگر ماوس آن 30 ثانیه پس از آخرین مورد دریافتی، فوکوس و انتخابش 90 ثانیه پس از آن و مستطیل انتخابش 3 ثانیه پس از آن.
sharedStore.forgetPeer(editorId);
reseed
از نسخهٔ 5.1.0، سند یک نشست را دوباره در ویرایشگر باز میکند، مانند یک پیوستن دوباره. اتصال Yjs آن را هنگام اتصال به اتاقی که مقداردهی اولیه شده است برای باز کردن سند اتاق فراخوانی میکند، و دوباره در هر پیوستن دوباره، با نگه داشتن صفحه پس از آنکه به اتاق پیوسته است.
value را مانند setInitialValue بارگذاری میکند و lww و version را مانند mergeLWW میگیرد، بنابراین مخزن سپس دقیقاً ثباتهای دادهشده را نگه میدارد و ساعتش از میان نسخهٔ خودش و version، بزرگتر را. همچنین تاریخچهٔ واگرد را خالی میکند و، برخلاف setInitialValue، انتخاب و فوکوس را دور میریزد، چون ممکن است به چیزی اشاره کنند که مقدار دیگر در خود ندارد.
جز استخراج نام فیزیکی از نام منطقی که در ادامه آمده است، هیچ ورودی واگردی نمیسازد، رویداد change ارسال نمیکند و هیچ تغییری نمیفرستد. وقتی مخزن قبلاً مشترکی داشته باشد، همان درخواست ثباتها را میفرستد که هر بارگذاری از این دست میفرستد و لایهٔ انتقالی که ثباتها را قبلاً تحویل داده است میتواند آن را دور بریزد، و، با روشن بودن focusTracker، انتخاب و فوکوس پاکشده را نیز.
مانند setInitialValue، در حالی که readonly تنظیم شده است نیز کار میکند، نمای جریان را کنار میگذارد، به رابطهای که در حال کشیده شدن است پایان میدهد و ویرایشگرهای یادداشت، نام گروه جدول و خانه را میبندد، و آنچه را در آنها تایپ شده است به همان شیوه نگه میدارد یا دور میریزد؛ نامی که یک خانهٔ نام منطقی در حال بسته شدن از آنچه خوانندهٔ آن تایپ کرده است استخراج میکند یک ویرایش معمولی است: ارسال میشود، قابل واگرد است و بهصورت رویداد change ارسال میشود.
بدون keepScreen، صفحه آنچه را مقدار در خود دارد نشان میدهد، مانند پس از setInitialValue. با keepScreen: true صفحهٔ خواننده روی سند بارگذاریشده بازگردانده میشود، فقط روی همان صفحه:
- موقعیت پیمایش و سطح بزرگنمایی، پس از آنکه عنصر آنها را نشان داده باشد؛ موردی که هرگز نشان داده نشده، یا در حالت پنهان بارگذاری شده و از آن پس نمایش داده نشده، همانجا باز میشود که مقدار قرار میدهد، مانند ویرایشگری که دیرتر میپیوندد؛
- زبانه، وقتی بارگذاری آن را جابهجا کرده باشد، و در زبانهٔ تنظیمات، زبانهای هم که خواننده از آن آمده است و قفل
Canvas Typeکه آنجا گرفته میشود نام آن را میبرد؛ - نمایش نامها و هر تنظیم مولد کد که خواننده زیر قفلش از خود نشان داده بود، اما فقط وقتی آن قفل پیش از بارگذاری روشن بوده، پس از آن هم روشن است و همان مقدار قفلشده را دارد. بنابراین وقتی همتایی در این میان یک تنظیم را باز کرده، تغییر داده و دوباره با مقداری دیگر قفل کرده است، ویرایشگر روی مقدار قفلشدهٔ جدید باز میشود، و جایی که قفل پیش از بارگذاری یا پس از آن خاموش است، مقدار بارگذاریشده را نشان میدهد؛
- هر تنظیمی که خوانندهٔ فقط خواندنی روی صفحهٔ خودش تغییر داده است، صرفنظر از وضعیت قفلها.
هیچیک از اینها ارسال نمیشود و value و runtimeValue همچنان سند بارگذاریشده را گزارش میکنند. باز کردن قفل بعدی یک همتا تنظیم کدی را که اینگونه نگه داشته شده است جایگزین میکند، مانند هر باز کردن قفل.
پیمایش یا بزرگنمایی بعدی خواننده، وقتی ویرایشگر قابل ویرایش است، موقعیت پیمایش و سطح بزرگنمایی نگهداشتهشده را دوباره به سند تبدیل میکند و با محل فعلی صفحه در رأس ارسال میشود، بنابراین رونوشتها آن بزرگنمایی را نیز میگیرند.
مقداردهی اولیهٔ دوباره آنچه را مخزن نگه داشته است همانطور که هست رها میکند. کشیدن، جابهجایی نما یا بزرگنمایی که هنوز نگه داشته شده است پس از آن ارسال میشود، از روی سند دوباره مقداردهیشده خوانده میشود؛ تغییر رنگ یا تغییر اندازهٔ یادداشت همانطور که انجام شده بود ارسال میشود، هرچند ویرایشگر دیگر آن را نشان نمیدهد؛ و آنچه disconnect() نگه داشته بود با connection() ارسال میشود.
پس ابتدا flushStreamBuffers را فراخوانی کنید، آنچه را منتشر میکند ارسال کنید و با مقداری که آن را در خود دارد مقداردهی اولیهٔ دوباره کنید. هرگز در حالت قطع اتصال مقداردهی اولیهٔ دوباره نکنید.
sharedStore.reseed(seed.value, {
lww: seed.lww,
version: seed.version,
keepScreen: true,
});
destroy
نمونهٔ sharedStore را بهطور کامل از بین میبرد.
خود ویرایشگر دستنخورده میماند، بنابراین با ترک یک نشست، سند همچنان قابل ویرایش میماند.
ردیابهای ماوس و فوکوس زمانی متوقف میشوند که آخرین sharedStore که ویرایشگر ارائه کرده است از بین برود.
دستهای از دنباله که مخزن هنوز نگه داشته است همراه با آن دور ریخته میشود؛ برای ارسال آن، ابتدا flushStreamBuffers را فراخوانی کنید.
نشانگرهای ماوس، فوکوسها، انتخابها و مستطیلهای انتخابی که ویرایشگرهای دیگر ارسال کردهاند تا انقضا رسمشده میمانند؛ از نسخهٔ 5.1.0 forgetPeer موارد یک ویرایشگر را بلافاصله حذف میکند.
sharedStore.destroy();