triggerix-ui-preset-war3 0.0.0

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/dist/index.cjs ADDED
@@ -0,0 +1,351 @@
1
+ 'use strict';
2
+
3
+ const editor = require('@triggerix/editor');
4
+
5
+ function parseTemplate(template, slots, slotValues) {
6
+ const segments = [];
7
+ const regex = /\$\{(\w+)\}/g;
8
+ let lastIndex = 0;
9
+ let match;
10
+ while ((match = regex.exec(template)) !== null) {
11
+ if (match.index > lastIndex) {
12
+ segments.push({ type: "text", content: template.slice(lastIndex, match.index) });
13
+ }
14
+ const key = match[1];
15
+ const slotDef = slots?.[key];
16
+ if (slotDef) {
17
+ const entry = slotValues?.[key];
18
+ segments.push({
19
+ type: "slot",
20
+ key,
21
+ label: slotDef.label,
22
+ tools: slotDef.tools,
23
+ value: entry?.value ?? null
24
+ });
25
+ } else {
26
+ segments.push({ type: "text", content: match[0] });
27
+ }
28
+ lastIndex = regex.lastIndex;
29
+ }
30
+ if (lastIndex < template.length) {
31
+ segments.push({ type: "text", content: template.slice(lastIndex) });
32
+ }
33
+ return segments;
34
+ }
35
+
36
+ function getEventDescriptor(registry, type, slotValues) {
37
+ const def = registry.getEvent(type);
38
+ if (!def)
39
+ return null;
40
+ return {
41
+ type: def.type,
42
+ segments: parseTemplate(def.template, def.slots, slotValues)
43
+ };
44
+ }
45
+ function getActionDescriptor(registry, type, slotValues) {
46
+ const def = registry.getAction(type);
47
+ if (!def)
48
+ return null;
49
+ return {
50
+ type: def.type,
51
+ segments: parseTemplate(def.template, def.slots, slotValues)
52
+ };
53
+ }
54
+ function getConditionDescriptor(registry, type, slotValues) {
55
+ const def = registry.getCondition(type);
56
+ if (!def)
57
+ return null;
58
+ return {
59
+ type: def.type,
60
+ segments: parseTemplate(def.template, def.slots, slotValues)
61
+ };
62
+ }
63
+ function getToolDescriptor(registry, toolName, slotValues) {
64
+ const def = registry.getTool(toolName);
65
+ if (!def)
66
+ return null;
67
+ if (def.type === "leaf") {
68
+ return {
69
+ type: "leaf",
70
+ name: toolName,
71
+ label: def.label,
72
+ input: def.input
73
+ };
74
+ }
75
+ return {
76
+ type: "composite",
77
+ name: toolName,
78
+ label: def.label,
79
+ segments: parseTemplate(def.template, def.slots, slotValues)
80
+ };
81
+ }
82
+ function getSlotToolDescriptors(registry, slotDef) {
83
+ return slotDef.tools.map((name) => getToolDescriptor(registry, name)).filter((d) => d !== null);
84
+ }
85
+
86
+ class War3Registry extends editor.BaseRegistry {
87
+ tools = /* @__PURE__ */ new Map();
88
+ registerTool(name, def) {
89
+ this.tools.set(name, def);
90
+ }
91
+ getTool(name) {
92
+ return this.tools.get(name);
93
+ }
94
+ getTools() {
95
+ return new Map(this.tools);
96
+ }
97
+ }
98
+
99
+ function resolveSlotValue(entry, registry) {
100
+ if (!entry.tool)
101
+ return void 0;
102
+ const toolDef = registry.getTool(entry.tool);
103
+ if (!toolDef)
104
+ return void 0;
105
+ if (toolDef.type === "leaf") {
106
+ return toolDef.resolve(entry.value);
107
+ }
108
+ const resolvedSubSlots = {};
109
+ if (entry.subSlots) {
110
+ for (const [key, subEntry] of Object.entries(entry.subSlots)) {
111
+ resolvedSubSlots[key] = resolveSlotValue(subEntry, registry);
112
+ }
113
+ }
114
+ return toolDef.resolve(resolvedSubSlots);
115
+ }
116
+ function resolveItemParams(slotValues, registry) {
117
+ const params = {};
118
+ let hasParams = false;
119
+ for (const [key, entry] of Object.entries(slotValues)) {
120
+ const resolved = resolveSlotValue(entry, registry);
121
+ if (resolved !== void 0) {
122
+ params[key] = resolved;
123
+ hasParams = true;
124
+ }
125
+ }
126
+ return hasParams ? params : void 0;
127
+ }
128
+ function generateRuleId() {
129
+ const cryptoRef = globalThis.crypto;
130
+ if (cryptoRef?.randomUUID) {
131
+ return cryptoRef.randomUUID();
132
+ }
133
+ return `rule-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
134
+ }
135
+ function toRule(state, registry, ruleId) {
136
+ const eventParams = state.event ? resolveItemParams(state.event.slotValues, registry) : void 0;
137
+ const rule = {
138
+ id: ruleId ?? generateRuleId(),
139
+ event: {
140
+ type: state.event?.type ?? "",
141
+ ...eventParams ? { params: eventParams } : {}
142
+ },
143
+ actions: state.actions.map((action) => {
144
+ const params = resolveItemParams(action.slotValues, registry);
145
+ return {
146
+ type: action.type,
147
+ ...params ? { params } : {}
148
+ };
149
+ })
150
+ };
151
+ if (state.conditions.length > 0) {
152
+ rule.conditions = {
153
+ type: "and",
154
+ conditions: state.conditions.map((cond) => {
155
+ const params = resolveItemParams(cond.slotValues, registry);
156
+ return {
157
+ type: cond.type,
158
+ ...params ? { params } : {}
159
+ };
160
+ })
161
+ };
162
+ }
163
+ return rule;
164
+ }
165
+
166
+ const INITIAL_STATE = {
167
+ event: null,
168
+ conditions: [],
169
+ actions: []
170
+ };
171
+ class War3EditorStateManager extends editor.ObservableState {
172
+ constructor() {
173
+ super({ ...INITIAL_STATE });
174
+ }
175
+ // --- Event ---
176
+ setEvent(type) {
177
+ this.setState((s) => ({ ...s, event: { type, slotValues: {} } }));
178
+ }
179
+ clearEvent() {
180
+ this.setState((s) => ({ ...s, event: null }));
181
+ }
182
+ setEventSlot(key, entry) {
183
+ this.setState((s) => {
184
+ if (!s.event)
185
+ return s;
186
+ return {
187
+ ...s,
188
+ event: {
189
+ ...s.event,
190
+ slotValues: { ...s.event.slotValues, [key]: entry }
191
+ }
192
+ };
193
+ });
194
+ }
195
+ // --- Actions ---
196
+ addAction(type) {
197
+ this.setState((s) => ({
198
+ ...s,
199
+ actions: [...s.actions, { type, slotValues: {} }]
200
+ }));
201
+ }
202
+ removeAction(index) {
203
+ this.setState((s) => ({
204
+ ...s,
205
+ actions: s.actions.filter((_, i) => i !== index)
206
+ }));
207
+ }
208
+ moveAction(from, to) {
209
+ this.setState((s) => {
210
+ const actions = [...s.actions];
211
+ const [moved] = actions.splice(from, 1);
212
+ actions.splice(to, 0, moved);
213
+ return { ...s, actions };
214
+ });
215
+ }
216
+ setActionSlot(actionIndex, key, entry) {
217
+ this.setState((s) => {
218
+ const actions = [...s.actions];
219
+ const action = actions[actionIndex];
220
+ if (!action)
221
+ return s;
222
+ actions[actionIndex] = {
223
+ ...action,
224
+ slotValues: { ...action.slotValues, [key]: entry }
225
+ };
226
+ return { ...s, actions };
227
+ });
228
+ }
229
+ // --- Conditions ---
230
+ addCondition(type) {
231
+ this.setState((s) => ({
232
+ ...s,
233
+ conditions: [...s.conditions, { type, slotValues: {} }]
234
+ }));
235
+ }
236
+ removeCondition(index) {
237
+ this.setState((s) => ({
238
+ ...s,
239
+ conditions: s.conditions.filter((_, i) => i !== index)
240
+ }));
241
+ }
242
+ setConditionSlot(conditionIndex, key, entry) {
243
+ this.setState((s) => {
244
+ const conditions = [...s.conditions];
245
+ const condition = conditions[conditionIndex];
246
+ if (!condition)
247
+ return s;
248
+ conditions[conditionIndex] = {
249
+ ...condition,
250
+ slotValues: { ...condition.slotValues, [key]: entry }
251
+ };
252
+ return { ...s, conditions };
253
+ });
254
+ }
255
+ // --- Reset ---
256
+ reset() {
257
+ this.setState(() => ({ ...INITIAL_STATE }));
258
+ }
259
+ }
260
+
261
+ function createWar3Editor() {
262
+ const registry = new War3Registry();
263
+ const stateManager = new War3EditorStateManager();
264
+ const editor = {
265
+ // --- Editor 接口 ---
266
+ getState: () => stateManager.getState(),
267
+ onChange: (listener) => stateManager.onChange(listener),
268
+ toRule: (ruleId) => toRule(stateManager.getState(), registry, ruleId),
269
+ reset: () => stateManager.reset(),
270
+ dispose: () => stateManager.dispose(),
271
+ // --- 注册 ---
272
+ registerEvent: (def) => registry.registerEvent(def),
273
+ registerAction: (def) => registry.registerAction(def),
274
+ registerCondition: (def) => registry.registerCondition(def),
275
+ registerTool: (name, def) => registry.registerTool(name, def),
276
+ // --- 查询 ---
277
+ getAvailableEvents: () => registry.getEvents(),
278
+ getAvailableActions: () => registry.getActions(),
279
+ getAvailableConditions: () => registry.getConditions(),
280
+ // --- 描述符 ---
281
+ getEventDescriptor: () => {
282
+ const state = stateManager.getState();
283
+ if (!state.event)
284
+ return null;
285
+ return getEventDescriptor(registry, state.event.type, state.event.slotValues);
286
+ },
287
+ getActionDescriptor: (index) => {
288
+ const state = stateManager.getState();
289
+ const action = state.actions[index];
290
+ if (!action)
291
+ return null;
292
+ return getActionDescriptor(registry, action.type, action.slotValues);
293
+ },
294
+ getConditionDescriptor: (index) => {
295
+ const state = stateManager.getState();
296
+ const condition = state.conditions[index];
297
+ if (!condition)
298
+ return null;
299
+ return getConditionDescriptor(registry, condition.type, condition.slotValues);
300
+ },
301
+ getToolDescriptor: (toolName, slotValues) => getToolDescriptor(registry, toolName, slotValues),
302
+ getSlotTools: (slotDef) => getSlotToolDescriptors(registry, slotDef),
303
+ // --- 状态操作 ---
304
+ setEvent: (type) => stateManager.setEvent(type),
305
+ clearEvent: () => stateManager.clearEvent(),
306
+ setEventSlot: (key, entry) => stateManager.setEventSlot(key, entry),
307
+ addAction: (type) => stateManager.addAction(type),
308
+ removeAction: (index) => stateManager.removeAction(index),
309
+ moveAction: (from, to) => stateManager.moveAction(from, to),
310
+ setActionSlot: (actionIndex, key, entry) => stateManager.setActionSlot(actionIndex, key, entry),
311
+ addCondition: (type) => stateManager.addCondition(type),
312
+ removeCondition: (index) => stateManager.removeCondition(index),
313
+ setConditionSlot: (conditionIndex, key, entry) => stateManager.setConditionSlot(conditionIndex, key, entry),
314
+ // --- Preset ---
315
+ applyPreset: (preset) => {
316
+ preset.setup(editor);
317
+ },
318
+ // --- 序列化工具 ---
319
+ resolveSlotValue: (entry) => resolveSlotValue(entry, registry)
320
+ };
321
+ return editor;
322
+ }
323
+
324
+ function defineWar3Preset(options) {
325
+ return {
326
+ name: options.name,
327
+ setup(editor) {
328
+ options.events?.forEach((def) => editor.registerEvent(def));
329
+ options.actions?.forEach((def) => editor.registerAction(def));
330
+ options.conditions?.forEach((def) => editor.registerCondition(def));
331
+ if (options.tools) {
332
+ for (const [name, def] of Object.entries(options.tools)) {
333
+ editor.registerTool(name, def);
334
+ }
335
+ }
336
+ }
337
+ };
338
+ }
339
+
340
+ exports.War3EditorStateManager = War3EditorStateManager;
341
+ exports.War3Registry = War3Registry;
342
+ exports.createWar3Editor = createWar3Editor;
343
+ exports.defineWar3Preset = defineWar3Preset;
344
+ exports.getActionDescriptor = getActionDescriptor;
345
+ exports.getConditionDescriptor = getConditionDescriptor;
346
+ exports.getEventDescriptor = getEventDescriptor;
347
+ exports.getSlotToolDescriptors = getSlotToolDescriptors;
348
+ exports.getToolDescriptor = getToolDescriptor;
349
+ exports.parseTemplate = parseTemplate;
350
+ exports.resolveSlotValue = resolveSlotValue;
351
+ exports.toRule = toRule;
@@ -0,0 +1,182 @@
1
+ import { BaseItemDef, Editor, Preset, BaseRegistry, ObservableState } from '@triggerix/editor';
2
+ export { Preset } from '@triggerix/editor';
3
+ import { Rule } from '@triggerix/core';
4
+
5
+ interface SlotDef {
6
+ label: string;
7
+ tools: string[];
8
+ }
9
+ interface SlotValueEntry {
10
+ tool: string | null;
11
+ value: unknown;
12
+ subSlots?: Record<string, SlotValueEntry>;
13
+ }
14
+ interface LeafToolInput {
15
+ type: 'text' | 'number' | 'select';
16
+ placeholder?: string;
17
+ options?: Array<{
18
+ value: string;
19
+ label: string;
20
+ }>;
21
+ }
22
+ interface LeafToolDef {
23
+ type: 'leaf';
24
+ label: string;
25
+ input: LeafToolInput;
26
+ resolve: (input: unknown) => unknown;
27
+ }
28
+ interface CompositeToolDef {
29
+ type: 'composite';
30
+ label: string;
31
+ template: string;
32
+ slots: Record<string, SlotDef>;
33
+ resolve: (slotValues: Record<string, unknown>) => unknown;
34
+ }
35
+ type ToolDef = LeafToolDef | CompositeToolDef;
36
+ interface War3EventDef extends BaseItemDef {
37
+ template: string;
38
+ slots?: Record<string, SlotDef>;
39
+ }
40
+ interface War3ActionDef extends BaseItemDef {
41
+ template: string;
42
+ slots?: Record<string, SlotDef>;
43
+ }
44
+ interface War3ConditionDef extends BaseItemDef {
45
+ template: string;
46
+ slots?: Record<string, SlotDef>;
47
+ }
48
+ type Segment = {
49
+ type: 'text';
50
+ content: string;
51
+ } | {
52
+ type: 'slot';
53
+ key: string;
54
+ label: string;
55
+ tools: string[];
56
+ value: unknown;
57
+ };
58
+ interface ItemDescriptor {
59
+ type: string;
60
+ segments: Segment[];
61
+ }
62
+ interface LeafToolDescriptor {
63
+ type: 'leaf';
64
+ name: string;
65
+ label: string;
66
+ input: LeafToolInput;
67
+ }
68
+ interface CompositeToolDescriptor {
69
+ type: 'composite';
70
+ name: string;
71
+ label: string;
72
+ segments: Segment[];
73
+ }
74
+ type ToolDescriptor = LeafToolDescriptor | CompositeToolDescriptor;
75
+ interface ItemState {
76
+ type: string;
77
+ slotValues: Record<string, SlotValueEntry>;
78
+ }
79
+ interface War3EditorState {
80
+ event: ItemState | null;
81
+ conditions: ItemState[];
82
+ actions: ItemState[];
83
+ }
84
+ interface War3PresetOptions {
85
+ name: string;
86
+ events?: War3EventDef[];
87
+ actions?: War3ActionDef[];
88
+ conditions?: War3ConditionDef[];
89
+ tools?: Record<string, ToolDef>;
90
+ }
91
+
92
+ interface War3Editor extends Editor<War3EditorState> {
93
+ registerEvent: (def: War3EventDef) => void;
94
+ registerAction: (def: War3ActionDef) => void;
95
+ registerCondition: (def: War3ConditionDef) => void;
96
+ registerTool: (name: string, def: ToolDef) => void;
97
+ getAvailableEvents: () => War3EventDef[];
98
+ getAvailableActions: () => War3ActionDef[];
99
+ getAvailableConditions: () => War3ConditionDef[];
100
+ getEventDescriptor: () => ItemDescriptor | null;
101
+ getActionDescriptor: (actionIndex: number) => ItemDescriptor | null;
102
+ getConditionDescriptor: (conditionIndex: number) => ItemDescriptor | null;
103
+ getToolDescriptor: (toolName: string, slotValues?: Record<string, SlotValueEntry>) => ToolDescriptor | null;
104
+ getSlotTools: (slotDef: SlotDef) => ToolDescriptor[];
105
+ setEvent: (type: string) => void;
106
+ clearEvent: () => void;
107
+ setEventSlot: (key: string, entry: SlotValueEntry) => void;
108
+ addAction: (type: string) => void;
109
+ removeAction: (index: number) => void;
110
+ moveAction: (from: number, to: number) => void;
111
+ setActionSlot: (actionIndex: number, key: string, entry: SlotValueEntry) => void;
112
+ addCondition: (type: string) => void;
113
+ removeCondition: (index: number) => void;
114
+ setConditionSlot: (conditionIndex: number, key: string, entry: SlotValueEntry) => void;
115
+ applyPreset: (preset: Preset<War3Editor>) => void;
116
+ resolveSlotValue: (entry: SlotValueEntry) => unknown;
117
+ }
118
+ declare function createWar3Editor(): War3Editor;
119
+
120
+ /**
121
+ * War3 注册表 - 继承 BaseRegistry,增加 Tool 注册能力
122
+ */
123
+ declare class War3Registry extends BaseRegistry<War3EventDef, War3ActionDef, War3ConditionDef> {
124
+ private tools;
125
+ registerTool(name: string, def: ToolDef): void;
126
+ getTool(name: string): ToolDef | undefined;
127
+ getTools(): Map<string, ToolDef>;
128
+ }
129
+
130
+ declare function getEventDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
131
+ declare function getActionDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
132
+ declare function getConditionDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
133
+ declare function getToolDescriptor(registry: War3Registry, toolName: string, slotValues?: Record<string, SlotValueEntry>): ToolDescriptor | null;
134
+ declare function getSlotToolDescriptors(registry: War3Registry, slotDef: SlotDef): ToolDescriptor[];
135
+
136
+ /**
137
+ * 解析模板字符串为 Segment 数组
138
+ * 模板格式: "普通文本${slotKey}更多文本"
139
+ */
140
+ declare function parseTemplate(template: string, slots?: Record<string, SlotDef>, slotValues?: Record<string, SlotValueEntry>): Segment[];
141
+
142
+ declare function defineWar3Preset(options: War3PresetOptions): Preset<War3Editor>;
143
+
144
+ /**
145
+ * 递归解析单个 slot 值
146
+ */
147
+ declare function resolveSlotValue(entry: SlotValueEntry, registry: War3Registry): unknown;
148
+ /**
149
+ * 将编辑器状态序列化为标准 Rule JSON
150
+ *
151
+ * 输出结构(与 @triggerix/core 兼容):
152
+ * {
153
+ * id, event: { type, params? }, conditions?: { type:'and', conditions:[...] },
154
+ * actions: [{ type, params? }]
155
+ * }
156
+ *
157
+ * 注意:实际 core 中 Event 字段为 source/payload,此处按编辑器约定使用 params 透传,
158
+ * 由 runtime 层负责映射,因此输出统一使用宽松对象后再断言为 Rule。
159
+ */
160
+ declare function toRule(state: War3EditorState, registry: War3Registry, ruleId?: string): Rule;
161
+
162
+ /**
163
+ * War3 编辑器状态管理
164
+ * 继承 ObservableState,提供模板模式特有的状态操作
165
+ */
166
+ declare class War3EditorStateManager extends ObservableState<War3EditorState> {
167
+ constructor();
168
+ setEvent(type: string): void;
169
+ clearEvent(): void;
170
+ setEventSlot(key: string, entry: SlotValueEntry): void;
171
+ addAction(type: string): void;
172
+ removeAction(index: number): void;
173
+ moveAction(from: number, to: number): void;
174
+ setActionSlot(actionIndex: number, key: string, entry: SlotValueEntry): void;
175
+ addCondition(type: string): void;
176
+ removeCondition(index: number): void;
177
+ setConditionSlot(conditionIndex: number, key: string, entry: SlotValueEntry): void;
178
+ reset(): void;
179
+ }
180
+
181
+ export { War3EditorStateManager, War3Registry, createWar3Editor, defineWar3Preset, getActionDescriptor, getConditionDescriptor, getEventDescriptor, getSlotToolDescriptors, getToolDescriptor, parseTemplate, resolveSlotValue, toRule };
182
+ export type { CompositeToolDef, CompositeToolDescriptor, ItemDescriptor, ItemState, LeafToolDef, LeafToolDescriptor, LeafToolInput, Segment, SlotDef, SlotValueEntry, ToolDef, ToolDescriptor, War3ActionDef, War3ConditionDef, War3Editor, War3EditorState, War3EventDef, War3PresetOptions };
@@ -0,0 +1,182 @@
1
+ import { BaseItemDef, Editor, Preset, BaseRegistry, ObservableState } from '@triggerix/editor';
2
+ export { Preset } from '@triggerix/editor';
3
+ import { Rule } from '@triggerix/core';
4
+
5
+ interface SlotDef {
6
+ label: string;
7
+ tools: string[];
8
+ }
9
+ interface SlotValueEntry {
10
+ tool: string | null;
11
+ value: unknown;
12
+ subSlots?: Record<string, SlotValueEntry>;
13
+ }
14
+ interface LeafToolInput {
15
+ type: 'text' | 'number' | 'select';
16
+ placeholder?: string;
17
+ options?: Array<{
18
+ value: string;
19
+ label: string;
20
+ }>;
21
+ }
22
+ interface LeafToolDef {
23
+ type: 'leaf';
24
+ label: string;
25
+ input: LeafToolInput;
26
+ resolve: (input: unknown) => unknown;
27
+ }
28
+ interface CompositeToolDef {
29
+ type: 'composite';
30
+ label: string;
31
+ template: string;
32
+ slots: Record<string, SlotDef>;
33
+ resolve: (slotValues: Record<string, unknown>) => unknown;
34
+ }
35
+ type ToolDef = LeafToolDef | CompositeToolDef;
36
+ interface War3EventDef extends BaseItemDef {
37
+ template: string;
38
+ slots?: Record<string, SlotDef>;
39
+ }
40
+ interface War3ActionDef extends BaseItemDef {
41
+ template: string;
42
+ slots?: Record<string, SlotDef>;
43
+ }
44
+ interface War3ConditionDef extends BaseItemDef {
45
+ template: string;
46
+ slots?: Record<string, SlotDef>;
47
+ }
48
+ type Segment = {
49
+ type: 'text';
50
+ content: string;
51
+ } | {
52
+ type: 'slot';
53
+ key: string;
54
+ label: string;
55
+ tools: string[];
56
+ value: unknown;
57
+ };
58
+ interface ItemDescriptor {
59
+ type: string;
60
+ segments: Segment[];
61
+ }
62
+ interface LeafToolDescriptor {
63
+ type: 'leaf';
64
+ name: string;
65
+ label: string;
66
+ input: LeafToolInput;
67
+ }
68
+ interface CompositeToolDescriptor {
69
+ type: 'composite';
70
+ name: string;
71
+ label: string;
72
+ segments: Segment[];
73
+ }
74
+ type ToolDescriptor = LeafToolDescriptor | CompositeToolDescriptor;
75
+ interface ItemState {
76
+ type: string;
77
+ slotValues: Record<string, SlotValueEntry>;
78
+ }
79
+ interface War3EditorState {
80
+ event: ItemState | null;
81
+ conditions: ItemState[];
82
+ actions: ItemState[];
83
+ }
84
+ interface War3PresetOptions {
85
+ name: string;
86
+ events?: War3EventDef[];
87
+ actions?: War3ActionDef[];
88
+ conditions?: War3ConditionDef[];
89
+ tools?: Record<string, ToolDef>;
90
+ }
91
+
92
+ interface War3Editor extends Editor<War3EditorState> {
93
+ registerEvent: (def: War3EventDef) => void;
94
+ registerAction: (def: War3ActionDef) => void;
95
+ registerCondition: (def: War3ConditionDef) => void;
96
+ registerTool: (name: string, def: ToolDef) => void;
97
+ getAvailableEvents: () => War3EventDef[];
98
+ getAvailableActions: () => War3ActionDef[];
99
+ getAvailableConditions: () => War3ConditionDef[];
100
+ getEventDescriptor: () => ItemDescriptor | null;
101
+ getActionDescriptor: (actionIndex: number) => ItemDescriptor | null;
102
+ getConditionDescriptor: (conditionIndex: number) => ItemDescriptor | null;
103
+ getToolDescriptor: (toolName: string, slotValues?: Record<string, SlotValueEntry>) => ToolDescriptor | null;
104
+ getSlotTools: (slotDef: SlotDef) => ToolDescriptor[];
105
+ setEvent: (type: string) => void;
106
+ clearEvent: () => void;
107
+ setEventSlot: (key: string, entry: SlotValueEntry) => void;
108
+ addAction: (type: string) => void;
109
+ removeAction: (index: number) => void;
110
+ moveAction: (from: number, to: number) => void;
111
+ setActionSlot: (actionIndex: number, key: string, entry: SlotValueEntry) => void;
112
+ addCondition: (type: string) => void;
113
+ removeCondition: (index: number) => void;
114
+ setConditionSlot: (conditionIndex: number, key: string, entry: SlotValueEntry) => void;
115
+ applyPreset: (preset: Preset<War3Editor>) => void;
116
+ resolveSlotValue: (entry: SlotValueEntry) => unknown;
117
+ }
118
+ declare function createWar3Editor(): War3Editor;
119
+
120
+ /**
121
+ * War3 注册表 - 继承 BaseRegistry,增加 Tool 注册能力
122
+ */
123
+ declare class War3Registry extends BaseRegistry<War3EventDef, War3ActionDef, War3ConditionDef> {
124
+ private tools;
125
+ registerTool(name: string, def: ToolDef): void;
126
+ getTool(name: string): ToolDef | undefined;
127
+ getTools(): Map<string, ToolDef>;
128
+ }
129
+
130
+ declare function getEventDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
131
+ declare function getActionDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
132
+ declare function getConditionDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
133
+ declare function getToolDescriptor(registry: War3Registry, toolName: string, slotValues?: Record<string, SlotValueEntry>): ToolDescriptor | null;
134
+ declare function getSlotToolDescriptors(registry: War3Registry, slotDef: SlotDef): ToolDescriptor[];
135
+
136
+ /**
137
+ * 解析模板字符串为 Segment 数组
138
+ * 模板格式: "普通文本${slotKey}更多文本"
139
+ */
140
+ declare function parseTemplate(template: string, slots?: Record<string, SlotDef>, slotValues?: Record<string, SlotValueEntry>): Segment[];
141
+
142
+ declare function defineWar3Preset(options: War3PresetOptions): Preset<War3Editor>;
143
+
144
+ /**
145
+ * 递归解析单个 slot 值
146
+ */
147
+ declare function resolveSlotValue(entry: SlotValueEntry, registry: War3Registry): unknown;
148
+ /**
149
+ * 将编辑器状态序列化为标准 Rule JSON
150
+ *
151
+ * 输出结构(与 @triggerix/core 兼容):
152
+ * {
153
+ * id, event: { type, params? }, conditions?: { type:'and', conditions:[...] },
154
+ * actions: [{ type, params? }]
155
+ * }
156
+ *
157
+ * 注意:实际 core 中 Event 字段为 source/payload,此处按编辑器约定使用 params 透传,
158
+ * 由 runtime 层负责映射,因此输出统一使用宽松对象后再断言为 Rule。
159
+ */
160
+ declare function toRule(state: War3EditorState, registry: War3Registry, ruleId?: string): Rule;
161
+
162
+ /**
163
+ * War3 编辑器状态管理
164
+ * 继承 ObservableState,提供模板模式特有的状态操作
165
+ */
166
+ declare class War3EditorStateManager extends ObservableState<War3EditorState> {
167
+ constructor();
168
+ setEvent(type: string): void;
169
+ clearEvent(): void;
170
+ setEventSlot(key: string, entry: SlotValueEntry): void;
171
+ addAction(type: string): void;
172
+ removeAction(index: number): void;
173
+ moveAction(from: number, to: number): void;
174
+ setActionSlot(actionIndex: number, key: string, entry: SlotValueEntry): void;
175
+ addCondition(type: string): void;
176
+ removeCondition(index: number): void;
177
+ setConditionSlot(conditionIndex: number, key: string, entry: SlotValueEntry): void;
178
+ reset(): void;
179
+ }
180
+
181
+ export { War3EditorStateManager, War3Registry, createWar3Editor, defineWar3Preset, getActionDescriptor, getConditionDescriptor, getEventDescriptor, getSlotToolDescriptors, getToolDescriptor, parseTemplate, resolveSlotValue, toRule };
182
+ export type { CompositeToolDef, CompositeToolDescriptor, ItemDescriptor, ItemState, LeafToolDef, LeafToolDescriptor, LeafToolInput, Segment, SlotDef, SlotValueEntry, ToolDef, ToolDescriptor, War3ActionDef, War3ConditionDef, War3Editor, War3EditorState, War3EventDef, War3PresetOptions };
@@ -0,0 +1,182 @@
1
+ import { BaseItemDef, Editor, Preset, BaseRegistry, ObservableState } from '@triggerix/editor';
2
+ export { Preset } from '@triggerix/editor';
3
+ import { Rule } from '@triggerix/core';
4
+
5
+ interface SlotDef {
6
+ label: string;
7
+ tools: string[];
8
+ }
9
+ interface SlotValueEntry {
10
+ tool: string | null;
11
+ value: unknown;
12
+ subSlots?: Record<string, SlotValueEntry>;
13
+ }
14
+ interface LeafToolInput {
15
+ type: 'text' | 'number' | 'select';
16
+ placeholder?: string;
17
+ options?: Array<{
18
+ value: string;
19
+ label: string;
20
+ }>;
21
+ }
22
+ interface LeafToolDef {
23
+ type: 'leaf';
24
+ label: string;
25
+ input: LeafToolInput;
26
+ resolve: (input: unknown) => unknown;
27
+ }
28
+ interface CompositeToolDef {
29
+ type: 'composite';
30
+ label: string;
31
+ template: string;
32
+ slots: Record<string, SlotDef>;
33
+ resolve: (slotValues: Record<string, unknown>) => unknown;
34
+ }
35
+ type ToolDef = LeafToolDef | CompositeToolDef;
36
+ interface War3EventDef extends BaseItemDef {
37
+ template: string;
38
+ slots?: Record<string, SlotDef>;
39
+ }
40
+ interface War3ActionDef extends BaseItemDef {
41
+ template: string;
42
+ slots?: Record<string, SlotDef>;
43
+ }
44
+ interface War3ConditionDef extends BaseItemDef {
45
+ template: string;
46
+ slots?: Record<string, SlotDef>;
47
+ }
48
+ type Segment = {
49
+ type: 'text';
50
+ content: string;
51
+ } | {
52
+ type: 'slot';
53
+ key: string;
54
+ label: string;
55
+ tools: string[];
56
+ value: unknown;
57
+ };
58
+ interface ItemDescriptor {
59
+ type: string;
60
+ segments: Segment[];
61
+ }
62
+ interface LeafToolDescriptor {
63
+ type: 'leaf';
64
+ name: string;
65
+ label: string;
66
+ input: LeafToolInput;
67
+ }
68
+ interface CompositeToolDescriptor {
69
+ type: 'composite';
70
+ name: string;
71
+ label: string;
72
+ segments: Segment[];
73
+ }
74
+ type ToolDescriptor = LeafToolDescriptor | CompositeToolDescriptor;
75
+ interface ItemState {
76
+ type: string;
77
+ slotValues: Record<string, SlotValueEntry>;
78
+ }
79
+ interface War3EditorState {
80
+ event: ItemState | null;
81
+ conditions: ItemState[];
82
+ actions: ItemState[];
83
+ }
84
+ interface War3PresetOptions {
85
+ name: string;
86
+ events?: War3EventDef[];
87
+ actions?: War3ActionDef[];
88
+ conditions?: War3ConditionDef[];
89
+ tools?: Record<string, ToolDef>;
90
+ }
91
+
92
+ interface War3Editor extends Editor<War3EditorState> {
93
+ registerEvent: (def: War3EventDef) => void;
94
+ registerAction: (def: War3ActionDef) => void;
95
+ registerCondition: (def: War3ConditionDef) => void;
96
+ registerTool: (name: string, def: ToolDef) => void;
97
+ getAvailableEvents: () => War3EventDef[];
98
+ getAvailableActions: () => War3ActionDef[];
99
+ getAvailableConditions: () => War3ConditionDef[];
100
+ getEventDescriptor: () => ItemDescriptor | null;
101
+ getActionDescriptor: (actionIndex: number) => ItemDescriptor | null;
102
+ getConditionDescriptor: (conditionIndex: number) => ItemDescriptor | null;
103
+ getToolDescriptor: (toolName: string, slotValues?: Record<string, SlotValueEntry>) => ToolDescriptor | null;
104
+ getSlotTools: (slotDef: SlotDef) => ToolDescriptor[];
105
+ setEvent: (type: string) => void;
106
+ clearEvent: () => void;
107
+ setEventSlot: (key: string, entry: SlotValueEntry) => void;
108
+ addAction: (type: string) => void;
109
+ removeAction: (index: number) => void;
110
+ moveAction: (from: number, to: number) => void;
111
+ setActionSlot: (actionIndex: number, key: string, entry: SlotValueEntry) => void;
112
+ addCondition: (type: string) => void;
113
+ removeCondition: (index: number) => void;
114
+ setConditionSlot: (conditionIndex: number, key: string, entry: SlotValueEntry) => void;
115
+ applyPreset: (preset: Preset<War3Editor>) => void;
116
+ resolveSlotValue: (entry: SlotValueEntry) => unknown;
117
+ }
118
+ declare function createWar3Editor(): War3Editor;
119
+
120
+ /**
121
+ * War3 注册表 - 继承 BaseRegistry,增加 Tool 注册能力
122
+ */
123
+ declare class War3Registry extends BaseRegistry<War3EventDef, War3ActionDef, War3ConditionDef> {
124
+ private tools;
125
+ registerTool(name: string, def: ToolDef): void;
126
+ getTool(name: string): ToolDef | undefined;
127
+ getTools(): Map<string, ToolDef>;
128
+ }
129
+
130
+ declare function getEventDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
131
+ declare function getActionDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
132
+ declare function getConditionDescriptor(registry: War3Registry, type: string, slotValues?: Record<string, SlotValueEntry>): ItemDescriptor | null;
133
+ declare function getToolDescriptor(registry: War3Registry, toolName: string, slotValues?: Record<string, SlotValueEntry>): ToolDescriptor | null;
134
+ declare function getSlotToolDescriptors(registry: War3Registry, slotDef: SlotDef): ToolDescriptor[];
135
+
136
+ /**
137
+ * 解析模板字符串为 Segment 数组
138
+ * 模板格式: "普通文本${slotKey}更多文本"
139
+ */
140
+ declare function parseTemplate(template: string, slots?: Record<string, SlotDef>, slotValues?: Record<string, SlotValueEntry>): Segment[];
141
+
142
+ declare function defineWar3Preset(options: War3PresetOptions): Preset<War3Editor>;
143
+
144
+ /**
145
+ * 递归解析单个 slot 值
146
+ */
147
+ declare function resolveSlotValue(entry: SlotValueEntry, registry: War3Registry): unknown;
148
+ /**
149
+ * 将编辑器状态序列化为标准 Rule JSON
150
+ *
151
+ * 输出结构(与 @triggerix/core 兼容):
152
+ * {
153
+ * id, event: { type, params? }, conditions?: { type:'and', conditions:[...] },
154
+ * actions: [{ type, params? }]
155
+ * }
156
+ *
157
+ * 注意:实际 core 中 Event 字段为 source/payload,此处按编辑器约定使用 params 透传,
158
+ * 由 runtime 层负责映射,因此输出统一使用宽松对象后再断言为 Rule。
159
+ */
160
+ declare function toRule(state: War3EditorState, registry: War3Registry, ruleId?: string): Rule;
161
+
162
+ /**
163
+ * War3 编辑器状态管理
164
+ * 继承 ObservableState,提供模板模式特有的状态操作
165
+ */
166
+ declare class War3EditorStateManager extends ObservableState<War3EditorState> {
167
+ constructor();
168
+ setEvent(type: string): void;
169
+ clearEvent(): void;
170
+ setEventSlot(key: string, entry: SlotValueEntry): void;
171
+ addAction(type: string): void;
172
+ removeAction(index: number): void;
173
+ moveAction(from: number, to: number): void;
174
+ setActionSlot(actionIndex: number, key: string, entry: SlotValueEntry): void;
175
+ addCondition(type: string): void;
176
+ removeCondition(index: number): void;
177
+ setConditionSlot(conditionIndex: number, key: string, entry: SlotValueEntry): void;
178
+ reset(): void;
179
+ }
180
+
181
+ export { War3EditorStateManager, War3Registry, createWar3Editor, defineWar3Preset, getActionDescriptor, getConditionDescriptor, getEventDescriptor, getSlotToolDescriptors, getToolDescriptor, parseTemplate, resolveSlotValue, toRule };
182
+ export type { CompositeToolDef, CompositeToolDescriptor, ItemDescriptor, ItemState, LeafToolDef, LeafToolDescriptor, LeafToolInput, Segment, SlotDef, SlotValueEntry, ToolDef, ToolDescriptor, War3ActionDef, War3ConditionDef, War3Editor, War3EditorState, War3EventDef, War3PresetOptions };
package/dist/index.mjs ADDED
@@ -0,0 +1,338 @@
1
+ import { BaseRegistry, ObservableState } from '@triggerix/editor';
2
+
3
+ function parseTemplate(template, slots, slotValues) {
4
+ const segments = [];
5
+ const regex = /\$\{(\w+)\}/g;
6
+ let lastIndex = 0;
7
+ let match;
8
+ while ((match = regex.exec(template)) !== null) {
9
+ if (match.index > lastIndex) {
10
+ segments.push({ type: "text", content: template.slice(lastIndex, match.index) });
11
+ }
12
+ const key = match[1];
13
+ const slotDef = slots?.[key];
14
+ if (slotDef) {
15
+ const entry = slotValues?.[key];
16
+ segments.push({
17
+ type: "slot",
18
+ key,
19
+ label: slotDef.label,
20
+ tools: slotDef.tools,
21
+ value: entry?.value ?? null
22
+ });
23
+ } else {
24
+ segments.push({ type: "text", content: match[0] });
25
+ }
26
+ lastIndex = regex.lastIndex;
27
+ }
28
+ if (lastIndex < template.length) {
29
+ segments.push({ type: "text", content: template.slice(lastIndex) });
30
+ }
31
+ return segments;
32
+ }
33
+
34
+ function getEventDescriptor(registry, type, slotValues) {
35
+ const def = registry.getEvent(type);
36
+ if (!def)
37
+ return null;
38
+ return {
39
+ type: def.type,
40
+ segments: parseTemplate(def.template, def.slots, slotValues)
41
+ };
42
+ }
43
+ function getActionDescriptor(registry, type, slotValues) {
44
+ const def = registry.getAction(type);
45
+ if (!def)
46
+ return null;
47
+ return {
48
+ type: def.type,
49
+ segments: parseTemplate(def.template, def.slots, slotValues)
50
+ };
51
+ }
52
+ function getConditionDescriptor(registry, type, slotValues) {
53
+ const def = registry.getCondition(type);
54
+ if (!def)
55
+ return null;
56
+ return {
57
+ type: def.type,
58
+ segments: parseTemplate(def.template, def.slots, slotValues)
59
+ };
60
+ }
61
+ function getToolDescriptor(registry, toolName, slotValues) {
62
+ const def = registry.getTool(toolName);
63
+ if (!def)
64
+ return null;
65
+ if (def.type === "leaf") {
66
+ return {
67
+ type: "leaf",
68
+ name: toolName,
69
+ label: def.label,
70
+ input: def.input
71
+ };
72
+ }
73
+ return {
74
+ type: "composite",
75
+ name: toolName,
76
+ label: def.label,
77
+ segments: parseTemplate(def.template, def.slots, slotValues)
78
+ };
79
+ }
80
+ function getSlotToolDescriptors(registry, slotDef) {
81
+ return slotDef.tools.map((name) => getToolDescriptor(registry, name)).filter((d) => d !== null);
82
+ }
83
+
84
+ class War3Registry extends BaseRegistry {
85
+ tools = /* @__PURE__ */ new Map();
86
+ registerTool(name, def) {
87
+ this.tools.set(name, def);
88
+ }
89
+ getTool(name) {
90
+ return this.tools.get(name);
91
+ }
92
+ getTools() {
93
+ return new Map(this.tools);
94
+ }
95
+ }
96
+
97
+ function resolveSlotValue(entry, registry) {
98
+ if (!entry.tool)
99
+ return void 0;
100
+ const toolDef = registry.getTool(entry.tool);
101
+ if (!toolDef)
102
+ return void 0;
103
+ if (toolDef.type === "leaf") {
104
+ return toolDef.resolve(entry.value);
105
+ }
106
+ const resolvedSubSlots = {};
107
+ if (entry.subSlots) {
108
+ for (const [key, subEntry] of Object.entries(entry.subSlots)) {
109
+ resolvedSubSlots[key] = resolveSlotValue(subEntry, registry);
110
+ }
111
+ }
112
+ return toolDef.resolve(resolvedSubSlots);
113
+ }
114
+ function resolveItemParams(slotValues, registry) {
115
+ const params = {};
116
+ let hasParams = false;
117
+ for (const [key, entry] of Object.entries(slotValues)) {
118
+ const resolved = resolveSlotValue(entry, registry);
119
+ if (resolved !== void 0) {
120
+ params[key] = resolved;
121
+ hasParams = true;
122
+ }
123
+ }
124
+ return hasParams ? params : void 0;
125
+ }
126
+ function generateRuleId() {
127
+ const cryptoRef = globalThis.crypto;
128
+ if (cryptoRef?.randomUUID) {
129
+ return cryptoRef.randomUUID();
130
+ }
131
+ return `rule-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
132
+ }
133
+ function toRule(state, registry, ruleId) {
134
+ const eventParams = state.event ? resolveItemParams(state.event.slotValues, registry) : void 0;
135
+ const rule = {
136
+ id: ruleId ?? generateRuleId(),
137
+ event: {
138
+ type: state.event?.type ?? "",
139
+ ...eventParams ? { params: eventParams } : {}
140
+ },
141
+ actions: state.actions.map((action) => {
142
+ const params = resolveItemParams(action.slotValues, registry);
143
+ return {
144
+ type: action.type,
145
+ ...params ? { params } : {}
146
+ };
147
+ })
148
+ };
149
+ if (state.conditions.length > 0) {
150
+ rule.conditions = {
151
+ type: "and",
152
+ conditions: state.conditions.map((cond) => {
153
+ const params = resolveItemParams(cond.slotValues, registry);
154
+ return {
155
+ type: cond.type,
156
+ ...params ? { params } : {}
157
+ };
158
+ })
159
+ };
160
+ }
161
+ return rule;
162
+ }
163
+
164
+ const INITIAL_STATE = {
165
+ event: null,
166
+ conditions: [],
167
+ actions: []
168
+ };
169
+ class War3EditorStateManager extends ObservableState {
170
+ constructor() {
171
+ super({ ...INITIAL_STATE });
172
+ }
173
+ // --- Event ---
174
+ setEvent(type) {
175
+ this.setState((s) => ({ ...s, event: { type, slotValues: {} } }));
176
+ }
177
+ clearEvent() {
178
+ this.setState((s) => ({ ...s, event: null }));
179
+ }
180
+ setEventSlot(key, entry) {
181
+ this.setState((s) => {
182
+ if (!s.event)
183
+ return s;
184
+ return {
185
+ ...s,
186
+ event: {
187
+ ...s.event,
188
+ slotValues: { ...s.event.slotValues, [key]: entry }
189
+ }
190
+ };
191
+ });
192
+ }
193
+ // --- Actions ---
194
+ addAction(type) {
195
+ this.setState((s) => ({
196
+ ...s,
197
+ actions: [...s.actions, { type, slotValues: {} }]
198
+ }));
199
+ }
200
+ removeAction(index) {
201
+ this.setState((s) => ({
202
+ ...s,
203
+ actions: s.actions.filter((_, i) => i !== index)
204
+ }));
205
+ }
206
+ moveAction(from, to) {
207
+ this.setState((s) => {
208
+ const actions = [...s.actions];
209
+ const [moved] = actions.splice(from, 1);
210
+ actions.splice(to, 0, moved);
211
+ return { ...s, actions };
212
+ });
213
+ }
214
+ setActionSlot(actionIndex, key, entry) {
215
+ this.setState((s) => {
216
+ const actions = [...s.actions];
217
+ const action = actions[actionIndex];
218
+ if (!action)
219
+ return s;
220
+ actions[actionIndex] = {
221
+ ...action,
222
+ slotValues: { ...action.slotValues, [key]: entry }
223
+ };
224
+ return { ...s, actions };
225
+ });
226
+ }
227
+ // --- Conditions ---
228
+ addCondition(type) {
229
+ this.setState((s) => ({
230
+ ...s,
231
+ conditions: [...s.conditions, { type, slotValues: {} }]
232
+ }));
233
+ }
234
+ removeCondition(index) {
235
+ this.setState((s) => ({
236
+ ...s,
237
+ conditions: s.conditions.filter((_, i) => i !== index)
238
+ }));
239
+ }
240
+ setConditionSlot(conditionIndex, key, entry) {
241
+ this.setState((s) => {
242
+ const conditions = [...s.conditions];
243
+ const condition = conditions[conditionIndex];
244
+ if (!condition)
245
+ return s;
246
+ conditions[conditionIndex] = {
247
+ ...condition,
248
+ slotValues: { ...condition.slotValues, [key]: entry }
249
+ };
250
+ return { ...s, conditions };
251
+ });
252
+ }
253
+ // --- Reset ---
254
+ reset() {
255
+ this.setState(() => ({ ...INITIAL_STATE }));
256
+ }
257
+ }
258
+
259
+ function createWar3Editor() {
260
+ const registry = new War3Registry();
261
+ const stateManager = new War3EditorStateManager();
262
+ const editor = {
263
+ // --- Editor 接口 ---
264
+ getState: () => stateManager.getState(),
265
+ onChange: (listener) => stateManager.onChange(listener),
266
+ toRule: (ruleId) => toRule(stateManager.getState(), registry, ruleId),
267
+ reset: () => stateManager.reset(),
268
+ dispose: () => stateManager.dispose(),
269
+ // --- 注册 ---
270
+ registerEvent: (def) => registry.registerEvent(def),
271
+ registerAction: (def) => registry.registerAction(def),
272
+ registerCondition: (def) => registry.registerCondition(def),
273
+ registerTool: (name, def) => registry.registerTool(name, def),
274
+ // --- 查询 ---
275
+ getAvailableEvents: () => registry.getEvents(),
276
+ getAvailableActions: () => registry.getActions(),
277
+ getAvailableConditions: () => registry.getConditions(),
278
+ // --- 描述符 ---
279
+ getEventDescriptor: () => {
280
+ const state = stateManager.getState();
281
+ if (!state.event)
282
+ return null;
283
+ return getEventDescriptor(registry, state.event.type, state.event.slotValues);
284
+ },
285
+ getActionDescriptor: (index) => {
286
+ const state = stateManager.getState();
287
+ const action = state.actions[index];
288
+ if (!action)
289
+ return null;
290
+ return getActionDescriptor(registry, action.type, action.slotValues);
291
+ },
292
+ getConditionDescriptor: (index) => {
293
+ const state = stateManager.getState();
294
+ const condition = state.conditions[index];
295
+ if (!condition)
296
+ return null;
297
+ return getConditionDescriptor(registry, condition.type, condition.slotValues);
298
+ },
299
+ getToolDescriptor: (toolName, slotValues) => getToolDescriptor(registry, toolName, slotValues),
300
+ getSlotTools: (slotDef) => getSlotToolDescriptors(registry, slotDef),
301
+ // --- 状态操作 ---
302
+ setEvent: (type) => stateManager.setEvent(type),
303
+ clearEvent: () => stateManager.clearEvent(),
304
+ setEventSlot: (key, entry) => stateManager.setEventSlot(key, entry),
305
+ addAction: (type) => stateManager.addAction(type),
306
+ removeAction: (index) => stateManager.removeAction(index),
307
+ moveAction: (from, to) => stateManager.moveAction(from, to),
308
+ setActionSlot: (actionIndex, key, entry) => stateManager.setActionSlot(actionIndex, key, entry),
309
+ addCondition: (type) => stateManager.addCondition(type),
310
+ removeCondition: (index) => stateManager.removeCondition(index),
311
+ setConditionSlot: (conditionIndex, key, entry) => stateManager.setConditionSlot(conditionIndex, key, entry),
312
+ // --- Preset ---
313
+ applyPreset: (preset) => {
314
+ preset.setup(editor);
315
+ },
316
+ // --- 序列化工具 ---
317
+ resolveSlotValue: (entry) => resolveSlotValue(entry, registry)
318
+ };
319
+ return editor;
320
+ }
321
+
322
+ function defineWar3Preset(options) {
323
+ return {
324
+ name: options.name,
325
+ setup(editor) {
326
+ options.events?.forEach((def) => editor.registerEvent(def));
327
+ options.actions?.forEach((def) => editor.registerAction(def));
328
+ options.conditions?.forEach((def) => editor.registerCondition(def));
329
+ if (options.tools) {
330
+ for (const [name, def] of Object.entries(options.tools)) {
331
+ editor.registerTool(name, def);
332
+ }
333
+ }
334
+ }
335
+ };
336
+ }
337
+
338
+ export { War3EditorStateManager, War3Registry, createWar3Editor, defineWar3Preset, getActionDescriptor, getConditionDescriptor, getEventDescriptor, getSlotToolDescriptors, getToolDescriptor, parseTemplate, resolveSlotValue, toRule };
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "triggerix-ui-preset-war3",
3
+ "version": "0.0.0",
4
+ "description": "War3-style template editor preset for Triggerix",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "dependencies": {
20
+ "@triggerix/core": "^0.0.3",
21
+ "@triggerix/editor": "^0.0.3"
22
+ },
23
+ "devDependencies": {
24
+ "typescript": "^6.0.3",
25
+ "unbuild": "^3.6.1"
26
+ },
27
+ "scripts": {
28
+ "build": "unbuild",
29
+ "dev": "unbuild --stub",
30
+ "typecheck": "tsc --noEmit"
31
+ }
32
+ }