@emailmaker/extensions-react 1.1.85-dev.1 → 1.1.85-dev.11
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 +42 -0
- package/index.js +53 -42
- package/package.json +4 -4
- package/types.d.ts +9 -0
package/README.md
CHANGED
|
@@ -340,6 +340,18 @@ import { ComponentRegistry } from '@emailmaker/extensions-react';
|
|
|
340
340
|
Лечится добавлением `PluginDev` в конфигурацию сборки плагина (`externals: 'esm'`) либо сборкой
|
|
341
341
|
плагина на глобалах.
|
|
342
342
|
|
|
343
|
+
## Ваши настройки резолва редактора не касаются
|
|
344
|
+
|
|
345
|
+
Внутри пакета React адресуется **путём** к копии, которая лежит в нём же, а не именем `react`.
|
|
346
|
+
Следствий два, и оба в вашу пользу:
|
|
347
|
+
|
|
348
|
+
- `resolve.dedupe`, `resolve.alias`, `resolve.modules` и Module Federation `shared` работают у вас
|
|
349
|
+
так, как вы их написали. Мы не занимаем имя `react` и ничего у вас не перехватываем.
|
|
350
|
+
- Редактор не зависит от того, что вы с этим именем делаете: своя копия достаётся ему при любой
|
|
351
|
+
конфигурации сборки, в том числе если наш плагин у вас не подключён.
|
|
352
|
+
|
|
353
|
+
Одно исключение — `sharedReact` ниже: им вы просите обратного.
|
|
354
|
+
|
|
343
355
|
## Общий React (необязательно)
|
|
344
356
|
|
|
345
357
|
Плагин хоста умеет обратное: отдать редактору **ваш** React вместо вендоренного —
|
|
@@ -866,6 +878,22 @@ App.registerPlugin('MyPluginSandbox', MyPluginSandbox);
|
|
|
866
878
|
|
|
867
879
|
> ⚠️ Sandbox работает в изолированном iframe. React-компоненты здесь недоступны — только нативный DOM.
|
|
868
880
|
|
|
881
|
+
### Скрипт живёт одно письмо
|
|
882
|
+
|
|
883
|
+
Документ холста пересоздаётся на каждое письмо: скрипт песочницы выполняется заново, и ничего из
|
|
884
|
+
прошлого письма в нём не остаётся. `handle.ready` — обещание, оно разрешается один раз, для первого
|
|
885
|
+
холста. Чтобы узнавать о готовности каждый раз, подпишитесь на `onReady`:
|
|
886
|
+
|
|
887
|
+
```ts
|
|
888
|
+
const script = sandboxApi.registerSandboxScript(url);
|
|
889
|
+
script.onReady(() => {
|
|
890
|
+
messageService.send('my-plugin:settings', mySettings);
|
|
891
|
+
});
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
Последнее, что вы отправили скрипту после его готовности, редактор повторяет в новый холст сам —
|
|
895
|
+
по каждому ключу сообщения. `onReady` нужен для состояния, которое вы считаете заново.
|
|
896
|
+
|
|
869
897
|
|
|
870
898
|
### MessageService (внутри sandbox)
|
|
871
899
|
|
|
@@ -978,6 +1006,20 @@ import { Form, FormColorField } from "@emailmaker/ui-kit";
|
|
|
978
1006
|
</Form>
|
|
979
1007
|
```
|
|
980
1008
|
|
|
1009
|
+
### Значки
|
|
1010
|
+
|
|
1011
|
+
Значки ui-kit берите по одному из подпути `icons` — в сборку плагина попадут только те, что вы
|
|
1012
|
+
используете. В release-сборке этот путь уходит на `@emailmaker/emailmaker/ui-kit/icons` хоста.
|
|
1013
|
+
|
|
1014
|
+
```tsx
|
|
1015
|
+
import { AIRequests, Sun } from "@emailmaker/ui-kit/icons";
|
|
1016
|
+
|
|
1017
|
+
<AIRequests />
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
`<EmIcons icon="Sun" />` тоже работает, но подтягивает весь каталог значков и пишет в консоль
|
|
1021
|
+
предупреждение.
|
|
1022
|
+
|
|
981
1023
|
|
|
982
1024
|
---
|
|
983
1025
|
|
package/index.js
CHANGED
|
@@ -42,7 +42,7 @@ var l = class e extends a {
|
|
|
42
42
|
_injectCallbacks = [];
|
|
43
43
|
_injections = Object.create(null);
|
|
44
44
|
_runCallbacks(e) {
|
|
45
|
-
this._injectCallbacks.forEach((t) => t(e));
|
|
45
|
+
[...this._injectCallbacks].forEach((t) => t(e));
|
|
46
46
|
}
|
|
47
47
|
constructor(e = null) {
|
|
48
48
|
super(), this._parent = e, e && this.addDisposable(e.onInject((e) => this._runCallbacks(e)));
|
|
@@ -63,7 +63,7 @@ var l = class e extends a {
|
|
|
63
63
|
}
|
|
64
64
|
_onInject(e, t, n = new a()) {
|
|
65
65
|
return n.addDisposable(this.onInject((r) => {
|
|
66
|
-
e === r && (n.dispose(), t(this.getInstance(r)));
|
|
66
|
+
e === r && !n.isDisposed() && (n.dispose(), t(this.getInstance(r)));
|
|
67
67
|
})), this._parent && n.addDisposable(this._parent._onInject(e, t, n)), this.addDisposable(n), n;
|
|
68
68
|
}
|
|
69
69
|
getInstance(e, t = !0) {
|
|
@@ -386,19 +386,30 @@ var T = new Proxy({}, { get(e, t, n) {
|
|
|
386
386
|
forContext() {
|
|
387
387
|
return this.target().forContext();
|
|
388
388
|
}
|
|
389
|
-
}, O = v("ComponentRegistry"), k;
|
|
390
|
-
function A(
|
|
391
|
-
k
|
|
389
|
+
}, O = v("ComponentRegistry"), k = v("ComponentRegistryGate");
|
|
390
|
+
function A() {
|
|
391
|
+
return T.getOrCreateInstance(k, () => ({ pending: [] }));
|
|
392
392
|
}
|
|
393
|
-
function j(e
|
|
393
|
+
function j(e) {
|
|
394
|
+
let t = A();
|
|
395
|
+
t.factory = e;
|
|
396
|
+
let n = t.pending.splice(0, t.pending.length);
|
|
397
|
+
for (let e of n) try {
|
|
398
|
+
e();
|
|
399
|
+
} catch (e) {
|
|
400
|
+
console.error("[extensions] deferred UI call failed once the component registry arrived:", e);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
function M(e, t = O) {
|
|
394
404
|
let n = T.getInstance(t);
|
|
395
405
|
if (n) return n;
|
|
396
|
-
|
|
397
|
-
|
|
406
|
+
let r = A().factory;
|
|
407
|
+
if (!r) throw Error("[extensions] component registry is not loaded yet — UI work starts at init()");
|
|
408
|
+
return T.getOrCreateInstance(t, r);
|
|
398
409
|
}
|
|
399
410
|
//#endregion
|
|
400
411
|
//#region packages/extensions-core/components/DomComponentRegistry.ts
|
|
401
|
-
var
|
|
412
|
+
var N = class {
|
|
402
413
|
_factories = /* @__PURE__ */ new Map();
|
|
403
414
|
add(e, t) {
|
|
404
415
|
let n = e;
|
|
@@ -409,28 +420,28 @@ var M = class {
|
|
|
409
420
|
get(e) {
|
|
410
421
|
return this._factories.get(e);
|
|
411
422
|
}
|
|
412
|
-
},
|
|
413
|
-
function
|
|
414
|
-
return T.getOrCreateInstance(t, () => new
|
|
423
|
+
}, P = v("DomComponentRegistry");
|
|
424
|
+
function F(e, t = P) {
|
|
425
|
+
return T.getOrCreateInstance(t, () => new N());
|
|
415
426
|
}
|
|
416
427
|
//#endregion
|
|
417
428
|
//#region packages/extensions-core/components/ComponentRegistry.ts
|
|
418
|
-
function F(e) {
|
|
419
|
-
return typeof e == "function";
|
|
420
|
-
}
|
|
421
429
|
function I(e) {
|
|
422
|
-
return
|
|
430
|
+
return typeof e == "function";
|
|
423
431
|
}
|
|
424
432
|
function L(e) {
|
|
425
|
-
return
|
|
433
|
+
return i(e);
|
|
426
434
|
}
|
|
427
435
|
function R(e) {
|
|
428
|
-
return typeof e == "
|
|
436
|
+
return typeof e == "function" || L(e);
|
|
429
437
|
}
|
|
430
|
-
function z(e
|
|
438
|
+
function z(e) {
|
|
439
|
+
return typeof e == "object" && !!e && "type" in e && "props" in e && !L(e);
|
|
440
|
+
}
|
|
441
|
+
function B(e, t) {
|
|
431
442
|
return n(e, t);
|
|
432
443
|
}
|
|
433
|
-
function
|
|
444
|
+
function V(t) {
|
|
434
445
|
return class extends e {
|
|
435
446
|
_ref = r();
|
|
436
447
|
_instance;
|
|
@@ -448,7 +459,7 @@ function B(t) {
|
|
|
448
459
|
}
|
|
449
460
|
};
|
|
450
461
|
}
|
|
451
|
-
var
|
|
462
|
+
var H = class {
|
|
452
463
|
_domComponentRegistry;
|
|
453
464
|
_components = /* @__PURE__ */ new Map();
|
|
454
465
|
_domAdapters = /* @__PURE__ */ new Map();
|
|
@@ -482,26 +493,26 @@ var V = class {
|
|
|
482
493
|
t.component = t.replacers.reduce((e, { replacer: t }) => t(e), void 0);
|
|
483
494
|
}
|
|
484
495
|
get(e) {
|
|
485
|
-
if (
|
|
496
|
+
if (R(e)) return e;
|
|
486
497
|
let t = e, n = this._components.get(t);
|
|
487
498
|
if (n?.component) return n.component;
|
|
488
499
|
let r = this._domComponentRegistry.get(e);
|
|
489
500
|
if (r) {
|
|
490
501
|
let e = this._domAdapters.get(t);
|
|
491
|
-
return e || (e =
|
|
502
|
+
return e || (e = V(r), this._domAdapters.set(t, e)), e;
|
|
492
503
|
}
|
|
493
504
|
}
|
|
494
505
|
_resolveComponentInput(e) {
|
|
495
506
|
if (e == null) return null;
|
|
496
|
-
if (typeof e == "number" || typeof e == "boolean" ||
|
|
507
|
+
if (typeof e == "number" || typeof e == "boolean" || L(e)) return e;
|
|
497
508
|
if (typeof e == "string") {
|
|
498
509
|
let t = this.get(e);
|
|
499
|
-
return
|
|
510
|
+
return L(t) ? t : t ? B(t) : e;
|
|
500
511
|
}
|
|
501
|
-
if (
|
|
502
|
-
if (
|
|
512
|
+
if (I(e)) return B(e);
|
|
513
|
+
if (z(e)) {
|
|
503
514
|
let t = this.get(e.type);
|
|
504
|
-
return
|
|
515
|
+
return L(t) ? t : t ? B(t, e.props) : null;
|
|
505
516
|
}
|
|
506
517
|
return null;
|
|
507
518
|
}
|
|
@@ -510,36 +521,36 @@ var V = class {
|
|
|
510
521
|
}
|
|
511
522
|
getReactElement(e) {
|
|
512
523
|
let r = this._resolveComponentInput(e);
|
|
513
|
-
return
|
|
524
|
+
return L(r) ? r : typeof r == "string" || r == null || typeof r == "boolean" || typeof r == "number" ? n(t, null, r) : n(t, null);
|
|
514
525
|
}
|
|
515
|
-
};
|
|
516
|
-
|
|
526
|
+
}, U = () => new H(F(T, P));
|
|
527
|
+
j(U), T.getOrCreateInstance(O, U);
|
|
517
528
|
//#endregion
|
|
518
529
|
//#region src/plugin/registryId.ts
|
|
519
|
-
var
|
|
530
|
+
var W = "PluginRegistry";
|
|
520
531
|
//#endregion
|
|
521
532
|
//#region src/plugin/pluginRegistry.ts
|
|
522
|
-
function
|
|
523
|
-
return e.getOrCreateInstance(
|
|
533
|
+
function G(e = h()) {
|
|
534
|
+
return e.getOrCreateInstance(W, () => new E());
|
|
524
535
|
}
|
|
525
|
-
new D(() =>
|
|
536
|
+
new D(() => G()), v("ELEMENT_INSERT_HTML_PIPELINE"), v("BLOCK_INSERT_HTML_PIPELINE");
|
|
526
537
|
//#endregion
|
|
527
538
|
//#region packages/extensions-core/identifiers/index.ts
|
|
528
|
-
function
|
|
539
|
+
function K(e) {
|
|
529
540
|
return v(e);
|
|
530
541
|
}
|
|
531
|
-
v("extensions.atomsHandlers"),
|
|
542
|
+
v("extensions.atomsHandlers"), K("HANDLE_ATOM_INSERT"), v("HeadlessMode"), v("extensions.sandboxExtensions"), v("MESSAGE_SERVICE"), K("SETTINGS_PANEL_EVENT"), K("MODAL_SHOW_EVENT"), K("MODAL_CLOSE_EVENT"), K("MODAL_UPDATE_EVENT");
|
|
532
543
|
//#endregion
|
|
533
544
|
//#region src/extensions/api/src/index.ts
|
|
534
|
-
function
|
|
545
|
+
function q() {
|
|
535
546
|
return typeof globalThis.crypto?.randomUUID == "function" ? globalThis.crypto.randomUUID() : `component-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
536
547
|
}
|
|
537
|
-
function
|
|
548
|
+
function J(e = q()) {
|
|
538
549
|
return e;
|
|
539
550
|
}
|
|
540
|
-
|
|
551
|
+
F(T);
|
|
541
552
|
//#endregion
|
|
542
553
|
//#region src/extensions/react/src/index.ts
|
|
543
|
-
var
|
|
554
|
+
var Y = M(T);
|
|
544
555
|
//#endregion
|
|
545
|
-
export {
|
|
556
|
+
export { Y as ComponentRegistry, J as createComponentIdentifier };
|
package/package.json
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "types.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"antd": "^6.3
|
|
8
|
+
"antd": "^6.4.3",
|
|
9
9
|
"react": "^19.2.7",
|
|
10
10
|
"react-dom": "^19.2.7",
|
|
11
11
|
"@types/react": "^19.2.17",
|
|
12
12
|
"@types/react-dom": "^19.2.3",
|
|
13
|
-
"@emailmaker/emailmaker": "1.1.85-dev.
|
|
14
|
-
"@emailmaker/extensions-app": "1.1.85-dev.
|
|
13
|
+
"@emailmaker/emailmaker": "1.1.85-dev.11",
|
|
14
|
+
"@emailmaker/extensions-app": "1.1.85-dev.11"
|
|
15
15
|
},
|
|
16
16
|
"name": "@emailmaker/extensions-react",
|
|
17
|
-
"version": "1.1.85-dev.
|
|
17
|
+
"version": "1.1.85-dev.11"
|
|
18
18
|
}
|
package/types.d.ts
CHANGED
|
@@ -322,6 +322,15 @@ interface ISandboxScriptHandle extends IDisposable {
|
|
|
322
322
|
* lifecycle initialization (`afterInit`).
|
|
323
323
|
*/
|
|
324
324
|
readonly ready: Promise<void>;
|
|
325
|
+
/**
|
|
326
|
+
* Fires every time the script becomes ready, including the first time.
|
|
327
|
+
*
|
|
328
|
+
* The canvas document is recreated for every email, so the script is evaluated again and becomes
|
|
329
|
+
* ready again — `ready` is a promise and settles only once, for the first canvas. A host that keeps
|
|
330
|
+
* state in the script subscribes here and sends it again; the editor also replays, on its own, the
|
|
331
|
+
* last message the host sent to the script after `ready`.
|
|
332
|
+
*/
|
|
333
|
+
onReady(listener: () => void): IDisposable;
|
|
325
334
|
}
|
|
326
335
|
interface ISandboxScriptApi {
|
|
327
336
|
/**
|