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 +351 -0
- package/dist/index.d.cts +182 -0
- package/dist/index.d.mts +182 -0
- package/dist/index.d.ts +182 -0
- package/dist/index.mjs +338 -0
- package/package.json +32 -0
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;
|
package/dist/index.d.cts
ADDED
|
@@ -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.d.mts
ADDED
|
@@ -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.d.ts
ADDED
|
@@ -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
|
+
}
|