Перейти до основного вмісту

Встановлення

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 усі три вбудовано у файл як URL data:, тож такій сторінці натомість потрібен worker-src data:. <erd-viewer> не потребує жодного з них, бо не запускає воркерів.
  • Починаючи з версії 5.0.0, обидва елементи стилізують себе сконструйованими таблицями стилів, які пропускає style-src 'self'. Панелі коду редактора все ще розфарбовують текст атрибутами style, а попередній перегляд діалогового вікна Export image — це зображення за URL blob:, тож редактору для них потрібні ще й 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 для звичайного імпорту. Передавайте цей режим далі: функція зворотного виклику, яка його відкидає, замінює діаграму, яку користувач хотів доповнити.

typeacceptМетод
json.jsoneditor.setSchemaJSON(text, { mode })
sql.sqleditor.setSchemaSQL(text, { placement: 'auto', mode })
graphql.graphql,.gql,.graphqlseditor.setSchemaGraphQL(text, { placement: 'auto', mode })
dbml.dbmleditor.setSchemaDBML(text, { placement: 'auto', mode })
aml.amleditor.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.jsonapplication/json
Кнопка Save file на вкладці схеми SQL, що зберігає текст, який показує ця вкладка, — див. схема SQL.sqlнемає
Діалогове вікно експорту зображення.png або .svgimage/png або image/svg+xml
Кнопка Save file на вкладці генератора коду — див. генератор кодуВідповідно до мови: .cs, .go, .java, .kt, .php, .rs, .scala, .swift, .ts, .py, .aml, .dbml, .graphql, .json або .mmdнемає
Кнопка Export CSV на вкладці словника, що зберігає всі рядки показаного аркуша незалежно від того, які з них показує його пошук, — див. імпорт і експорт CSV.csvtext/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.