Встановлення
npm install @dineug/erd-editor
Пакет підтримує лише ESM ("type": "module") і містить тільки папку dist.
Збірки CommonJS немає, тож виклик require('@dineug/erd-editor') не працює.
Він містить два користувацькі елементи: <erd-editor>, редактор, і, починаючи з версії 5.0.0, <erd-viewer>, який показує діаграму лише для читання — див. ErdViewerElement.
Починаючи з версії 5.0.0, імпорт кореня пакета не визначає жодного з них. Кожен елемент має власну точку входу, яка його визначає, — див. реєстрація елементів.
Його залежності часу виконання залишено зовнішніми, у вигляді імпортів лише за назвою пакета (bare imports), які ваш збирач розв’язує, дедуплікує й очищає від невикористаного коду (tree-shaking). Починаючи з версії 5.0.0, його dist містить один файл на модуль, тож збирач залишає лише ті модулі, до яких дістається сторінка, — див. точки входу.
Його спільні воркери (shared workers) генеруються як окремі файли точок входу в каталозі dist/workers/ і створюються виразом new URL('./…', import.meta.url), тобто записом, який Vite, webpack 5 і Rspack збирають як точку входу воркера. Див. Web Workers.
Для сторінки, за якою не стоїть збирач, є дві самодостатні збірки — див. тег script.
Використання
import '@dineug/erd-editor/erd-editor.js';
const editor = document.createElement('erd-editor');
editor.style.cssText = 'display: block; width: 100%; height: 100vh;';
document.body.appendChild(editor);
// load a document without adding an undo entry, then keep it in sync
editor.setInitialValue(localStorage.getItem('my-diagram') ?? '');
editor.addEventListener('change', () => {
localStorage.setItem('my-diagram', editor.value);
});
@dineug/erd-editor/erd-editor.js визначає <erd-editor> під час імпорту. Сторінка, яка лише показує діаграму, натомість імпортує @dineug/erd-editor/erd-viewer.js — див. ErdViewerElement.
Елемент <erd-editor> не має власного розміру. Задайте йому (або його контейнеру) явні ширину й висоту.
Починаючи з версії 4.1.0, відкритий оглядач закріплюється всередині елемента ліворуч від полотна ERD і звужує полотно, а не перекриває його. Новий редактор запускається із закритим оглядачем.
Панель не буває вужчою за 200px і залишає полотну щонайменше 320px, тож в елементі, вужчому за 520px, відкритий оглядач не малюється, доки елемент не розшириться, — див. поруч із полотном.
Виклик setInitialValue('') створює новий порожній документ. Присвоєння властивості value натомість завантажує документ як зміну, тому така зміна потрапляє в історію змін.
Починаючи з версії 4.0.0, властивість editor.value — це документ у тій формі, яку містить файл, і саме його слід зберігати. Властивість editor.runtimeValue — це документ у тому вигляді, у якому його тримає редактор, включно з видаленими сутностями: ним ініціалізують співавтора, і він ніколи не потрапляє у файл — див. runtimeValue.
Починаючи з версії 4.0.0, у новому документі також увімкнено всі блокування налаштувань: області перегляду, вкладки, мови генератора коду, обох стилів назв, типу лапок і, починаючи з версії 4.2.0, відображення назв. Прокручування, зміна масштабу, перемикання вкладок, перемикання відображення назв або зміна одного з інших налаштувань залишає властивість editor.value без змін і не генерує подію change. Документ, завантажений із тексту, зберігає ті блокування, які в ньому вказано. Документ, у якому не вказано жодного блокування, як-от будь-який файл, збережений до версії 4.0.0, відкривається з усіма ввімкненими блокуваннями, у масштабі 100% і на вкладці ERD, незалежно від того, яку область перегляду та вкладку в ньому збережено. Його область перегляду заблоковано в початку координат 0, 0, а якщо там не намальовано жодної частини діаграми, область перегляду натомість відкривається на діаграмі — див. setInitialValue.
Файл, збережений до версії 4.2.0, відкривається з відображенням назв, заблокованим на варіанті Physical Names, навіть якщо всі інші блокування в ньому вимкнено. Редактор версії 4.0.0 або 4.1.0 під час збереження залишає блокування відображення назв таким, яким воно є, але відкидає варіант, тож файл версії 4.2.0, збережений із розблокованим відображенням назв, залишається розблокованим, але знову відкривається у варіанті Physical Names.
Про решту API див. ErdEditorElement.
CDN
<script type="module">
import 'https://esm.run/@dineug/erd-editor@5.1.0/erd-editor.js';
const editor = document.createElement('erd-editor');
editor.style.cssText = 'display: block; width: 100%; height: 100vh;';
document.body.appendChild(editor);
</script>
<!-- or -->
<script type="module" src="https://esm.run/@dineug/erd-editor@5.1.0/erd-editor.js"></script>
Сервіс esm.run розв’язує зовнішні залежності пакета за вас, тож цей код працює без збирача.
Кожна точка входу береться за шляхом після версії: …/erd-editor.js визначає редактор, а …/erd-viewer.js — засіб перегляду, який отримує з CDN кожну мову інтерфейсу, крім англійської, коли сторінка її попросить. URL самого пакета, https://esm.run/@dineug/erd-editor@5.1.0, віддає корінь, який не визначає жодного елемента.
URL без версії завжди віддає найновіший випуск. Якщо ви не хочете, щоб мажорне оновлення без попередження потрапило на вашу сторінку, закріпіть версію, як вище.
Версія 5.0.0 сама є таким оновленням: сторінка, яка має залишатися на 4.x, закріплює версію @4.2.0 — див. оновлення з 4.x.
esm.run віддає спільні воркери з cdn.jsdelivr.net, а браузер не запускає спільного воркера з джерела, відмінного від джерела сторінки. Тож редактор, завантажений так, працює без своїх воркерів, як на хості, що їх блокує, — див. Web Workers. Збірка для тегу script містить їх у своєму файлі.
Тег script
Починаючи з версії 3.6.0, пакет також постачає UMD-збірку, у якій усі залежності й усі спільні воркери містяться в одному файлі, dist/erd-editor.umd.js.
Саме на неї вказують поля unpkg і jsdelivr, тож її віддає URL лише з назвою пакета на будь-якому з цих двох CDN, і вона визначає об’єкт window.ErdEditor.
<erd-editor></erd-editor>
<script src="https://cdn.jsdelivr.net/npm/@dineug/erd-editor@5.1.0"></script>
<script>
const editor = document.querySelector('erd-editor');
editor.setInitialValue(localStorage.getItem('my-diagram') ?? '');
</script>
Завантаження цієї збірки визначає <erd-editor>. Об’єкт window.ErdEditor містить дві функції зворотного виклику для файлів, ErdEditor.setExportFileCallback і ErdEditor.setImportFileCallback, починаючи з версії 3.9.2 — ErdEditor.createKeyBindingMap, починаючи з версії 4.2.0 — ErdEditor.dictionaryRowChords (див. dictionaryRowChords), а починаючи з версії 5.0.0 — ErdEditor.ErdEditorElement і ErdEditor.defineErdEditor (див. реєстрація елементів). Функції toImage він не містить.
Починаючи з версії 5.0.0, другий файл, dist/erd-viewer.umd.js, визначає <erd-viewer> і кладе ErdViewerElement та defineErdViewer у window.ErdViewer. Він не запускає жодного воркера, містить усі 25 мов інтерфейсу й не робить жодних запитів, крім до src, який йому задано.
<erd-viewer src="diagram.erd.json" style="display: block; height: 480px"></erd-viewer>
<script src="https://cdn.jsdelivr.net/npm/@dineug/erd-editor@5.1.0/dist/erd-viewer.umd.js"></script>
Жоден із файлів не визначає тег іншого, і кожен не залишає на сторінці жодної глобальної змінної, крім власної та window.Konva.
Мапа експортів і далі спрямовує збирач до ES-модулів, тож пакет, встановлений із npm, ніколи не підхоплює жодного з цих файлів.
Сторінка, яка не може завантажити власного скрипта, може натомість вставити розміщений засіб перегляду з erd-editor.io/embed — див. вбудовування.
HTML
<erd-editor system-dark-mode enable-theme-builder enable-locale-picker enable-welcome-screen></erd-editor>
<script type="module">
import 'https://esm.run/@dineug/erd-editor@5.1.0/erd-editor.js';
const editor = document.querySelector('erd-editor');
</script>
erd-editor {
display: block;
width: 100%;
height: 100vh;
}
Починаючи з версії 4.0.0, атрибут enable-locale-picker додає на панель інструментів панель вибору Display Language, а атрибут enable-welcome-screen додає вітальний екран, який з’являється на порожній діаграмі, — див. enableLocalePicker і enableWelcomeScreen.
Сторінка, яка завантажує документ, як це робить приклад із розділу використання, вмикає властивість enableWelcomeScreen не в розмітці, а тоді, коли метод setInitialValue() уже завантажив документ, тож екран ніколи не блимає поверх файлу, який ще завантажується.
Редактор містить усі 25 мов інтерфейсу — і в ES-збірці, і до збірки для тегу script, — тож не потрібно ні віддавати файл локалі, ні щось реєструвати. Без панелі вибору й без виклику setLocale() редактор показує інтерфейс англійською.
Додавання тут атрибута readonly відкриває редактор як читач: присвоєння властивості value, виклик clear() і кожен виклик setSchema*() — включно з setSchemaJSON() і викликом у режимі додавання — ігноруються, а подія change ніколи не генерується. Його вкладки, оглядач і швидкий пошук залишаються для читання, а кожен елемент керування, що змінив би діаграму, відсутній.
Читання властивостей editor.value та editor.runtimeValue і далі працює, і обидві зберігають власні налаштування документа: налаштування перегляду, які змінює читач, як-от масштаб чи база даних, залишаються на екрані цього редактора. Натомість завантажуйте документ методом setInitialValue() — див. readonly.
Рендеринг на сервері
Кожна точка входу, крім engine.js і peer.js, потребує DOM, тож у Node викидає виняток. erd-editor.js і erd-viewer.js визначають свій елемент на рівні модуля, а корінь пакета, який починаючи з версії 5.0.0 нічого не визначає, під час завантаження все одно будує обидва класи елементів.
У Next.js, Nuxt, SvelteKit або Astro підключайте точку входу елемента з коду, що виконується лише на клієнті, а іменований імпорт із кореня, як-от setExportFileCallback чи toImage, — з того самого коду.
useEffect(() => {
import('@dineug/erd-editor/erd-editor.js');
}, []);
Vite
Під час розробки додайте до попереднього збирання Vite пакет ELK, який імпортує воркер розміщення редактора, інакше розміщення, які виконує цей воркер, завершуються помилкою: Flow, Tree - vertical і Tree - horizontal автоматичного розміщення, режим Flow вкладки візуалізації та імпорт, який розміщує Flow.
Vite 7 і старіші також потребують, щоб редактор було виключено з попереднього збирання, бо їхня попередня збірка вказує URL воркерів на файли, яких вона ніколи не записує, тож усі три воркери дають збій. У Vite 8 цей exclude пропустіть: він лише змушує сервер розробки окремо завантажувати кожен файл пакета. Збірка для production не потребує ні того, ні іншого.
// vite.config.js
export default {
optimizeDeps: {
include: ['@dineug/erd-editor > elkjs/lib/elk.bundled.js'],
// Vite 7 and older only:
// exclude: ['@dineug/erd-editor'],
},
};
TypeScript
Імпорт @dineug/erd-editor/erd-editor.js додає тег erd-editor до інтерфейсу HTMLElementTagNameMap, а @dineug/erd-editor/erd-viewer.js — тег erd-viewer, тож елемент типізовано без приведення типів. Будь-який імпорт із кореня, навіть лише типу, приносить обидва.
import '@dineug/erd-editor/erd-editor.js';
import type { ErdEditorElement } from '@dineug/erd-editor';
const editor = document.createElement('erd-editor'); // ErdEditorElement
const found = document.querySelector('erd-editor'); // ErdEditorElement | null
Тип ErdEditorElement експортується, щоб ви могли анотувати ним власні змінні й пропси. Починаючи з версії 5.0.0, це також клас елемента, а ErdViewerElement — інтерфейс і клас засобу перегляду — див. реєстрація елементів.
Починаючи з версії 4.0.0, пакет також експортує типи LocaleCode, LocaleOption і SchemaSQLOptions, а починаючи з версії 5.0.0 — ToImageOptions — див. точки входу. Параметри, які приймають методи setSchema*(), не мають експортованої назви; виводьте їх з елемента, як-от Parameters<ErdEditorElement['setSchemaSQL']>[1]. Те саме стосується спільного сховища та його типів.
Починаючи з версії 5.0.0, поле typesVersions пакета типізує й кожну точку входу за підшляхом у режимі moduleResolution: "node10", який не читає мапи експортів.
Реєстрація елементів
Починаючи з версії 5.0.0, пакет визначає тег лише там, де сторінка про це просить.
| Імпорт | Що визначає |
|---|---|
@dineug/erd-editor/erd-editor.js | <erd-editor> |
@dineug/erd-editor/erd-viewer.js | <erd-viewer> |
@dineug/erd-editor | Нічого |
Кожна з двох точок входу визначає свій тег під час обчислення й нічого не експортує, тож її імпортують заради побічного ефекту, і жодна не визначає тег іншої.
Корінь експортує обидва класи елементів, ErdEditorElement і ErdViewerElement, а також defineErdEditor() і defineErdViewer(), які визначають свій тег там, де ви їх викликаєте:
import { defineErdEditor } from '@dineug/erd-editor';
defineErdEditor();
Виклик нічого не робить, поки тег уже належить цьому класові, тож точка входу й виклик define або два виклики define можуть зустрітися на одній сторінці. Він викидає Error з назвою тега, коли тег належить іншому класові, як-от другій копії пакета, зібраній у ту саму сторінку: Another element class already defines the custom element name erd-editor.
Класи кореня — це ті, які визначають точки входу, тож customElements.get('erd-editor') === ErdEditorElement, щойно виконалася будь-яка з них. Доки тег не визначено, document.createElement('erd-editor') створює звичайний HTMLElement без жодного з членів редактора, а new ErdEditorElement() викидає виняток.
Для власного тега визначте клас під ним самі й самі додайте тег до HTMLElementTagNameMap. Робіть це у вікні, яке не завантажує ні точки входу цього елемента, ні його збірки для тегу script і не викликає для нього жодної функції define, бо клас має одну назву на вікно:
import { ErdEditorElement } from '@dineug/erd-editor';
customElements.define('my-erd-editor', ErdEditorElement);
declare global {
interface HTMLElementTagNameMap {
'my-erd-editor': ErdEditorElement;
}
}
Збірка, що містить обидва елементи, змушує Vite і Rolldown один раз для кожної мови інтерфейсу, крім англійської, попереджати про INEFFECTIVE_DYNAMIC_IMPORT. Засіб перегляду завантажує кожну з них власним import(), а редактор імпортує всі словники одразу, тож вони залишаються в чанку редактора й завантажуються разом із ним. Нічого не ламається, а збірка лише із засобом перегляду зберігає кожну мову у власному чанку.
Підсвічування синтаксису
Панелі схеми SQL і генератора коду підсвічує Shiki в окремому спільному воркері, а також, починаючи з версії 4.0.0, скрипти Before tables і After tables на вкладці схеми SQL.
Починаючи з версії 3.7.0, нічого не потрібно ні встановлювати, ні реєструвати: воркер створюється під час першого рендерингу панелі коду, тож сторінка, яка не відкриває жодної такої панелі, ніколи не завантажує граматики.
| Мови | SQL, TypeScript, GraphQL, C#, Java, Kotlin, Scala, Go, Python, PHP, Rust, Swift, JSON, Mermaid |
| Теми | github-dark і github-light, відповідно до світлого чи темного вигляду редактора |
Це саме ті мови, які генерують панелі: JPA підсвічується як Java, SQLAlchemy — як Python, TypeORM, Sequelize, Drizzle і Zod — як TypeScript, Doctrine — як PHP, SeaORM — як Rust, JSON Schema — як JSON, а DBML і AML — як SQL, найближча граматика з наявних у комплекті, — див. генератор коду.
Рушій регулярних виразів написано на чистому JavaScript, тож жодна політика хоста не потребує дозволу wasm-unsafe-eval.
Там, де немає SharedWorker — у Chrome на Android до Chrome 148, у Safari до 16.4, — збій записується в журнал, а код показується звичайним текстом; скрипти все одно можна редагувати.
Оновлення з версії 3.6.0 або старішої: пакет @dineug/erd-editor-shiki-worker більше не публікується, а разом із ним зникла й функція setGetShikiServiceCallback.
Приберіть його встановлення й реєстрацію; сторінка, яка завантажувала воркер із CDN, також прибирає той другий тег <script>.
Web Workers
Редактор виконує три завдання у воркерах SharedWorker: підсвічування синтаксису, експорт зображень і розміщення таблиць, на якому ґрунтуються автоматичне розміщення, режим Flow вкладки візуалізації та, починаючи з версії 4.0.0, розміщення імпортованої схеми.
Усі три постачаються в пакеті @dineug/erd-editor. Жоден із них не потребує налаштування з вашого боку, але хост може заблокувати будь-який із них.
Починаючи з версії 5.0.0, кожен воркер створюється у власному модулі, тож збірка містить лише ті воркери, яких досягають її модулі: збірка toImage без жодного елемента містить лише воркер експорту зображень, а <erd-viewer> не запускає воркерів узагалі — див. точки входу.
Воркер, який виконував збирання сміття документа, вилучено у версії 4.0.0 разом із самим збиранням.
| Воркер | Без нього |
|---|---|
| Підсвічування синтаксису | Панелі схеми SQL і генератора коду, а також скрипти схеми SQL залишаються звичайним текстом |
| Експорт зображень | PNG, SVG, Copy to clipboard, попередній перегляд діалогового вікна Export image і, починаючи з версії 5.0.0, toImage() малюються в головному потоці, і на час малювання сторінка блокується |
| Розміщення таблиць | Варіанти Flow, Tree - vertical і Tree - horizontal автоматичного розміщення, а також режим Flow вкладки візуалізації завершуються повідомленням Could not place tables; імпорт, таблиці якого розміщує Flow, — SQL-, GraphQL-, DBML- чи AML-файл, імпортований через Import або Import and Add, або виклик setSchema*() з placement: 'auto' — розставляє свої таблиці рядами без жодного повідомлення; на Force і режим Graph це не впливає, бо вони виконуються всередині редактора |
Експорт зображень чекає відповіді свого воркера десять секунд і потім малює в головному потоці, а підсвічування синтаксису залишає код звичайним текстом, щойно його воркер дає збій, тож хост, який блокує воркери, втрачає продуктивність, а не функціональність.
Розміщення таблиць — виняток: рушій, що обчислює розміщення, важить більше за сам редактор і ніколи не завантажується в процес сторінки, тож під час першого розміщення воно чекає на свій воркер тридцять секунд, а щойно воркер відповів, дає кожному розміщенню шістдесят секунд на повернення результату.
Якщо час будь-якого з цих очікувань спливає, розміщення завершується так само, як і без воркера. Автоматичне розміщення показує повідомлення Placing tables одразу після запуску, тоді як режим Flow та імпорт, таблиці якого розміщує Flow, показують його, лише коли розміщення, включно із запуском його воркера, триває вже шість секунд.
Vite, webpack 5 і Rspack генерують воркери як файли поруч із вашими чанками. esbuild, а також Rolldown, використаний сам по собі, а не через Vite, не генерують жодного, тож сторінка, яку вони збирають, працює без воркерів.
У експериментальному режимі webpack experiments.outputModule жоден воркер не запускається, бо кожен чекає на чанк, відокремлений від нього, який ніхто не завантажує. Залишайте типовий вивід webpack або задайте optimization.splitChunks: false.
Content Security Policy
Сторінці під суворою політикою Content Security Policy для елементів потрібні такі директиви:
worker-src 'self'для збірки, яку обробляє збирач, воркери якої — файли поруч із пакетом, і щеblob:, якщо ваш збирач вбудовує воркер у код. У збірці для тегу script усі три вбудовано у файл як URLdata:, тож такій сторінці натомість потрібенworker-src data:.<erd-viewer>не потребує жодного з них, бо не запускає воркерів.- Починаючи з версії
5.0.0, обидва елементи стилізують себе сконструйованими таблицями стилів, які пропускаєstyle-src 'self'. Панелі коду редактора все ще розфарбовують текст атрибутамиstyle, а попередній перегляд діалогового вікнаExport image— це зображення за URLblob:, тож редактору для них потрібні ще йstyle-src 'unsafe-inline'таimg-src blob:. - Браузер без сконструйованих таблиць стилів, як-от Firefox до 101, натомість отримує елементи
<style>, яким для будь-якого з елементів потрібенstyle-src 'unsafe-inline'. <erd-viewer>отримує свійsrcчерез fetch, тож це джерело треба внести вconnect-src— див. що він додає на сторінку.
Точки входу
Пакет має п’ять точок входу:
| Точка входу | Що це |
|---|---|
@dineug/erd-editor | Корінь: експорти нижче. Починаючи з версії 5.0.0, він не визначає жодного елемента, хоча для завантаження все одно потребує DOM |
@dineug/erd-editor/erd-editor.js | Починаючи з версії 5.0.0. Визначає <erd-editor> і нічого не експортує |
@dineug/erd-editor/erd-viewer.js | Починаючи з версії 5.0.0. Визначає <erd-viewer> і нічого не експортує |
@dineug/erd-editor/engine.js | Сховище документа без DOM |
@dineug/erd-editor/peer.js | Починаючи з версії 3.9.1. Учасник без інтерфейсу для MCP-сервера і, починаючи з версії 5.1.0, для прив’язки Yjs |
Корінь експортує обидва класи елементів та їхні функції define, два сетери функцій зворотного виклику, а також, починаючи з версії 3.9.2, типові прив’язки клавіш разом з їхніми типами, починаючи з версії 4.0.0, типи мов інтерфейсу та тип параметрів методу getSchemaSQL(), починаючи з версії 4.2.0, сполучення клавіш для рядків вкладки словника і, починаючи з версії 5.0.0, toImage.
| Експорт | Опис |
|---|---|
ErdEditorElement | Інтерфейс елемента — див. ErdEditorElement. Починаючи з версії 5.0.0, також його клас, той, яким визначено <erd-editor> — див. реєстрація елементів. |
ErdViewerElement | Починаючи з версії 5.0.0. Інтерфейс і клас засобу перегляду — див. ErdViewerElement. |
defineErdEditor(), defineErdViewer() | Починаючи з версії 5.0.0. Визначають <erd-editor> або <erd-viewer> як його клас. Виклик нічого не робить, поки тег належить цьому класові, і викидає Error, коли його посідає інший клас — див. реєстрація елементів. |
toImage(value, options) | Починаючи з версії 5.0.0. Малює документ як PNG Blob або рядок SVG з параметрами діалогового вікна Export image — див. toImage. |
ToImageOptions (тип) | Починаючи з версії 5.0.0. Параметри, які приймає toImage(): format, background, darkMode і scale. |
setExportFileCallback(cb) | Замінює браузерне завантаження файлу, (blob, { fileName }) => void. |
setImportFileCallback(cb) | Замінює браузерне вікно вибору файлу, ({ type, op, accept, mode }) => void; поле mode — починаючи з версії 4.0.0. Починаючи з версії 4.2.0, кнопка Import CSV вкладки словника відкриває вікно вибору файлу браузера, навіть якщо функцію зворотного виклику задано, — див. діалогові вікна файлів. |
createKeyBindingMap() | Під час кожного виклику повертає типові прив’язки клавіш як новий об’єкт KeyBindingMap — див. createKeyBindingMap. |
KeyBindingMap, KeyBindingName, ShortcutOption (типи) | Мапа прив’язок, об’єднання назв її команд і одна прив’язка. |
dictionaryRowChords(map) | Починаючи з версії 4.2.0. Під час кожного виклику повертає як новий масив ShortcutOption[] сполучення клавіш, якими сітка вкладки словника вставляє й видаляє рядки відповідно до переданої вами мапи KeyBindingMap. Сполучення, що вставляє рядки вище (за типових прив’язок — Alt+Shift+Enter), не входить до жодної прив’язки — див. dictionaryRowChords. |
LocaleCode, LocaleOption (типи) | Починаючи з версії 4.0.0. 25 кодів мов інтерфейсу, а також ці коди разом із 'system', які приймає метод setLocale(), — див. мова інтерфейсу. |
SchemaSQLOptions (тип) | Починаючи з версії 4.0.0. Параметри, які приймає метод getSchemaSQL(): statements, header і, починаючи з версії 4.2.0, logicalNameAsComment — див. getSchemaSQL. |
Починаючи з версії 5.0.0, dist містить один немінімізований файл на модуль, кожен поруч зі своєю декларацією, а поле sideEffects у package.json називає лише дві точки входу тегів і дві заглушки, потрібні файлам воркерів. Тож збирач відкидає кожен модуль, якого не досягає сторінка, і мінімізує один раз:
- Іменований імпорт із кореня, як-от
setExportFileCallback, не збирає ні елемента, ні воркера. toImageприносить воркер експорту зображень і жодного елемента.erd-editor.jsприносить редактор і всі три спільні воркери.erd-viewer.jsприносить засіб перегляду без жодного воркера, з англійською всередині й кожною іншою мовою інтерфейсу у власному чанку, що завантажується, коли сторінка її попросить.
Модуль @dineug/erd-editor/engine.js запускає сховище документа без DOM, тож працює у Web Worker — див. віддалене зберігання.
Він експортує функцію createReplicationStore і тип ReplicationStore. Починаючи з версії 3.10.0, він також експортує тип ReplicationChange, { value: string; changed: boolean }, який отримує слухач події change репліки, — див. on@change.
Починаючи з версії 4.0.0, сховище ReplicationStore також має властивість runtimeValue. Його властивість value і значення, яке передає подія change, — це форма зберігання, яку містить файл, так само як в елемента, — див. ReplicationStore.
Модуль @dineug/erd-editor/peer.js — учасник без інтерфейсу (headless peer), через який MCP-сервер редагує документ.
Починаючи з версії 5.1.0, саме його також прив’язує до документа Y.Doc функція bindPeerStore з @dineug/erd-editor-yjs: сховище учасника, створене викликом createPeerStore() цієї точки входу, як учасник кімнати без інтерфейсу або як ущільнювач, що згортає історію кімнати.
Крім того, що показує про нього сторінка Yjs — виклик createPeerStore(), value прив’язаного сховища учасника та його destroy(), — ця документація його не описує.
Діалогові вікна файлів
Імпорт і експорт проходять через функції зворотного виклику, які можна підставити, тож хост без браузерного діалогового вікна файлів — наприклад, вебподання (webview) в IDE — може надати власне.
Вони несиметричні: експорт передає вам готовий файл, тоді як імпорт лише запитує файл, а вміст ви передаєте назад самі.
Починаючи з версії 4.2.0, кнопка Import CSV вкладки словника — єдиний імпорт, який ніколи не викликає функцію зворотного виклику для імпорту, адже поле type цієї функції не має значення для CSV. Ця кнопка завжди відкриває власне вікно вибору файлу браузера для файлів .csv — див. імпорт і експорт CSV.
Поле op має значення set або diff — операція diff передається в метод setDiffValue() незалежно від значення type. В іншому разі метод вибирається за полем type, а поле accept містить розширення цього типу, готові для передавання в діалогове вікно файлів хоста.
Починаючи з версії 4.0.0, операція set містить mode: 'append', коли користувач вибрав імпорт із додаванням, і не містить mode для звичайного імпорту. Передавайте цей режим далі: функція зворотного виклику, яка його відкидає, замінює діаграму, яку користувач хотів доповнити.
type | accept | Метод |
|---|---|---|
json | .json | editor.setSchemaJSON(text, { mode }) |
sql | .sql | editor.setSchemaSQL(text, { placement: 'auto', mode }) |
graphql | .graphql,.gql,.graphqls | editor.setSchemaGraphQL(text, { placement: 'auto', mode }) |
dbml | .dbml | editor.setSchemaDBML(text, { placement: 'auto', mode }) |
aml | .aml | editor.setSchemaAML(text, { placement: 'auto', mode }) |
Параметр placement: 'auto' розміщує таблиці за їхніми зв’язками ще до того, як вони з’являться, як це робить власний імпорт редактора, і змушує виклик повертати Promise. Без нього таблиці одразу з’являються рядами — див. setSchemaSQL і setSchemaJSON.
import { setExportFileCallback, setImportFileCallback } from '@dineug/erd-editor';
setExportFileCallback((blob, { fileName }) => host.writeFile(fileName, blob));
setImportFileCallback(async ({ type, op, accept, mode }) => {
const text = await host.pickFile(accept);
if (op === 'diff') {
editor.setDiffValue(text);
} else if (type === 'json') {
editor.setSchemaJSON(text, { mode });
} else if (type === 'sql') {
editor.setSchemaSQL(text, { placement: 'auto', mode });
} else if (type === 'graphql') {
editor.setSchemaGraphQL(text, { placement: 'auto', mode });
} else if (type === 'dbml') {
editor.setSchemaDBML(text, { placement: 'auto', mode });
} else if (type === 'aml') {
editor.setSchemaAML(text, { placement: 'auto', mode });
}
});
Розгалужуйте обробку за кожним значенням type, яке ви підтримуєте, а решту ігноруйте.
Виклик setSchemaJSON() у режимі заміни, як і присвоєння властивості value, очищає документ перед розбором, тож передавання туди даних, які не є документом .erd.json, — через загальну гілку else або тому, що туди потрапило значення type, додане пізніше, — спорожнює діаграму, нічого не імпортуючи.
Значення fileName, яке генерує редактор, — це <database name>-<timestamp> плюс розширення файлу, де мітка часу — це місцевий час у форматі yyyy-MM-dd'T'HH_mm_ss. Якщо назва бази даних порожня, замість неї використовується unnamed. У назві CSV-файлу словника перед розширенням стоїть назва аркуша, як-от <database name>-<timestamp>-words.csv.
Функція зворотного виклику для експорту отримує такі файли. Починаючи з версії 4.0.0, серед них є SVG і файли генератора коду, а файл .sql надходить не безпосередньо з пункту Export, а з кнопки Save file на вкладці схеми SQL. Починаючи з версії 4.2.0, серед них є й CSV-файл вкладки словника. toImage() не викликає жодної з цих функцій: він повертає вам своє зображення.
| Файл | Розширення | type об’єкта Blob |
|---|---|---|
| Експорт у JSON | .erd.json | application/json |
Кнопка Save file на вкладці схеми SQL, що зберігає текст, який показує ця вкладка, — див. схема SQL | .sql | немає |
| Діалогове вікно експорту зображення | .png або .svg | image/png або image/svg+xml |
Кнопка Save file на вкладці генератора коду — див. генератор коду | Відповідно до мови: .cs, .go, .java, .kt, .php, .rs, .scala, .swift, .ts, .py, .aml, .dbml, .graphql, .json або .mmd | немає |
Кнопка Export CSV на вкладці словника, що зберігає всі рядки показаного аркуша незалежно від того, які з них показує його пошук, — див. імпорт і експорт CSV | .csv | text/csv |
Хосту, який вибирає обробник за розширенням, потрібен обробник для кожного з них.
Якщо функції зворотного виклику не задано, редактор використовує власну поведінку браузера для завантаження й вибору файлів. Передайте null, щоб повернутися до неї.
Підтримка браузерів
Chrome 91+, Edge 94+, Firefox 93+, Safari 16.4+ — базовий рівень ES2022, під який зібрано опубліковані збірки. Поліфіли до збірок не входять. Додайте власні, якщо вам потрібно підтримувати старіші браузери.
Оновлення з 4.x
Версія 5.0.0 — мажорний випуск. Переводячи сторінку з 4.x, перевірте кожен із цих пунктів:
-
import '@dineug/erd-editor'більше не визначає<erd-editor>. Натомість імпортуйте@dineug/erd-editor/erd-editor.jsзаради його ефекту або викличтеdefineErdEditor(), а іменовані імпорти з кореня залиште як є. TypeScript не позначає сторінку, що залишилася на простому імпорті, бо декларації кореня й далі називають тег уHTMLElementTagNameMap, але створений елемент — звичайнийHTMLElement, тож перший виклик його методу викидаєTypeError— див. реєстрація елементів.-import '@dineug/erd-editor';+import '@dineug/erd-editor/erd-editor.js';import { setExportFileCallback } from '@dineug/erd-editor'; -
На CDN це стосується й
https://esm.run/@dineug/erd-editor, який тепер віддає корінь і нічого не визначає: імпортуйтеhttps://esm.run/@dineug/erd-editor@5.1.0/erd-editor.js. URL jsDelivr та unpkg лише з назвою пакета і далі віддають збірку для тегу script, яка визначає<erd-editor>, як і раніше. URL без версії тепер віддає найновіший випуск 5.x; щоб залишитися на 4.x, закріпіть версію@4.2.0— див. CDN і тег script. -
Корінь нічого не визначає, але все одно потребує DOM, тож за рендерингу на сервері іменований імпорт із нього, як-от
setExportFileCallback, залишається на клієнтському шляху поруч із точкою входу елемента — див. рендеринг на сервері. -
window.ErdEditorотримуєErdEditorElementіdefineErdEditor. Збірка засобу перегляду для тегу script кладеErdViewerElementіdefineErdViewerуwindow.ErdViewer, і жодна з глобальних змінних не міститьtoImage. -
Редактор з атрибутом
readonlyвідкривається як читач. Його шість вкладок, оглядач, швидкий пошук і присутність залишаються, а кожен елемент керування, що змінив би діаграму, відсутній, а не вимкнений: панель інструментів показує назву бази даних як текст, вкладка налаштувань показує свої налаштування з вимкненими елементами керування під позначкоюRead only, а плаваюча панель інструментів зберігає лише масштаб, відображення назв, режим дзен і компас, тожHandіSelectзникли, а перетягування панорамує. Натискання нічого не виділяє: єдине виділення — це обведення, яке навколо знайденого ставить перехід з оглядача чи швидкого пошуку і яке знімає клацання без руху, а сполучення виділення всього нічого не виділяють. Ввімкненняreadonlyзавершує все, що було відкрито, як-от виділення, інструмент «Рука», редактор клітинки, перетягування,Map Columns, попередній переглядForceавтоматичного розміщення й подорож у часі, і зберігає прокручування, масштаб, вкладку та відображення назв — див. readonly. -
Налаштування, які змінює читач
readonly, залишаються на екрані цього редактора незалежно від їхніх блокувань: прокручування й масштаб, вкладка, відображення назв, View Option, база даних, а також мова генератора коду, стилі назв і тип лапок.value,runtimeValueта експорт JSON зберігають власні значення документа, до яких у 4.x могли дійти зміни читача, аgetSharedStore()не надсилає жодного з них іншим редакторам.getSchemaSQL()без СУБД пише для бази даних, яку вибрав читач. Вимкненняreadonlyповертає базу даних, налаштування коду й View Option до того, що цей редактор показував би, якби читач нічого не змінював, а прокручування, масштаб, вкладку та відображення назв залишає там, де їх залишив читач. -
Рядок
Recalculation table widthвкладки налаштувань зник. Завантаження та вставлення, як і раніше, підганяють ширину кожної таблиці під її текст. -
У Vite 8 приберіть
exclude: ['@dineug/erd-editor']зoptimizeDeps, який і далі потрібен лише Vite 7 і старішим, аincludeдля ELK залиште — див. Vite.
Оновлення з 3.x
Версія 4.0.0 — мажорний випуск. Переводячи сторінку з 3.x, перевірте кожен із цих пунктів, а потім ті, що наведені в розділі оновлення з 4.x для 5.0.0:
editor.value, значенняvalueрепліки й значенняvalue, яке передає її подіяchange, — це форма зберігання, яку містить файл: без видалених сутностей, виміряних ширин, порядку накладання та точок прив’язки зв’язків. Як і раніше, зберігайтеvalue, а ці дані читайте зruntimeValue; мітки часу сутностей (meta) прибрано повністю. Співавтора або репліку, що приєднується до активного сеансу, ініціалізуйте зruntimeValueактивного учасника, а не зvalueчи файлу, і ніколи не зберігайтеruntimeValue— див. value і runtimeValue.- Блокування налаштувань замінюють параметри
Save Scroll InformationіSave Zoom Information. У новому документі й у будь-якому документі, збереженому до версії4.0.0, увімкнено всі блокування, тож прокручування, зміна масштабу, перемикання вкладки або зміна мови генератора коду, стилю назв чи типу лапок залишає властивістьvalueбез змін і не генерує подіюchange. Сторінці, яка зберігала область перегляду через подіюchange, потрібно, щоб налаштуванняViewport(іCanvas Typeдля вкладки) було розблоковано на вкладці налаштувань, або потрібен документ, у якому полеsettings.lockSettingsзалишає ці біти скинутими, — див. блокування. - Об’єкт
settingsбільше не має полівwidth,height,scrollTop,scrollLeft,relationshipOptimizationчиignoreSaveSettings, а константиSaveSettingTypeзникли. Полеsettings.lockSettingsз бітамиLockSettingTypeзамінює полеignoreSaveSettings, яке версія4.0.0або новіша не читає й не записує, — див. Settings. - JSON Schema, яку кожен файл указує в полі
$schema, тепер описує лише форму зберігання й є закритою: вона відхиляє файл, збережений попереднім випуском, доки збереження у версії4.0.0або новішій не перезапише його. - Збирання сміття документа зникло разом із його воркером, тож видалена сутність залишається в
runtimeValue, доки документ не буде наступного разу відкрито з його файлу. Залишилися три спільні воркери — див. Web Workers. - Тримайте кожен редактор і кожну репліку в спільному сеансі на версії
4.0.0або новішій. Попередній випуск ігнорує нові типи дій: дії груп таблиць, зіставлення стовпців, блокувань і скриптів схеми SQL — див. змішані випуски. - Функція зворотного виклику для імпорту отримує
mode: 'append'для імпорту з додаванням, і це значення вона має передати далі. Функція зворотного виклику для експорту тепер також отримує файли.svgі файли генератора коду, а пунктExport▸Schema SQLвідкриває вкладку схеми SQL замість збереження, тож файл.sqlнадходить лише з кнопкиSave fileцієї вкладки — див. діалогові вікна файлів. - Клавіші
DeleteіBackspaceприв’язано до нової командиremoveSelection. Поки редактор має фокус поза текстовим полем, типова дія клавіші скасовується на кожній вкладці, а на вкладці ERD виділення видаляється. ТипиKeyBindingNameіKeyBindingMapдоповнюються нею, а викликsetKeyBindingMap({ removeSelection: [] })залишає обидві клавіші сторінці — див. setKeyBindingMap. - Поле
ThemeOptions.appearanceтакож приймає'system'— варіантSystemконструктора теми, який встановлюється під час увімкненняsystemDarkMode. ПодіяchangePresetThemeповідомляє'system', поки його вибрано, тож зберігайте це значення як є й передавайте назад уsetPresetTheme. КолиsystemDarkModeувімкнено, викликsetPresetTheme()зі значенням'light'або'dark'тепер залишається в силі, а не перезаписується наступною зміною в ОС — див. systemDarkMode і changePresetTheme. @dineug/erd-editor-mcpверсії1.0.0або новішої, розширення для VS Code версії4.0.0або новішої та плагіни для Obsidian і JetBrains версії1.0.0або новішої працюють за протоколом хаба версії 2. Сервер версії1.0.0або новішої і старіший випуск редактора, що обслуговує агентів, або старіший сервер і один із цих редакторів відхиляють один одного з помилкоюprotocolMismatch, указуючи сторону, яку слід оновити, — див. оновлення.- URL CDN без версії віддає найновіший випуск, з версії
5.0.0— 5.x. Щоб залишитися на 3.x, закріпіть версію@3.10.0— див. CDN.