@emailmaker/extensions-react 1.0.111-dev.8 → 1.0.111-dev.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -56
- package/index.js +11 -5
- package/package.json +3 -3
- package/types.d.ts +20 -5
package/README.md
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
## ⚙️ Требования
|
|
16
16
|
|
|
17
17
|
- Современный браузер с поддержкой **ES2015** (и выше)
|
|
18
|
-
- Node.js >=
|
|
19
|
-
- React и Ant Design подключаются через
|
|
18
|
+
- Node.js >= 20 (рекомендуется LTS; CLI-шаблон использует `tsx` и Vite/Webpack 5)
|
|
19
|
+
- React и Ant Design в плагине подключаются через `PluginDev` (alias/externals на runtime хоста из `@emailmaker/emailmaker/runtime/*`), а не отдельным npm-пакетом runtime
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
---
|
|
@@ -33,21 +33,39 @@
|
|
|
33
33
|
|
|
34
34
|
## 🔰 Быстрый старт
|
|
35
35
|
|
|
36
|
-
👉
|
|
36
|
+
👉 Рекомендуемый способ — **CLI** (`@emailmaker/cli`): согласованная структура, Vite/Webpack, app + sandbox, dev/release host.
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
|
|
40
|
-
cd
|
|
39
|
+
npx @emailmaker/cli my-plugin --kind plugin --preset advanced --bundler vite --target npm-package --output-dir ./my-plugin
|
|
40
|
+
cd my-plugin
|
|
41
41
|
npm install
|
|
42
42
|
npm run start
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
- Webpack / Vite
|
|
45
|
+
Сгенерированный проект включает:
|
|
46
|
+
- Webpack / Vite (по выбору)
|
|
47
47
|
- React + Ant Design
|
|
48
48
|
- TypeScript
|
|
49
49
|
- Структуру проекта, описанную ниже
|
|
50
50
|
|
|
51
|
+
Проверка release-сборки без ручного деплоя:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm run build
|
|
55
|
+
npm run start:release
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Альтернатива: пример из репозитория
|
|
59
|
+
|
|
60
|
+
[Готовый example](https://github.com/emailmaker/simple_plugin) можно клонировать для ознакомления; для новых плагинов предпочтительнее CLI-шаблон.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git clone https://github.com/emailmaker/simple_plugin
|
|
64
|
+
cd simple_plugin
|
|
65
|
+
npm install
|
|
66
|
+
npm run start
|
|
67
|
+
```
|
|
68
|
+
|
|
51
69
|
|
|
52
70
|
---
|
|
53
71
|
|
|
@@ -56,18 +74,19 @@ npm run start
|
|
|
56
74
|
### 📦 Основные пакеты
|
|
57
75
|
|
|
58
76
|
```bash
|
|
59
|
-
npm install @emailmaker/emailmaker @emailmaker/
|
|
77
|
+
npm install @emailmaker/emailmaker @emailmaker/extensions-app @emailmaker/extensions-react @emailmaker/extensions-sandbox
|
|
60
78
|
```
|
|
61
79
|
|
|
62
80
|
| Пакет | Назначение | Что экспортирует |
|
|
63
81
|
|-------|------------|------------------|
|
|
64
|
-
| `@emailmaker/emailmaker` | Основной пакет | `init()`, `prefetch()`, типы `IPlugin`, `Instance
|
|
65
|
-
| `@emailmaker/emailmaker/runtime` | Общие зависимости | React, ReactDOM, Ant Design и связанные модули |
|
|
82
|
+
| `@emailmaker/emailmaker` | Основной пакет | `init()`, `prefetch()`, типы `IPlugin`, `Instance`; runtime React/Ant Design — subpath `@emailmaker/emailmaker/runtime/*` (отдельный npm не нужен) |
|
|
66
83
|
| `@emailmaker/extensions-app` | API для app-плагинов | `pluginRegistry`, `DomComponentRegistry`, `ElementsApi`, `SettingsPanelApi`, `ModalApi` |
|
|
67
84
|
| `@emailmaker/extensions-react` | React API для плагинов | `ComponentRegistry`, `createComponentIdentifier()` |
|
|
68
85
|
| `@emailmaker/extensions-sandbox` | API для sandbox-плагинов | `App`, `MessageService`, `SyncService` |
|
|
69
86
|
|
|
70
|
-
`@emailmaker/ui-kit` ставится
|
|
87
|
+
`@emailmaker/ui-kit` ставится отдельно (devDependency в CLI-шаблоне), если плагин использует готовые UI-компоненты платформы.
|
|
88
|
+
|
|
89
|
+
> React и Ant Design в коде плагина импортируются как `react` / `antd`. `PluginDev` в dev/release подставляет runtime хоста через alias/externals — см. раздел «Сборка плагина».
|
|
71
90
|
|
|
72
91
|
### Импорты
|
|
73
92
|
|
|
@@ -93,8 +112,8 @@ import type { IPlugin, Instance } from '@emailmaker/emailmaker';
|
|
|
93
112
|
## Что обычно ставить
|
|
94
113
|
|
|
95
114
|
- если у вас обычный React-плагин, ставьте все пакеты из команды выше
|
|
96
|
-
- если используете UI Kit, добавьте
|
|
97
|
-
- если пишете только sandbox-часть,
|
|
115
|
+
- если используете UI Kit, добавьте ещё `@emailmaker/ui-kit`
|
|
116
|
+
- если пишете только sandbox-часть, достаточно main + `@emailmaker/extensions-sandbox`
|
|
98
117
|
|
|
99
118
|
> Для React-плагинов пакет `@emailmaker/extensions-react` нужен по умолчанию.
|
|
100
119
|
|
|
@@ -198,7 +217,7 @@ module.exports = {
|
|
|
198
217
|
|
|
199
218
|
Если release bundle неожиданно стал толстым или target `встраиваемый bundle` не загружается, начните с раздела `Troubleshooting`.
|
|
200
219
|
|
|
201
|
-
Типы для плагина всё равно собираются отдельно: CLI-шаблон запускает `build:types` и кладёт `dist/
|
|
220
|
+
Типы для плагина всё равно собираются отдельно: CLI-шаблон запускает `build:types` и кладёт `dist/public-types.d.ts` рядом с JS bundle, поэтому TypeScript support сохраняется и для browser/advanced targets.
|
|
202
221
|
|
|
203
222
|
### tsconfig.json
|
|
204
223
|
|
|
@@ -273,27 +292,35 @@ emailmaker.init({
|
|
|
273
292
|
|
|
274
293
|
## 📁 Структура проекта
|
|
275
294
|
|
|
295
|
+
CLI-шаблон (типичный layout):
|
|
296
|
+
|
|
276
297
|
```txt
|
|
277
|
-
plugin
|
|
278
|
-
├──
|
|
279
|
-
│
|
|
280
|
-
|
|
281
|
-
│
|
|
282
|
-
|
|
283
|
-
│
|
|
284
|
-
|
|
298
|
+
my-plugin/
|
|
299
|
+
├── src/
|
|
300
|
+
│ ├── app/ # UI-часть, взаимодействие с редактором
|
|
301
|
+
│ │ └── MyPlugin.tsx
|
|
302
|
+
│ ├── sandbox/ # Скрипт для DOM письма (отдельная сборка)
|
|
303
|
+
│ │ └── index.ts
|
|
304
|
+
│ ├── dev.tsx # Локальный debug host (редактор + плагин)
|
|
305
|
+
│ └── public-types.d.ts # Типы плагина для npm / augmentation
|
|
306
|
+
├── config/ # Vite/Webpack: dev host, release, sandbox
|
|
307
|
+
├── scripts/ # dev-runner, build-runner, release-runner, build-types
|
|
308
|
+
├── dist/ # Сборка app-плагина (+ public-types.d.ts)
|
|
309
|
+
└── package.json
|
|
285
310
|
```
|
|
286
311
|
|
|
287
|
-
-
|
|
288
|
-
- `app` — точка входа, из которой можно подключить скрипт sandbox:
|
|
312
|
+
- **`src/app`** — регистрация плагина, панели, работа с API редактора. Отсюда подключается sandbox:
|
|
289
313
|
|
|
290
314
|
```ts
|
|
291
315
|
const sandboxApi = this.editor.use('SandboxScriptApi');
|
|
292
316
|
sandboxApi.registerSandboxScript(this.options.publicPath + 'sandbox.js');
|
|
293
317
|
```
|
|
294
318
|
|
|
295
|
-
-
|
|
296
|
-
-
|
|
319
|
+
- **`src/sandbox`** — код в iframe; собирается отдельным entry (`build:sandbox`), без React.
|
|
320
|
+
- **`src/dev.tsx`** — локальный запуск `emailmaker` с плагином (`npm run start`).
|
|
321
|
+
- **`src/public-types.d.ts`** — `PluginTypeMap`, `Config`, опции; после `npm run build:types` копируется в `dist/public-types.d.ts`.
|
|
322
|
+
|
|
323
|
+
Общие идентификаторы событий app ↔ sandbox держите в `src/interfaces/` (или аналогичном shared-модуле внутри `src/`).
|
|
297
324
|
|
|
298
325
|
|
|
299
326
|
---
|
|
@@ -341,6 +368,24 @@ class TestPlugin implements IPlugin {
|
|
|
341
368
|
}
|
|
342
369
|
```
|
|
343
370
|
|
|
371
|
+
### Sandbox-часть
|
|
372
|
+
|
|
373
|
+
Скрипт в iframe (`@emailmaker/extensions-sandbox`) использует **упрощённый** lifecycle — без `required()`:
|
|
374
|
+
|
|
375
|
+
```ts
|
|
376
|
+
import { App } from '@emailmaker/extensions-sandbox';
|
|
377
|
+
import type { IPlugin } from '@emailmaker/extensions-sandbox';
|
|
378
|
+
|
|
379
|
+
class MyPluginSandbox implements IPlugin {
|
|
380
|
+
init() { /* ... */ }
|
|
381
|
+
afterInit?() { /* ... */ }
|
|
382
|
+
dispose() { /* ... */ }
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
App.registerPlugin('MyPluginSandbox', MyPluginSandbox);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
|
|
344
389
|
|
|
345
390
|
---
|
|
346
391
|
|
|
@@ -493,10 +538,15 @@ elementsApi.insert({
|
|
|
493
538
|
Добавление новой панели настроек. Например, можно добавить панель которая будет отображаться при клике на элементе в sandbox.
|
|
494
539
|
|
|
495
540
|
```ts
|
|
541
|
+
import { createComponentIdentifier } from '@emailmaker/extensions-app';
|
|
542
|
+
|
|
543
|
+
const SettingsPanelId = createComponentIdentifier('MySettingsPanel');
|
|
544
|
+
// ComponentRegistry.add(SettingsPanelId, MySettingsPanel);
|
|
545
|
+
|
|
496
546
|
const panel = editor.use('SettingsPanelApi');
|
|
497
547
|
panel.showSettingsPanel({
|
|
498
548
|
content: {
|
|
499
|
-
type:
|
|
549
|
+
type: SettingsPanelId,
|
|
500
550
|
props: {...}
|
|
501
551
|
},
|
|
502
552
|
caption: 'Настройки',
|
|
@@ -513,7 +563,7 @@ panel.showSettingsPanel({
|
|
|
513
563
|
```ts
|
|
514
564
|
panel.showSettingsPanel({
|
|
515
565
|
instanceKey: blockUuid,
|
|
516
|
-
content: { type:
|
|
566
|
+
content: { type: SettingsPanelId, props: { blockUuid, settings } },
|
|
517
567
|
});
|
|
518
568
|
```
|
|
519
569
|
|
|
@@ -531,20 +581,30 @@ panel.showSettingsPanel({
|
|
|
531
581
|
> Интерфейс основан на модалках `Ant Design`
|
|
532
582
|
|
|
533
583
|
```ts
|
|
584
|
+
import { createComponentIdentifier } from '@emailmaker/extensions-app';
|
|
585
|
+
import { ComponentRegistry } from '@emailmaker/extensions-react';
|
|
586
|
+
|
|
587
|
+
const MyPanelId = createComponentIdentifier('MyPanel');
|
|
588
|
+
ComponentRegistry.add(MyPanelId, MyPanel);
|
|
589
|
+
|
|
534
590
|
const modal = editor.use('ModalApi');
|
|
535
591
|
modal.show({
|
|
536
592
|
title: 'Выбор группы',
|
|
537
593
|
content: {
|
|
538
|
-
type:
|
|
539
|
-
props: { groups, settings }
|
|
540
|
-
}
|
|
594
|
+
type: MyPanelId,
|
|
595
|
+
props: { groups, settings },
|
|
596
|
+
},
|
|
541
597
|
});
|
|
542
598
|
```
|
|
543
599
|
|
|
600
|
+
Для простого UI можно передать JSX напрямую (см. раздел `extensions-react`).
|
|
601
|
+
|
|
544
602
|
|
|
545
603
|
### EmailSettingsApi
|
|
546
604
|
|
|
547
|
-
> API для работы с настройками
|
|
605
|
+
> API для работы с настройками письма (редактор email / emailmaker). В widget-сценариях может быть недоступен.
|
|
606
|
+
|
|
607
|
+
Позволяет получать и изменять настройки внешнего вида письма и стили элементов контента.
|
|
548
608
|
|
|
549
609
|
API разделен на два типа методов:
|
|
550
610
|
- **Layout Settings** — настройки письма целиком (фон, ширина, адаптивность)
|
|
@@ -605,18 +665,25 @@ msg.send('MY_EVENT', { value: 123 });
|
|
|
605
665
|
msg.addListener('MY_EVENT', (data) => console.log(data));
|
|
606
666
|
```
|
|
607
667
|
|
|
608
|
-
|
|
668
|
+
Выносите имена событий в общий модуль (CLI-шаблон: `src/interfaces/`), чтобы app и sandbox использовали одни и те же строки:
|
|
669
|
+
|
|
670
|
+
```ts
|
|
671
|
+
// src/interfaces/messages.ts
|
|
672
|
+
export const MY_PLUGIN_UPDATE = 'my-plugin:update' as const;
|
|
673
|
+
|
|
674
|
+
export type MyPluginUpdatePayload = { text: string };
|
|
675
|
+
```
|
|
609
676
|
|
|
610
677
|
```ts
|
|
611
|
-
|
|
678
|
+
// app
|
|
679
|
+
msg.send(MY_PLUGIN_UPDATE, { text: 'hello' });
|
|
612
680
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
void,
|
|
616
|
-
void
|
|
617
|
-
>('Activate_Product_Settings');
|
|
681
|
+
// sandbox
|
|
682
|
+
messageService.addListener(MY_PLUGIN_UPDATE, (data) => { /* ... */ });
|
|
618
683
|
```
|
|
619
684
|
|
|
685
|
+
Тип payload задайте рядом с константой (`MyPluginUpdatePayload`) — отдельный runtime-пакет для идентификаторов не нужен.
|
|
686
|
+
|
|
620
687
|
|
|
621
688
|
### SandboxScriptApi
|
|
622
689
|
|
|
@@ -706,14 +773,17 @@ syncService.commit();
|
|
|
706
773
|
|
|
707
774
|
## 🧱 Регистрация UI компонентов
|
|
708
775
|
|
|
709
|
-
`ComponentRegistry` нужен, когда вы хотите зарегистрировать React-компонент и потом передавать его в API по идентификатору:
|
|
776
|
+
`ComponentRegistry` нужен, когда вы хотите зарегистрировать React-компонент и потом передавать его в API по **типизированному** идентификатору:
|
|
710
777
|
|
|
711
778
|
```ts
|
|
779
|
+
import { createComponentIdentifier } from '@emailmaker/extensions-app';
|
|
712
780
|
import { ComponentRegistry } from '@emailmaker/extensions-react';
|
|
713
781
|
|
|
714
|
-
|
|
782
|
+
const MyPanelId = createComponentIdentifier<{ groups: Group[] }>('MyPanel');
|
|
715
783
|
|
|
716
|
-
ComponentRegistry.
|
|
784
|
+
ComponentRegistry.add(MyPanelId, MyReactPanel);
|
|
785
|
+
|
|
786
|
+
ComponentRegistry.override(MyPanelId, (Base) => (props) => (
|
|
717
787
|
<div className="bordered"><Base {...props} /></div>
|
|
718
788
|
));
|
|
719
789
|
```
|
|
@@ -721,7 +791,7 @@ ComponentRegistry.override('MyPanel', (Base) => (props) => (
|
|
|
721
791
|
## Когда использовать
|
|
722
792
|
|
|
723
793
|
- если хотите просто показать React UI, чаще всего удобнее передать JSX напрямую
|
|
724
|
-
- если нужен `ComponentId
|
|
794
|
+
- если нужен стабильный `ComponentId` для `{ type, props }` — `createComponentIdentifier` + `ComponentRegistry`
|
|
725
795
|
- если UI без React, используйте `DomComponentRegistry`
|
|
726
796
|
|
|
727
797
|
Пример с JSX:
|
|
@@ -735,11 +805,21 @@ settingsPanel.showSettingsPanel({
|
|
|
735
805
|
});
|
|
736
806
|
```
|
|
737
807
|
|
|
808
|
+
Пример с идентификатором:
|
|
809
|
+
|
|
810
|
+
```ts
|
|
811
|
+
settingsPanel.showSettingsPanel({
|
|
812
|
+
content: { type: MyPanelId, props: { groups } },
|
|
813
|
+
});
|
|
814
|
+
```
|
|
815
|
+
|
|
738
816
|
|
|
739
817
|
---
|
|
740
818
|
|
|
741
819
|
## 🎨 UI Kit
|
|
742
820
|
|
|
821
|
+
В **коде плагина** импортируйте компоненты из `@emailmaker/ui-kit`. В **release-сборке** `PluginDev` externalizes ui-kit на singleton хоста: `@emailmaker/emailmaker/ui-kit` (отдельно ставить main subpath не нужно).
|
|
822
|
+
|
|
743
823
|
### ColorPicker — минимальный пример
|
|
744
824
|
|
|
745
825
|
Растягивается на ширину родителя (Form.Item, колонку и т.д.) — дополнительный inline-style для ширины не нужен.
|
|
@@ -893,7 +973,7 @@ emailmaker.init({
|
|
|
893
973
|
|
|
894
974
|
> При множественной инициализации действует принцип «first-write wins» — опции фиксируются при первом создании экземпляра.
|
|
895
975
|
|
|
896
|
-
CLI-шаблон уже собирает типы отдельно (`npm run build:types`) и публикует `dist/
|
|
976
|
+
CLI-шаблон уже собирает типы отдельно (`npm run build:types`) и публикует `dist/public-types.d.ts` рядом с JS bundle, поэтому поддержку TypeScript стоит считать частью любого release target, а не только npm/ESM сценария.
|
|
897
977
|
|
|
898
978
|
### Расширение Config
|
|
899
979
|
|
|
@@ -940,7 +1020,7 @@ settingsPanel.showSettingsPanel({
|
|
|
940
1020
|
|
|
941
1021
|
### `--dev` / `--dev-packages`
|
|
942
1022
|
|
|
943
|
-
**Самый частый флаг для разработки:** подставляет **dev**-версии внутренних npm-пакетов (`@emailmaker/*`), которые в шаблонах задаются с dist-tag `dev` вместо `latest`. Используйте, когда нужны свежие предрелизные сборки экосистемы.
|
|
1023
|
+
**Самый частый флаг для разработки:** подставляет **dev**-версии внутренних npm-пакетов (`@emailmaker-internal/*`), которые в шаблонах задаются с dist-tag `dev` вместо `latest`. Используйте, когда нужны свежие предрелизные сборки экосистемы.
|
|
944
1024
|
|
|
945
1025
|
```bash
|
|
946
1026
|
npx @emailmaker/cli my-plugin --kind plugin --preset advanced --bundler vite --target npm-package --dev --output-dir ./my-plugin
|
|
@@ -959,8 +1039,8 @@ npx @emailmaker/cli my-plugin --kind plugin --preset advanced --bundler vite --t
|
|
|
959
1039
|
| `--advanced-profile` | Для `--stand-mode advanced`: `subpath`, `shadow-dom`, `umd`. |
|
|
960
1040
|
| `--preset` | Шаблон плагина: `minimal` или `advanced`. |
|
|
961
1041
|
| `--bundler` | `vite` или `webpack` — сборщик в шаблоне. |
|
|
962
|
-
| `--target` | Поставка плагина: `npm-package`, `browser`, `advanced
|
|
963
|
-
| `--advanced-target` |
|
|
1042
|
+
| `--target` | Поставка плагина: `npm-package`, `browser`, `advanced` (**`advanced` — только webpack**; у Vite доступны `npm-package` и `browser`). |
|
|
1043
|
+
| `--advanced-target` | Для `--target advanced` (только webpack): `async-globals` или `legacy-async-globals`. |
|
|
964
1044
|
| `--app` | Идентификатор приложения (`REACT_APP_NAME`), как в монорепозитории; в опубликованном CLI может быть скрыт. |
|
|
965
1045
|
| `--output-dir` | Каталог, куда положить сгенерированный проект. |
|
|
966
1046
|
| `--output-base` | Базовый каталог: внутри него будет создана папка проекта. |
|
|
@@ -977,7 +1057,7 @@ npx @emailmaker/cli --help
|
|
|
977
1057
|
- интерактивный wizard и неинтерактивный запуск;
|
|
978
1058
|
- генерация проекта плагина и демо-стендов;
|
|
979
1059
|
- шаблоны под **vite** и **webpack**;
|
|
980
|
-
- выбор способа поставки плагина: npm-модуль, браузерный
|
|
1060
|
+
- выбор способа поставки плагина: npm-модуль, браузерный bundle (`browser`), режим **advanced** (webpack-only).
|
|
981
1061
|
|
|
982
1062
|
## Основные режимы
|
|
983
1063
|
|
|
@@ -1035,7 +1115,14 @@ npx @emailmaker/cli my-plugin --kind plugin --preset advanced --bundler vite --t
|
|
|
1035
1115
|
|
|
1036
1116
|
Обычно это значит, что dev host использует `PluginDev({ externals: false })`, а release target уже требует runtime contract.
|
|
1037
1117
|
|
|
1038
|
-
|
|
1118
|
+
Проверьте локально через CLI-шаблон:
|
|
1119
|
+
|
|
1120
|
+
```bash
|
|
1121
|
+
npm run build
|
|
1122
|
+
npm run start:release
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
Также проверьте:
|
|
1039
1126
|
|
|
1040
1127
|
- target сборки в CLI / config
|
|
1041
1128
|
- release config для `src/index.ts`
|
|
@@ -1080,20 +1167,20 @@ npx @emailmaker/cli my-plugin --kind plugin --preset advanced --bundler vite --t
|
|
|
1080
1167
|
- **Externals не работают в dev server**
|
|
1081
1168
|
> В serve-режиме externals должны быть отключены: `PluginDev({ externals: false })`. Зависимости резолвятся из runtime через alias.
|
|
1082
1169
|
|
|
1083
|
-
- **ESM output не грузится через `<script>`**
|
|
1084
|
-
> ESM-сборка содержит `import
|
|
1170
|
+
- **ESM output не грузится через обычный `<script>`**
|
|
1171
|
+
> ESM-сборка содержит `import`. Используйте `<script type="module">`, npm-интеграцию или target **browser** (`PluginDev({ externals: 'globals' })`, UMD bundle).
|
|
1085
1172
|
|
|
1086
|
-
- **
|
|
1087
|
-
> Runtime должен быть загружен до плагина. Подключайте
|
|
1173
|
+
- **Browser/UMD-плагин: «Cannot read property of undefined»**
|
|
1174
|
+
> Runtime хоста должен быть загружен до плагина. Подключайте через npm + lazy import, либо декларативно `{ type: 'umd', url: '…', name: 'MyPlugin', resolve: 'registry' }` (с `pluginRegistry.add`).
|
|
1088
1175
|
|
|
1089
1176
|
- **Не загружаются JS/CSS / iframe не отображается**
|
|
1090
1177
|
> Проверьте `publicPath` и подключение основного плагина (`VitePlugin` / `WebpackPlugin`). В serve-режиме он обслуживает статику из `node_modules/`.
|
|
1091
1178
|
|
|
1092
1179
|
- **Панель или компонент не отображается**
|
|
1093
|
-
> Убедитесь в регистрации через `ComponentRegistry`.
|
|
1180
|
+
> Убедитесь в регистрации через `ComponentRegistry` и `createComponentIdentifier`.
|
|
1094
1181
|
|
|
1095
1182
|
- **Событие не обрабатывается**
|
|
1096
|
-
> Проверьте подписку на событие в `MessageService
|
|
1183
|
+
> Проверьте подписку на событие в `MessageService` и совпадение строковых id в app и sandbox.
|
|
1097
1184
|
|
|
1098
1185
|
- **Изменения в iframe теряются**
|
|
1099
1186
|
> Не забывайте вызывать `syncService.commit()`.
|
|
@@ -1104,7 +1191,7 @@ npx @emailmaker/cli my-plugin --kind plugin --preset advanced --bundler vite --t
|
|
|
1104
1191
|
|
|
1105
1192
|
**С `externals.json` на `PluginDev`:**
|
|
1106
1193
|
|
|
1107
|
-
|
|
1194
|
+
Для **новых** проектов используйте только `PluginDev`. Файл `externals.json` в экосистеме остаётся legacy-следом; не подключайте его вручную в Vite-шаблонах.
|
|
1108
1195
|
|
|
1109
1196
|
**С `pluginRegistry.add` на прямой класс:**
|
|
1110
1197
|
|
package/index.js
CHANGED
|
@@ -503,11 +503,17 @@ function R(e = p()) {
|
|
|
503
503
|
}
|
|
504
504
|
new w(() => R());
|
|
505
505
|
//#endregion
|
|
506
|
+
//#region packages/extensions-core/identifiers/index.ts
|
|
507
|
+
function z(e) {
|
|
508
|
+
return h(e);
|
|
509
|
+
}
|
|
510
|
+
z("HANDLE_ATOM_INSERT"), z("SETTINGS_PANEL_EVENT"), z("MODAL_SHOW_EVENT"), z("MODAL_CLOSE_EVENT"), z("MODAL_UPDATE_EVENT");
|
|
511
|
+
//#endregion
|
|
506
512
|
//#region src/extensions/api/src/index.ts
|
|
507
|
-
function
|
|
513
|
+
function B() {
|
|
508
514
|
return typeof globalThis.crypto?.randomUUID == "function" ? globalThis.crypto.randomUUID() : `component-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
509
515
|
}
|
|
510
|
-
function
|
|
516
|
+
function V(e = B()) {
|
|
511
517
|
return e;
|
|
512
518
|
}
|
|
513
519
|
//#endregion
|
|
@@ -567,7 +573,7 @@ D(S), (function(e) {
|
|
|
567
573
|
n.packages[e.id] = e, n.validateAll();
|
|
568
574
|
}, t.__compat.registerPackage({
|
|
569
575
|
id: "extensions-react",
|
|
570
|
-
version: "1.0.111-dev.
|
|
576
|
+
version: "1.0.111-dev.9",
|
|
571
577
|
requires: {
|
|
572
578
|
host: "^1.0.105",
|
|
573
579
|
"extensions-api": "^0.9.0"
|
|
@@ -575,6 +581,6 @@ D(S), (function(e) {
|
|
|
575
581
|
});
|
|
576
582
|
}
|
|
577
583
|
})(typeof window < "u" ? window : typeof globalThis < "u" ? globalThis : void 0);
|
|
578
|
-
var
|
|
584
|
+
var H = I(S);
|
|
579
585
|
//#endregion
|
|
580
|
-
export {
|
|
586
|
+
export { H as ComponentRegistry, V as createComponentIdentifier };
|
package/package.json
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
"react-dom": "^18.2.0",
|
|
11
11
|
"@types/react": "^18.2.70",
|
|
12
12
|
"@types/react-dom": "^18.2.0",
|
|
13
|
-
"@emailmaker/emailmaker": "1.0.111-dev.
|
|
14
|
-
"@emailmaker/extensions-app": "1.0.111-dev.
|
|
13
|
+
"@emailmaker/emailmaker": "1.0.111-dev.9",
|
|
14
|
+
"@emailmaker/extensions-app": "1.0.111-dev.9"
|
|
15
15
|
},
|
|
16
16
|
"name": "@emailmaker/extensions-react",
|
|
17
|
-
"version": "1.0.111-dev.
|
|
17
|
+
"version": "1.0.111-dev.9"
|
|
18
18
|
}
|
package/types.d.ts
CHANGED
|
@@ -54,11 +54,22 @@ interface IDisposable {
|
|
|
54
54
|
* Payload for `BlocksApi.handleInject` when a block/structure was inserted in the sandbox
|
|
55
55
|
* (mirrors `application_block_inserted` message data).
|
|
56
56
|
*/
|
|
57
|
-
interface BlockInjectInfo {
|
|
57
|
+
interface BlockInjectInfo$1 {
|
|
58
|
+
/** Editor catalog route (project / template / common / structure path) — same as legacy iframe `type`. */
|
|
58
59
|
type?: string;
|
|
60
|
+
/** Alias of {@link type} when enriched on the app side. */
|
|
61
|
+
insertFrom?: string;
|
|
59
62
|
name?: string;
|
|
60
63
|
blockId?: string;
|
|
61
64
|
project?: string;
|
|
65
|
+
fragmentRole?: 'block' | 'structure';
|
|
66
|
+
/** Catalog block id (same as {@link blockId} when known). */
|
|
67
|
+
id?: string;
|
|
68
|
+
title?: string | null;
|
|
69
|
+
/** REST / API block taxonomy — not the same as {@link type}. */
|
|
70
|
+
blockType?: string;
|
|
71
|
+
/** Host-only metadata (`Block.meta` / `setBlockMeta` on the embedder side). */
|
|
72
|
+
meta?: Record<string, unknown>;
|
|
62
73
|
}
|
|
63
74
|
/**
|
|
64
75
|
* Context passed to ElementsApi.handleBeforeInject before element (atom) HTML is sent to the iframe.
|
|
@@ -73,7 +84,7 @@ interface ElementInsertContext extends Record<string, unknown> {
|
|
|
73
84
|
* Context passed to BlocksApi.handleBeforeInject before block HTML is sent to the iframe.
|
|
74
85
|
* `insertFrom` is the editor catalog route (e.g. project / template / common), not REST Block.type taxonomy.
|
|
75
86
|
*/
|
|
76
|
-
interface BlockInsertContext extends Record<string, unknown> {
|
|
87
|
+
interface BlockInsertContext$1 extends Record<string, unknown> {
|
|
77
88
|
html: string;
|
|
78
89
|
insertFrom?: string;
|
|
79
90
|
fragmentRole?: 'block' | 'structure';
|
|
@@ -107,6 +118,8 @@ interface BlockInsertContext extends Record<string, unknown> {
|
|
|
107
118
|
project_title?: string;
|
|
108
119
|
project_author?: string;
|
|
109
120
|
isAmp?: boolean;
|
|
121
|
+
/** Host-only metadata (not sent to iframe). */
|
|
122
|
+
meta?: Record<string, unknown>;
|
|
110
123
|
/** Remaining catalog/API fields not mapped above (shallow copy). */
|
|
111
124
|
catalogExtra?: Record<string, unknown>;
|
|
112
125
|
}
|
|
@@ -118,12 +131,14 @@ interface IBlocksApi {
|
|
|
118
131
|
* Runs before block HTML is posted to the iframe. Listeners receive a mutable context; they may
|
|
119
132
|
* mutate `html` and related fields or return a partial object to merge (SaveEmitter-style).
|
|
120
133
|
*/
|
|
121
|
-
handleBeforeInject(listener: (ctx: BlockInsertContext) => MayBePromise<Partial<BlockInsertContext> | void>, priority?: number, thisArg?: unknown): IDisposable;
|
|
134
|
+
handleBeforeInject(listener: (ctx: BlockInsertContext$1) => MayBePromise<Partial<BlockInsertContext$1> | void>, priority?: number, thisArg?: unknown): IDisposable;
|
|
122
135
|
/**
|
|
123
|
-
* Fires after a block or structure was inserted in the sandbox
|
|
136
|
+
* Fires after a block or structure was inserted in the sandbox.
|
|
137
|
+
* Payload is enriched on the app shell (incl. `meta`, `insertFrom`, `blockType`) from pending insert context;
|
|
138
|
+
* iframe only sends a minimal ack on `application_block_inserted`.
|
|
124
139
|
* Does not allow changing markup; use {@link handleBeforeInject} to transform HTML before postMessage.
|
|
125
140
|
*/
|
|
126
|
-
handleInject(listener: (info: BlockInjectInfo) => void, priority?: number, thisArg?: unknown): IDisposable;
|
|
141
|
+
handleInject(listener: (info: BlockInjectInfo$1) => void, priority?: number, thisArg?: unknown): IDisposable;
|
|
127
142
|
}
|
|
128
143
|
/**
|
|
129
144
|
* Information about an element.
|