@emailmaker/extensions-app 1.0.111-dev.7 → 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.
Files changed (4) hide show
  1. package/README.md +143 -56
  2. package/index.js +60 -22
  3. package/package.json +2 -2
  4. package/types.d.ts +27 -6
package/README.md CHANGED
@@ -15,8 +15,8 @@
15
15
  ## ⚙️ Требования
16
16
 
17
17
  - Современный браузер с поддержкой **ES2015** (и выше)
18
- - Node.js >= 14
19
- - React и Ant Design подключаются через [`externals`](https://webpack.js.org/configuration/externals/) или напрямую из `@emailmaker/emailmaker/runtime`
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
- 👉 Самый простой способ начать — использовать [готовый шаблон](https://github.com/emailmaker/simple_plugin):
36
+ 👉 Рекомендуемый способ — **CLI** (`@emailmaker/cli`): согласованная структура, Vite/Webpack, app + sandbox, dev/release host.
37
37
 
38
38
  ```bash
39
- git clone https://github.com/emailmaker/simple_plugin
40
- cd simple_plugin
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/emailmaker/runtime @emailmaker/extensions-app @emailmaker/extensions-react @emailmaker/extensions-sandbox
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` ставится отдельно, если плагин использует готовые UI-компоненты платформы.
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, добавьте еще `@emailmaker/ui-kit`
97
- - если пишете только sandbox-часть, нужен `@emailmaker/extensions-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/index.d.ts` рядом с JS bundle, поэтому TypeScript support сохраняется и для browser/advanced targets.
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-root/
278
- ├── shared/ # Общие типы и интерфейсы
279
- │ └── interfaces.ts # Идентификаторы сообщений
280
- ├── app/ # UI-часть, взаимодействие с редактором
281
- │ └── MyPlugin.ts # Регистрация и логика плагина
282
- ├── sandbox/ # Работа с DOM письма
283
- │ └── index.ts # Точка входа для sandbox
284
- ├── test/ # Точка входа для тестирования
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
- - `shared` — общие типы для взаимодействия между `app` и `sandbox`
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
- - `sandbox/index.ts` — точка входа в скрипт, взаимодействующий с DOM письма. Скрипт должен быть собран отдельной точкой входа, так как он исполняется в изолированной среде iframe.
296
- - `test/index.tsx` — пример локального запуска редактора `emailmaker` с загрузкой плагина из `app`
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: 'SettingsPanelId',
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: 'SettingsPanelId', props: { blockUuid, settings } },
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: 'MyPanel',
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
- import { createIdentifier } from 'di';
678
+ // app
679
+ msg.send(MY_PLUGIN_UPDATE, { text: 'hello' });
612
680
 
613
- export const Activate_Product_Settings = createIdentifier<
614
- { groupId?: string; visualSettings: VisualSettings },
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
- ComponentRegistry.add('MyPanel', MyReactPanel);
782
+ const MyPanelId = createComponentIdentifier<{ groups: Group[] }>('MyPanel');
715
783
 
716
- ComponentRegistry.override('MyPanel', (Base) => (props) => (
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`, используйте `ComponentRegistry`
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/index.d.ts`, поэтому поддержку TypeScript стоит считать частью любого release target, а не только npm/ESM сценария.
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` | Доп. цель для режима `advanced` (только webpack), см. справку CLI. |
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-модуль, браузерный бандл, режим **advanced**.
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` и не работает как обычный скрипт. Используйте `<script type="module">` или соберите плагин в режиме `global` / `iife`.
1170
+ - **ESM output не грузится через обычный `<script>`**
1171
+ > ESM-сборка содержит `import`. Используйте `<script type="module">`, npm-интеграцию или target **browser** (`PluginDev({ externals: 'globals' })`, UMD bundle).
1085
1172
 
1086
- - **Global-плагин: «Cannot read property of undefined»**
1087
- > Runtime должен быть загружен до плагина. Подключайте плагин через ленивый импорт `() => import(…)` или декларативно `{ type: 'global', url: '…' }`.
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
- Старый подход с `externals.json` продолжает работать — файл генерируется для обратной совместимости. Но рекомендуем перейти на `PluginDev`: удалите загрузку `externals.json` из конфига и подключите плагин — он настроит externals и alias автоматически.
1194
+ Для **новых** проектов используйте только `PluginDev`. Файл `externals.json` в экосистеме остаётся legacy-следом; не подключайте его вручную в Vite-шаблонах.
1108
1195
 
1109
1196
  **С `pluginRegistry.add` на прямой класс:**
1110
1197
 
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import "react";
1
2
  //#region packages/runtime-core/disposable/index.ts
2
3
  var e = class e {
3
4
  _isDisposed = !1;
@@ -400,6 +401,43 @@ function w(e = c()) {
400
401
  }
401
402
  var T = new y(() => w());
402
403
  //#endregion
404
+ //#region packages/extensions-core/identifiers/index.ts
405
+ function E(e) {
406
+ return u(e);
407
+ }
408
+ E("HANDLE_ATOM_INSERT"), E("SETTINGS_PANEL_EVENT"), E("MODAL_SHOW_EVENT"), E("MODAL_CLOSE_EVENT"), E("MODAL_UPDATE_EVENT");
409
+ //#endregion
410
+ //#region packages/extensions-core/utils/blockInjectInfo.ts
411
+ function D(e) {
412
+ if (e.meta !== void 0 && e.meta !== null && typeof e.meta == "object") return e.meta;
413
+ let t = e.catalogExtra?.meta;
414
+ if (typeof t == "object" && t) return t;
415
+ }
416
+ function O(e, t) {
417
+ let n = e.insertFrom ?? t?.type, r = t?.blockId ?? (e.id != null && e.id !== "" ? String(e.id) : void 0), i = t?.project ?? (e.project !== void 0 && e.project !== null ? String(e.project) : void 0);
418
+ return {
419
+ type: t?.type ?? n,
420
+ insertFrom: n,
421
+ name: t?.name ?? e.name,
422
+ blockId: r,
423
+ project: i,
424
+ fragmentRole: e.fragmentRole,
425
+ id: r,
426
+ title: e.title ?? void 0,
427
+ blockType: e.type,
428
+ meta: D(e)
429
+ };
430
+ }
431
+ function k(e, t) {
432
+ return t ? O(t, e) : {
433
+ type: e.type,
434
+ name: e.name,
435
+ blockId: e.blockId,
436
+ project: e.project,
437
+ insertFrom: e.type
438
+ };
439
+ }
440
+ //#endregion
403
441
  //#region src/extensions/api/src/index.ts
404
442
  (function(e) {
405
443
  if (!(!e || typeof e != "object")) {
@@ -456,12 +494,12 @@ var T = new y(() => w());
456
494
  n.packages[e.id] = e, n.validateAll();
457
495
  }, t.__compat.registerPackage({
458
496
  id: "extensions-api",
459
- version: "1.0.111-dev.7",
497
+ version: "1.0.111-dev.9",
460
498
  requires: { host: "^1.0.105" }
461
499
  });
462
500
  }
463
501
  })(typeof window < "u" ? window : typeof globalThis < "u" ? globalThis : void 0);
464
- function E(e, t, n, r) {
502
+ function A(e, t, n, r) {
465
503
  if (typeof r.value == "function") {
466
504
  Object.defineProperty(e, n, {
467
505
  value: r.value.bind(t),
@@ -489,50 +527,50 @@ function E(e, t, n, r) {
489
527
  enumerable: !1
490
528
  });
491
529
  }
492
- function D(e, t, n) {
530
+ function j(e, t, n) {
493
531
  let r = t.use(n), i = /* @__PURE__ */ new Set(), a = [r];
494
532
  for (let e = Object.getPrototypeOf(r); e && e !== Object.prototype; e = Object.getPrototypeOf(e)) a.push(e);
495
533
  for (let t of a) for (let n of Reflect.ownKeys(t)) {
496
534
  if (n === "constructor" || i.has(n)) continue;
497
535
  let a = Object.getOwnPropertyDescriptor(t, n);
498
- a && (i.add(n), E(e, r, n, a));
536
+ a && (i.add(n), A(e, r, n, a));
499
537
  }
500
538
  }
501
- function O() {
539
+ function M() {
502
540
  return typeof globalThis.crypto?.randomUUID == "function" ? globalThis.crypto.randomUUID() : `component-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
503
541
  }
504
- var k = class {
542
+ var N = class {
505
543
  constructor(e) {
506
- D(this, e, "SandboxScriptApi");
544
+ j(this, e, "SandboxScriptApi");
507
545
  }
508
- }, A = class {
546
+ }, P = class {
509
547
  constructor(e) {
510
- D(this, e, "ElementsApi");
548
+ j(this, e, "ElementsApi");
511
549
  }
512
- }, j = class {
550
+ }, F = class {
513
551
  constructor(e) {
514
- D(this, e, "BlocksApi");
552
+ j(this, e, "BlocksApi");
515
553
  }
516
- }, M = class {
554
+ }, I = class {
517
555
  constructor(e) {
518
- D(this, e, "MessageService");
556
+ j(this, e, "MessageService");
519
557
  }
520
- }, N = class {
558
+ }, L = class {
521
559
  constructor(e) {
522
- D(this, e, "SettingsPanelApi");
560
+ j(this, e, "SettingsPanelApi");
523
561
  }
524
- }, P = class {
562
+ }, R = class {
525
563
  constructor(e) {
526
- D(this, e, "ModalApi");
564
+ j(this, e, "ModalApi");
527
565
  }
528
- }, F = class {
566
+ }, z = class {
529
567
  constructor(e) {
530
- D(this, e, "EmailSettingsApi");
568
+ j(this, e, "EmailSettingsApi");
531
569
  }
532
570
  };
533
- function I(e = O()) {
571
+ function B(e = M()) {
534
572
  return e;
535
573
  }
536
- var L = S(_), R = "1.0.111-dev.7";
574
+ var V = S(_), H = "1.0.111-dev.9";
537
575
  //#endregion
538
- export { j as BlocksApi, L as DomComponentRegistry, A as ElementsApi, F as EmailSettingsApi, M as MessageService, P as ModalApi, k as SandboxScriptApi, N as SettingsPanelApi, I as createComponentIdentifier, T as pluginRegistry, R as version };
576
+ export { F as BlocksApi, V as DomComponentRegistry, P as ElementsApi, z as EmailSettingsApi, I as MessageService, R as ModalApi, N as SandboxScriptApi, L as SettingsPanelApi, O as blockInsertContextToInjectInfo, B as createComponentIdentifier, k as mergeBlockInjectAck, T as pluginRegistry, H as version };
package/package.json CHANGED
@@ -5,8 +5,8 @@
5
5
  "main": "index.js",
6
6
  "types": "types.d.ts",
7
7
  "name": "@emailmaker/extensions-app",
8
- "version": "1.0.111-dev.7",
8
+ "version": "1.0.111-dev.9",
9
9
  "dependencies": {
10
- "@emailmaker/emailmaker": "1.0.111-dev.7"
10
+ "@emailmaker/emailmaker": "1.0.111-dev.9"
11
11
  }
12
12
  }
package/types.d.ts CHANGED
@@ -53,11 +53,22 @@ interface IDisposable$1 {
53
53
  * Payload for `BlocksApi.handleInject` when a block/structure was inserted in the sandbox
54
54
  * (mirrors `application_block_inserted` message data).
55
55
  */
56
- interface BlockInjectInfo {
56
+ interface BlockInjectInfo$1 {
57
+ /** Editor catalog route (project / template / common / structure path) — same as legacy iframe `type`. */
57
58
  type?: string;
59
+ /** Alias of {@link type} when enriched on the app side. */
60
+ insertFrom?: string;
58
61
  name?: string;
59
62
  blockId?: string;
60
63
  project?: string;
64
+ fragmentRole?: 'block' | 'structure';
65
+ /** Catalog block id (same as {@link blockId} when known). */
66
+ id?: string;
67
+ title?: string | null;
68
+ /** REST / API block taxonomy — not the same as {@link type}. */
69
+ blockType?: string;
70
+ /** Host-only metadata (`Block.meta` / `setBlockMeta` on the embedder side). */
71
+ meta?: Record<string, unknown>;
61
72
  }
62
73
  /**
63
74
  * Context passed to ElementsApi.handleBeforeInject before element (atom) HTML is sent to the iframe.
@@ -72,7 +83,7 @@ interface ElementInsertContext extends Record<string, unknown> {
72
83
  * Context passed to BlocksApi.handleBeforeInject before block HTML is sent to the iframe.
73
84
  * `insertFrom` is the editor catalog route (e.g. project / template / common), not REST Block.type taxonomy.
74
85
  */
75
- interface BlockInsertContext extends Record<string, unknown> {
86
+ interface BlockInsertContext$1 extends Record<string, unknown> {
76
87
  html: string;
77
88
  insertFrom?: string;
78
89
  fragmentRole?: 'block' | 'structure';
@@ -106,6 +117,8 @@ interface BlockInsertContext extends Record<string, unknown> {
106
117
  project_title?: string;
107
118
  project_author?: string;
108
119
  isAmp?: boolean;
120
+ /** Host-only metadata (not sent to iframe). */
121
+ meta?: Record<string, unknown>;
109
122
  /** Remaining catalog/API fields not mapped above (shallow copy). */
110
123
  catalogExtra?: Record<string, unknown>;
111
124
  }
@@ -117,12 +130,14 @@ interface IBlocksApi {
117
130
  * Runs before block HTML is posted to the iframe. Listeners receive a mutable context; they may
118
131
  * mutate `html` and related fields or return a partial object to merge (SaveEmitter-style).
119
132
  */
120
- handleBeforeInject(listener: (ctx: BlockInsertContext) => MayBePromise$1<Partial<BlockInsertContext> | void>, priority?: number, thisArg?: unknown): IDisposable$1;
133
+ handleBeforeInject(listener: (ctx: BlockInsertContext$1) => MayBePromise$1<Partial<BlockInsertContext$1> | void>, priority?: number, thisArg?: unknown): IDisposable$1;
121
134
  /**
122
- * Fires after a block or structure was inserted in the sandbox (same channel as `application_block_inserted`).
135
+ * Fires after a block or structure was inserted in the sandbox.
136
+ * Payload is enriched on the app shell (incl. `meta`, `insertFrom`, `blockType`) from pending insert context;
137
+ * iframe only sends a minimal ack on `application_block_inserted`.
123
138
  * Does not allow changing markup; use {@link handleBeforeInject} to transform HTML before postMessage.
124
139
  */
125
- handleInject(listener: (info: BlockInjectInfo) => void, priority?: number, thisArg?: unknown): IDisposable$1;
140
+ handleInject(listener: (info: BlockInjectInfo$1) => void, priority?: number, thisArg?: unknown): IDisposable$1;
126
141
  }
127
142
  /**
128
143
  * Information about an element.
@@ -177,6 +192,8 @@ interface IElementsApi {
177
192
  html: string;
178
193
  }) => void, priority?: number, thisArg?: unknown): IDisposable$1;
179
194
  }
195
+ /** Minimal sandbox ack for `application_block_inserted` (iframe → app). */
196
+ type BlockInsertSandboxAck$1 = Pick<BlockInjectInfo$1, 'type' | 'name' | 'blockId' | 'project'>;
180
197
  /**
181
198
  * API for interacting with the MessageService.
182
199
  * Provides methods to send and receive messages, as well as manage event listeners.
@@ -364,6 +381,10 @@ interface ISettingsPanelApi {
364
381
  */
365
382
  closeSettingsPanel(): void;
366
383
  }
384
+ /** @see extensions-core `blockInsertContextToInjectInfo` */
385
+ declare function blockInsertContextToInjectInfo(ctx: BlockInsertContext, ack?: BlockInsertSandboxAck): BlockInjectInfo;
386
+ /** @see extensions-core `mergeBlockInjectAck` */
387
+ declare function mergeBlockInjectAck(ack: BlockInsertSandboxAck, ctx?: BlockInsertContext | null): BlockInjectInfo;
367
388
  /**
368
389
  * Unique identifier for a UI component.
369
390
  * @template P The component's props type.
@@ -654,4 +675,4 @@ declare module '@emailmaker/emailmaker' {
654
675
  }
655
676
  declare const pluginRegistry: PluginRegistry;
656
677
  declare const version: string;
657
- export { BlocksApi, ComponentId, ComponentInput, ComponentInputRegistry, ComponentType, DomComponentRegistry, ElementsApi, EmailContentStyles, EmailLayoutSettings, EmailSettingsApi, type IDisposable, IDomComponent, IDomComponentFactory, IDomComponentRegistry, type ISandboxScriptHandle, Identifier, MayBePromise, MessageService, ModalApi, SandboxScriptApi, SettingsPanelApi, createComponentIdentifier, pluginRegistry, version };
678
+ export { type BlockInjectInfo$1 as BlockInjectInfo, type BlockInsertContext$1 as BlockInsertContext, type BlockInsertSandboxAck$1 as BlockInsertSandboxAck, BlocksApi, ComponentId, ComponentInput, ComponentInputRegistry, ComponentType, DomComponentRegistry, type ElementInsertContext, ElementsApi, EmailContentStyles, EmailLayoutSettings, EmailSettingsApi, type IBlocksApi, type IDisposable, IDomComponent, IDomComponentFactory, IDomComponentRegistry, type IElementsApi, type ISandboxScriptHandle, Identifier, MayBePromise, MessageService, ModalApi, SandboxScriptApi, SettingsPanelApi, blockInsertContextToInjectInfo, createComponentIdentifier, mergeBlockInjectAck, pluginRegistry, version };