@monbolc/lowcode-editor-core 2.1.5 → 2.1.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 monbo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/es/di.js ADDED
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @monbolc/lowcode-editor-core — DIContainer
3
+ *
4
+ * A tiny, type-friendly dependency injection container. Each entry is
5
+ * keyed by a constructor / factory function. Resolve is async because
6
+ * a factory may itself call `get(...)` to satisfy its own deps.
7
+ *
8
+ * Why a custom container instead of InversifyJS / tsyringe?
9
+ * - The editor's DI surface is small (a few dozen services at most).
10
+ * - We want zero runtime deps and a TS-friendly API.
11
+ * - We do not need scoping / child containers / aspect interception.
12
+ */
13
+ import { uid } from '@monbolc/lowcode-utils';
14
+ export class DIContainer {
15
+ constructor() {
16
+ this.services = new Map();
17
+ this.id = uid('di');
18
+ }
19
+ /**
20
+ * Register a service. The `ctor` is the lookup key — call `get(ctor)`
21
+ * to retrieve the instance. The `factory` builds the instance.
22
+ */
23
+ register(ctor, factory, scope = 'singleton') {
24
+ if (this.services.has(ctor)) {
25
+ throw new Error(`[DIContainer:${this.id}] service already registered for this ctor`);
26
+ }
27
+ this.services.set(ctor, { factory, scope });
28
+ }
29
+ /**
30
+ * Resolve a service. If a singleton was already built, returns the
31
+ * cached instance; otherwise calls the factory and caches.
32
+ */
33
+ async get(ctor) {
34
+ const reg = this.services.get(ctor);
35
+ if (!reg) {
36
+ throw new Error(`[DIContainer:${this.id}] no service registered for this ctor`);
37
+ }
38
+ if (reg.instance !== undefined && reg.scope === 'singleton') {
39
+ return reg.instance;
40
+ }
41
+ const instance = await reg.factory(this);
42
+ if (reg.scope === 'singleton')
43
+ reg.instance = instance;
44
+ return instance;
45
+ }
46
+ /**
47
+ * Synchronous lookup. Returns undefined if the service is not yet built
48
+ * (or not registered at all). Useful for non-async consumers.
49
+ */
50
+ peek(ctor) {
51
+ const reg = this.services.get(ctor);
52
+ return reg?.instance;
53
+ }
54
+ /** True if a factory is registered for this key. */
55
+ has(ctor) {
56
+ return this.services.has(ctor);
57
+ }
58
+ /** Drop all registrations and cached instances. */
59
+ clear() {
60
+ this.services.clear();
61
+ }
62
+ /** Number of registered services. */
63
+ size() {
64
+ return this.services.size;
65
+ }
66
+ }
67
+ //# sourceMappingURL=di.js.map
package/es/di.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"di.js","sourceRoot":"","sources":["../src/di.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAa7C,MAAM,OAAO,WAAW;IAAxB;QACmB,aAAQ,GAAG,IAAI,GAAG,EAA2C,CAAC;QAC9D,OAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IAqDlC,CAAC;IAnDC;;;OAGG;IACH,QAAQ,CAAI,IAAgB,EAAE,OAAmB,EAAE,QAAmC,WAAW;QAC/F,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAwB,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC,EAAE,4CAA4C,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAwB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAG,CAAI,IAAgB;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAwB,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC,EAAE,uCAAuC,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC5D,OAAO,GAAG,CAAC,QAAa,CAAC;QAC3B,CAAC;QACD,MAAM,QAAQ,GAAG,MAAO,GAAG,CAAC,OAAsB,CAAC,IAAI,CAAC,CAAC;QACzD,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW;YAAE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACvD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,IAAI,CAAI,IAAgB;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAwB,CAAC,CAAC;QACxD,OAAO,GAAG,EAAE,QAAyB,CAAC;IACxC,CAAC;IAED,oDAAoD;IACpD,GAAG,CAAI,IAAgB;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAwB,CAAC,CAAC;IACrD,CAAC;IAED,mDAAmD;IACnD,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,qCAAqC;IACrC,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;CACF"}
package/es/editor.js ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @monbolc/lowcode-editor-core — Editor (composition root)
3
+ *
4
+ * The `Editor` class wires DI, i18n, the plugin manager, and the command
5
+ * manager into a single object. Subclasses (e.g. a future
6
+ * `BrowserEditor`) can override `init` to also mount UI.
7
+ */
8
+ import { Emitter } from '@monbolc/lowcode-utils';
9
+ import { CommandManager } from '@monbolc/lowcode-plugin-command';
10
+ import { DIContainer } from './di.js';
11
+ import { I18nImpl } from './i18n.js';
12
+ import { PluginManager } from './plugin.js';
13
+ export class Editor {
14
+ constructor(options = {}) {
15
+ this.events = new Emitter();
16
+ this.i18n = new I18nImpl();
17
+ this.di = new DIContainer();
18
+ this.commands = new CommandManager();
19
+ this._ready = false;
20
+ this.id = `editor_${Math.random().toString(36).slice(2, 10)}`;
21
+ this.plugins = new PluginManager(this.events);
22
+ this.initialPlugins = options.plugins ?? [];
23
+ if (options.locale)
24
+ this.i18n.setLocale(options.locale);
25
+ }
26
+ get ready() {
27
+ return this._ready;
28
+ }
29
+ async init(extraPlugins = []) {
30
+ if (this._ready) {
31
+ throw new Error(`[Editor:${this.id}] init() called twice`);
32
+ }
33
+ this.events.emit('phase', { name: 'init' });
34
+ for (const p of this.initialPlugins)
35
+ this.plugins.register(p);
36
+ for (const p of extraPlugins)
37
+ this.plugins.register(p);
38
+ this.events.emit('phase', { name: 'register' });
39
+ const ctx = {
40
+ editor: this,
41
+ i18n: this.i18n,
42
+ di: this.di,
43
+ events: this.events,
44
+ plugins: this.plugins,
45
+ commands: this.commands,
46
+ };
47
+ await this.plugins.initAll(ctx);
48
+ this._ready = true;
49
+ this.events.emit('phase', { name: 'ready' });
50
+ }
51
+ async destroy() {
52
+ if (!this._ready)
53
+ return;
54
+ this.events.emit('phase', { name: 'destroy' });
55
+ const ctx = {
56
+ editor: this,
57
+ i18n: this.i18n,
58
+ di: this.di,
59
+ events: this.events,
60
+ plugins: this.plugins,
61
+ commands: this.commands,
62
+ };
63
+ await this.plugins.destroyAll(ctx);
64
+ this.di.clear();
65
+ this.commands.clearHistory();
66
+ this._ready = false;
67
+ }
68
+ async get(ctor) {
69
+ return this.di.get(ctor);
70
+ }
71
+ peek(ctor) {
72
+ return this.di.peek(ctor);
73
+ }
74
+ }
75
+ //# sourceMappingURL=editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.js","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"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"}
package/es/i18n.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @monbolc/lowcode-editor-core — I18n
3
+ *
4
+ * Tiny internationalization helper. Plugins call `i18n.register({...})`
5
+ * to add strings; consumers call `i18n.t('pluginName.someKey')` to get
6
+ * a string in the active locale (or the default if missing).
7
+ *
8
+ * Shape: { default: string, byLocale?: Record<locale, string> }
9
+ * Example:
10
+ * i18n.register({ 'designer.duplicate': { default: 'Duplicate', byLocale: { zh_CN: '复制' } } });
11
+ * i18n.t('designer.duplicate'); // 'Duplicate' (or '复制' if locale='zh_CN')
12
+ */
13
+ export class I18nImpl {
14
+ constructor() {
15
+ this.messages = new Map();
16
+ this._locale = '';
17
+ }
18
+ get locale() {
19
+ return this._locale;
20
+ }
21
+ setLocale(locale) {
22
+ this._locale = locale ?? '';
23
+ }
24
+ register(messages) {
25
+ for (const [id, value] of Object.entries(messages)) {
26
+ // Allow shorthand: `'foo': 'Hello'` instead of `{ default: 'Hello' }`.
27
+ const normalized = typeof value === 'string' ? { default: value } : value;
28
+ this.messages.set(id, normalized);
29
+ }
30
+ }
31
+ t(id, locale, fallback) {
32
+ const msg = this.messages.get(id);
33
+ if (!msg) {
34
+ if (fallback !== undefined)
35
+ return fallback;
36
+ // Last resort: return the id itself so missing translations are visible.
37
+ return id;
38
+ }
39
+ const activeLocale = locale ?? this._locale;
40
+ if (activeLocale && msg.byLocale?.[activeLocale] !== undefined) {
41
+ return msg.byLocale[activeLocale];
42
+ }
43
+ return msg.default;
44
+ }
45
+ /** Number of registered message ids. */
46
+ size() {
47
+ return this.messages.size;
48
+ }
49
+ }
50
+ //# sourceMappingURL=i18n.js.map
package/es/i18n.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,OAAO,QAAQ;IAArB;QACmB,aAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;QACnD,YAAO,GAAW,EAAE,CAAC;IAqC/B,CAAC;IAnCC,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,QAAQ,CAAC,QAA8C;QACrD,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnD,uEAAuE;YACvE,MAAM,UAAU,GACd,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YACzD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,CAAC,CAAC,EAAU,EAAE,MAAe,EAAE,QAAiB;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,QAAQ,CAAC;YAC5C,yEAAyE;YACzE,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;QAC5C,IAAI,YAAY,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC;YAC/D,OAAO,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IAED,wCAAwC;IACxC,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;CACF"}
package/es/index.js ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @monbolc/lowcode-editor-core — barrel export
3
+ *
4
+ * SapuLowcodeEngine core API surface (L2). DI + i18n + plugin registry +
5
+ * command manager + event bus. No React, no mobx — that's L3+.
6
+ */
7
+ // --- DI ---
8
+ export { DIContainer } from './di.js';
9
+ // --- i18n ---
10
+ export { I18nImpl } from './i18n.js';
11
+ // --- plugin manager ---
12
+ export { PluginManager } from './plugin.js';
13
+ // --- editor (composition root) ---
14
+ export { Editor } from './editor.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,aAAa;AACb,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAGnC,eAAe;AACf,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,yBAAyB;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,oCAAoC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
package/es/plugin.js ADDED
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @monbolc/lowcode-editor-core — PluginManager
3
+ *
4
+ * Validates plugin names, topologically sorts by `dependencies`,
5
+ * and exposes registration APIs.
6
+ */
7
+ export class PluginManager {
8
+ constructor(eventBus) {
9
+ this.plugins = new Map();
10
+ this.sortedCache = null;
11
+ this.eventBus = eventBus;
12
+ }
13
+ register(plugin) {
14
+ if (this.plugins.has(plugin.name)) {
15
+ throw new Error(`[PluginManager] plugin "${plugin.name}" is already registered`);
16
+ }
17
+ if (!/^[A-Za-z0-9_@./\-]+$/.test(plugin.name)) {
18
+ throw new Error(`[PluginManager] plugin name "${plugin.name}" contains invalid characters`);
19
+ }
20
+ this.plugins.set(plugin.name, plugin);
21
+ this.sortedCache = null; // invalidate sort cache
22
+ this.eventBus.emit('pluginRegistered', { name: plugin.name });
23
+ }
24
+ unregister(name) {
25
+ const existed = this.plugins.delete(name);
26
+ if (existed)
27
+ this.sortedCache = null;
28
+ return existed;
29
+ }
30
+ has(name) {
31
+ return this.plugins.has(name);
32
+ }
33
+ get(name) {
34
+ return this.plugins.get(name);
35
+ }
36
+ list() {
37
+ return Array.from(this.plugins.values());
38
+ }
39
+ /**
40
+ * Return plugins in dependency order: deps first, then dependents.
41
+ * Throws on circular or missing deps.
42
+ */
43
+ sortedByDeps() {
44
+ if (this.sortedCache)
45
+ return this.sortedCache;
46
+ const result = [];
47
+ const visited = new Set();
48
+ const visiting = new Set();
49
+ const visit = (plugin) => {
50
+ if (visited.has(plugin.name))
51
+ return;
52
+ if (visiting.has(plugin.name)) {
53
+ throw new Error(`[PluginManager] circular dependency at "${plugin.name}"`);
54
+ }
55
+ visiting.add(plugin.name);
56
+ for (const dep of plugin.dependencies ?? []) {
57
+ const sub = this.plugins.get(dep);
58
+ if (!sub) {
59
+ throw new Error(`[PluginManager] plugin "${plugin.name}" depends on missing plugin "${dep}"`);
60
+ }
61
+ visit(sub);
62
+ }
63
+ visiting.delete(plugin.name);
64
+ visited.add(plugin.name);
65
+ result.push(plugin);
66
+ };
67
+ for (const plugin of this.plugins.values())
68
+ visit(plugin);
69
+ this.sortedCache = result;
70
+ return result;
71
+ }
72
+ /**
73
+ * Run init() for each plugin in dep order. If any throws, the error
74
+ * is rethrown but earlier plugins remain initialized.
75
+ */
76
+ async initAll(ctx) {
77
+ for (const plugin of this.sortedByDeps()) {
78
+ if (!plugin.init)
79
+ continue;
80
+ try {
81
+ await plugin.init(ctx);
82
+ }
83
+ catch (err) {
84
+ this.eventBus.emit('error', { plugin: plugin.name, error: err });
85
+ throw err;
86
+ }
87
+ }
88
+ }
89
+ /**
90
+ * Run destroy() in reverse init order. Errors are swallowed and emitted
91
+ * so one bad plugin doesn't prevent others from cleaning up.
92
+ */
93
+ async destroyAll(ctx) {
94
+ const plugins = [...this.sortedByDeps()].reverse();
95
+ for (const plugin of plugins) {
96
+ if (!plugin.destroy)
97
+ continue;
98
+ try {
99
+ await plugin.destroy(ctx);
100
+ }
101
+ catch (err) {
102
+ this.eventBus.emit('error', { plugin: plugin.name, error: err });
103
+ }
104
+ }
105
+ }
106
+ }
107
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
package/es/types.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @monbolc/lowcode-editor-core — public types
3
+ *
4
+ * Editor public API: plugin context, editor composition root, and the
5
+ * service-registration shapes that plugins use to wire themselves in.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monbolc/lowcode-editor-core",
3
- "version": "2.1.5",
3
+ "version": "2.1.6",
4
4
  "description": "Core API: DI container + i18n + plugin registry for SapuLowcodeEngine (L2)",
5
5
  "license": "MIT",
6
6
  "main": "lib/index.js",
@@ -15,12 +15,14 @@
15
15
  },
16
16
  "files": [
17
17
  "lib",
18
- "es"
18
+ "es",
19
+ "LICENSE"
19
20
  ],
20
21
  "scripts": {
21
- "build": "tsc -p tsconfig.json",
22
+ "build": "npm run build:cjs && npm run build:es",
22
23
  "build:es": "tsc -p tsconfig.esm.json && node ../../scripts/add-js-extensions.mjs es",
23
- "clean": "rimraf lib es"
24
+ "clean": "rimraf lib es",
25
+ "build:cjs": "tsc -p tsconfig.json"
24
26
  },
25
27
  "dependencies": {
26
28
  "@monbolc/lowcode-plugin-command": "^2.1.5",
@@ -48,5 +50,5 @@
48
50
  "i18n",
49
51
  "plugin"
50
52
  ],
51
- "gitHead": "b23c688931a9afae9f3fc05308d587a2c053f983"
53
+ "gitHead": "11e98f766bf66eabdae929d0103f798654f13dfb"
52
54
  }