@tmagic/editor 1.8.0-beta.21 → 1.8.0-beta.23
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/es/components/CodeBlockEditor.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/es/components/Resizer.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +6 -1
- package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +35 -3
- package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +26 -5
- package/dist/es/index.js +2 -2
- package/dist/es/initService.js +2 -1
- package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +23 -12
- package/dist/es/layouts/sidebar/ComponentListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceConfigPanel.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/es/services/codeBlock.js +4 -2
- package/dist/es/services/editor.js +12 -8
- package/dist/es/utils/dep/collect-worker-client.js +67 -27
- package/dist/es/utils/dep/worker.js +1 -1
- package/dist/es/utils/type-match-rules.js +24 -36
- package/dist/tmagic-editor.umd.cjs +413 -306
- package/package.json +12 -12
- package/src/fields/StyleSetter/components/Box.vue +1 -1
- package/src/fields/StyleSetter/components/Position.vue +1 -1
- package/src/fields/StyleSetter/pro/Background.vue +7 -0
- package/src/fields/StyleSetter/pro/Font.vue +57 -0
- package/src/fields/StyleSetter/pro/Position.vue +31 -0
- package/src/layouts/props-panel/PropsPanel.vue +30 -16
- package/src/layouts/sidebar/ComponentListPanel.vue +5 -1
- package/src/layouts/sidebar/layer/LayerPanel.vue +1 -1
- package/src/services/editor.ts +27 -8
- package/src/utils/dep/collect-worker-client.ts +97 -31
- package/src/utils/type-match-rules.ts +41 -34
- package/types/index.d.ts +106 -153
|
@@ -119,7 +119,8 @@ var CodeBlockEditor_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
119
119
|
const closedHandler = () => {
|
|
120
120
|
changedValue.value = void 0;
|
|
121
121
|
};
|
|
122
|
-
const
|
|
122
|
+
const parentFloating = inject("parentFloating", ref(null));
|
|
123
|
+
const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(uiService, parentFloating);
|
|
123
124
|
const frameworkWidth = computed(() => uiService.get("frameworkRect")?.width || 0);
|
|
124
125
|
watch(boxVisible, (visible) => {
|
|
125
126
|
nextTick(() => {
|
|
@@ -7,7 +7,8 @@ var Resizer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
|
|
|
7
7
|
emits: ["change"],
|
|
8
8
|
setup(__props, { emit: __emit }) {
|
|
9
9
|
const emit = __emit;
|
|
10
|
-
const
|
|
10
|
+
const targetEl = useTemplateRef("target");
|
|
11
|
+
const { isDragging } = useGetSo(targetEl, emit);
|
|
11
12
|
return (_ctx, _cache) => {
|
|
12
13
|
return openBlock(), createElementBlock("span", {
|
|
13
14
|
ref: "target",
|
|
@@ -30,7 +30,9 @@ var CondOpSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
30
30
|
const optionComponent = getDesignConfig("components")?.option;
|
|
31
31
|
const options = computed(() => {
|
|
32
32
|
const [id, ...fieldNames] = [...props.config.parentFields || [], ...props.model.field];
|
|
33
|
-
|
|
33
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
34
|
+
const type = getFieldType(ds, fieldNames);
|
|
35
|
+
return getCondOpOptionsByFieldType(type);
|
|
34
36
|
});
|
|
35
37
|
const fieldChangeHandler = (v) => {
|
|
36
38
|
emit("change", v);
|
|
@@ -315,7 +315,8 @@ var DataSourceFields_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
315
315
|
const addDialogVisible = useModel(__props, "visible");
|
|
316
316
|
const addFromJsonDialogVisible = useModel(__props, "visible1");
|
|
317
317
|
const { height: editorHeight } = useEditorContentHeight();
|
|
318
|
-
const
|
|
318
|
+
const parentFloating = inject("parentFloating", ref(null));
|
|
319
|
+
const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(uiService, parentFloating);
|
|
319
320
|
const frameworkWidth = computed(() => uiService.get("frameworkRect")?.width || 0);
|
|
320
321
|
/**
|
|
321
322
|
* 由 DataSourceConfigPanel 注入:打开数据源详情后需要直接打开的字段路径(字段名数组)。
|
|
@@ -128,7 +128,8 @@ var DataSourceInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
128
128
|
*/
|
|
129
129
|
const fieldQuerySearch = (queryString, leftAngleIndex, dotIndex, cb) => {
|
|
130
130
|
let result = [];
|
|
131
|
-
const
|
|
131
|
+
const dsKey = queryString.substring(leftAngleIndex + 1, dotIndex);
|
|
132
|
+
const keys = getKeysArray(dsKey);
|
|
132
133
|
const dsId = keys.shift();
|
|
133
134
|
const ds = dataSources.value.find((ds) => ds.id === dsId);
|
|
134
135
|
if (!ds) {
|
|
@@ -215,7 +215,8 @@ var DataSourceMocks_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
215
215
|
};
|
|
216
216
|
const addDialogVisible = useModel(__props, "visible");
|
|
217
217
|
const { height: editorHeight } = useEditorContentHeight();
|
|
218
|
-
const
|
|
218
|
+
const parentFloating = inject("parentFloating", ref(null));
|
|
219
|
+
const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(uiService, parentFloating);
|
|
219
220
|
const frameworkWidth = computed(() => uiService.get("frameworkRect")?.width || 0);
|
|
220
221
|
return (_ctx, _cache) => {
|
|
221
222
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
@@ -33,7 +33,8 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
33
33
|
const parentFields = computed(() => filterFunction(mForm, props.config.parentFields, props) || []);
|
|
34
34
|
const fieldOnChange = (_formState, v, { model }) => {
|
|
35
35
|
const [id, ...fieldNames] = [...parentFields.value, ...v];
|
|
36
|
-
const
|
|
36
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
37
|
+
const type = getFieldType(ds, fieldNames);
|
|
37
38
|
if (type === "number") model.value = Number(model.value);
|
|
38
39
|
else if (type === "boolean") model.value = Boolean(model.value);
|
|
39
40
|
else if (type === "null") model.value = null;
|
|
@@ -131,7 +132,8 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
131
132
|
name: "value",
|
|
132
133
|
type: (_mForm, { model }) => {
|
|
133
134
|
const [id, ...fieldNames] = [...parentFields.value, ...model.field];
|
|
134
|
-
const
|
|
135
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
136
|
+
const type = getFieldType(ds, fieldNames);
|
|
135
137
|
if (type === "number") return "number";
|
|
136
138
|
if (type === "boolean") return "select";
|
|
137
139
|
if (type === "null") return "display";
|
|
@@ -7,7 +7,7 @@ var _hoisted_2 = {
|
|
|
7
7
|
};
|
|
8
8
|
var _hoisted_3 = { class: "next-input" };
|
|
9
9
|
var _hoisted_4 = [
|
|
10
|
-
"
|
|
10
|
+
"value",
|
|
11
11
|
"title",
|
|
12
12
|
"disabled",
|
|
13
13
|
"onChange"
|
|
@@ -69,7 +69,7 @@ var Box_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompon
|
|
|
69
69
|
key: index,
|
|
70
70
|
class: normalizeClass(item.class)
|
|
71
71
|
}, [item.text ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(item.text), 1)) : createCommentVNode("v-if", true), createElementVNode("span", _hoisted_3, [createElementVNode("input", {
|
|
72
|
-
|
|
72
|
+
value: __props.model[item.name],
|
|
73
73
|
placeholder: "0",
|
|
74
74
|
title: __props.model[item.name],
|
|
75
75
|
disabled: __props.disabled,
|
|
@@ -4,6 +4,7 @@ import RepeatX_default from "../icons/background-repeat/RepeatX.js";
|
|
|
4
4
|
import RepeatY_default from "../icons/background-repeat/RepeatY.js";
|
|
5
5
|
import NoRepeat_default from "../icons/background-repeat/NoRepeat.js";
|
|
6
6
|
import { MContainer, defineFormConfig } from "@tmagic/form";
|
|
7
|
+
import { appendValidateSuggestion } from "@tmagic/design";
|
|
7
8
|
import { Fragment, createBlock, createElementBlock, defineComponent, markRaw, openBlock, renderList, unref } from "vue";
|
|
8
9
|
//#region packages/editor/src/fields/StyleSetter/pro/Background.vue?vue&type=script&setup=true&lang.ts
|
|
9
10
|
var Background_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
@@ -26,7 +27,11 @@ var Background_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
26
27
|
text: "背景色",
|
|
27
28
|
labelWidth: "68px",
|
|
28
29
|
type: "data-source-field-select",
|
|
29
|
-
fieldConfig: { type: "colorPicker" }
|
|
30
|
+
fieldConfig: { type: "colorPicker" },
|
|
31
|
+
rules: [{
|
|
32
|
+
typeMatch: true,
|
|
33
|
+
message: appendValidateSuggestion("背景色应为字符串", "请参考以下示例值:\"#000000\"")
|
|
34
|
+
}]
|
|
30
35
|
},
|
|
31
36
|
{
|
|
32
37
|
name: "backgroundImage",
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { validateDataSourceFieldSelectValue } from "../../../utils/type-match-rules.js";
|
|
1
2
|
import Left_default from "../icons/text-align/Left.js";
|
|
2
3
|
import Center_default from "../icons/text-align/Center.js";
|
|
3
4
|
import Right_default from "../icons/text-align/Right.js";
|
|
4
5
|
import { MContainer, defineFormConfig } from "@tmagic/form";
|
|
6
|
+
import { appendValidateSuggestion } from "@tmagic/design";
|
|
5
7
|
import { Fragment, createBlock, createElementBlock, defineComponent, markRaw, openBlock, renderList, unref } from "vue";
|
|
6
8
|
//#region packages/editor/src/fields/StyleSetter/pro/Font.vue?vue&type=script&setup=true&lang.ts
|
|
7
9
|
var Font_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
@@ -25,7 +27,11 @@ var Font_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
|
|
|
25
27
|
name: "fontSize",
|
|
26
28
|
text: "字号",
|
|
27
29
|
type: "data-source-field-select",
|
|
28
|
-
fieldConfig: { type: "text" }
|
|
30
|
+
fieldConfig: { type: "text" },
|
|
31
|
+
rules: [{
|
|
32
|
+
typeMatch: true,
|
|
33
|
+
message: appendValidateSuggestion("字号应为字符串或数字", "请参考以下示例值:24 或 \"24\"")
|
|
34
|
+
}]
|
|
29
35
|
}, {
|
|
30
36
|
labelWidth: "68px",
|
|
31
37
|
name: "lineHeight",
|
|
@@ -39,20 +45,46 @@ var Font_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
|
|
|
39
45
|
text: "字重",
|
|
40
46
|
labelWidth: "68px",
|
|
41
47
|
type: "data-source-field-select",
|
|
48
|
+
dataSourceFieldType: ["string", "number"],
|
|
42
49
|
fieldConfig: {
|
|
43
50
|
type: "select",
|
|
51
|
+
allowCreate: true,
|
|
44
52
|
options: ["normal", "bold"].concat(Array(7).fill(1).map((x, i) => `${i + 1}00`)).map((item) => ({
|
|
45
53
|
value: item,
|
|
46
54
|
text: item
|
|
47
55
|
}))
|
|
48
|
-
}
|
|
56
|
+
},
|
|
57
|
+
rules: [{ typeMatch: false }, { validator: ({ value, callback }, { config, model, prop }, mForm) => {
|
|
58
|
+
if (value === "" || value === null || value === void 0) return callback();
|
|
59
|
+
const result = validateDataSourceFieldSelectValue(value, {
|
|
60
|
+
fieldType: "data-source-field-select",
|
|
61
|
+
mForm,
|
|
62
|
+
props: {
|
|
63
|
+
config,
|
|
64
|
+
model,
|
|
65
|
+
prop
|
|
66
|
+
}
|
|
67
|
+
}, { validatePlainValue: (plainValue) => {
|
|
68
|
+
if (typeof plainValue === "string" || typeof plainValue === "number" && !Number.isNaN(plainValue)) return;
|
|
69
|
+
return "字重应为字符串或数字";
|
|
70
|
+
} });
|
|
71
|
+
if (result && typeof result.then === "function") {
|
|
72
|
+
result.then((error) => callback(error), (error) => callback(error));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
return callback(result);
|
|
76
|
+
} }]
|
|
49
77
|
},
|
|
50
78
|
{
|
|
51
79
|
labelWidth: "68px",
|
|
52
80
|
name: "color",
|
|
53
81
|
text: "颜色",
|
|
54
82
|
type: "data-source-field-select",
|
|
55
|
-
fieldConfig: { type: "colorPicker" }
|
|
83
|
+
fieldConfig: { type: "colorPicker" },
|
|
84
|
+
rules: [{
|
|
85
|
+
typeMatch: true,
|
|
86
|
+
message: appendValidateSuggestion("颜色应为字符串", "请参考以下示例值:\"#000000\"")
|
|
87
|
+
}]
|
|
56
88
|
},
|
|
57
89
|
{
|
|
58
90
|
name: "textAlign",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MContainer, defineFormConfig } from "@tmagic/form";
|
|
2
|
+
import { appendValidateSuggestion } from "@tmagic/design";
|
|
2
3
|
import { Fragment, createBlock, createElementBlock, defineComponent, openBlock, renderList, unref } from "vue";
|
|
3
4
|
//#region packages/editor/src/fields/StyleSetter/pro/Position.vue?vue&type=script&setup=true&lang.ts
|
|
4
5
|
var Position_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
@@ -44,12 +45,20 @@ var Position_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
44
45
|
name: "left",
|
|
45
46
|
type: "data-source-field-select",
|
|
46
47
|
text: "left",
|
|
47
|
-
fieldConfig: { type: "text" }
|
|
48
|
+
fieldConfig: { type: "text" },
|
|
49
|
+
rules: [{
|
|
50
|
+
typeMatch: true,
|
|
51
|
+
message: appendValidateSuggestion("left 应为字符串", "请参考以下示例值:\"10\"")
|
|
52
|
+
}]
|
|
48
53
|
}, {
|
|
49
54
|
name: "top",
|
|
50
55
|
type: "data-source-field-select",
|
|
51
56
|
text: "top",
|
|
52
|
-
fieldConfig: { type: "text" }
|
|
57
|
+
fieldConfig: { type: "text" },
|
|
58
|
+
rules: [{
|
|
59
|
+
typeMatch: true,
|
|
60
|
+
message: appendValidateSuggestion("top 应为字符串", "请参考以下示例值:\"10\"")
|
|
61
|
+
}]
|
|
53
62
|
}]
|
|
54
63
|
},
|
|
55
64
|
{
|
|
@@ -60,12 +69,20 @@ var Position_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
60
69
|
name: "right",
|
|
61
70
|
type: "data-source-field-select",
|
|
62
71
|
text: "right",
|
|
63
|
-
fieldConfig: { type: "text" }
|
|
72
|
+
fieldConfig: { type: "text" },
|
|
73
|
+
rules: [{
|
|
74
|
+
typeMatch: true,
|
|
75
|
+
message: appendValidateSuggestion("right 应为字符串", "请参考以下示例值:\"10\"")
|
|
76
|
+
}]
|
|
64
77
|
}, {
|
|
65
78
|
name: "bottom",
|
|
66
79
|
type: "data-source-field-select",
|
|
67
80
|
text: "bottom",
|
|
68
|
-
fieldConfig: { type: "text" }
|
|
81
|
+
fieldConfig: { type: "text" },
|
|
82
|
+
rules: [{
|
|
83
|
+
typeMatch: true,
|
|
84
|
+
message: appendValidateSuggestion("bottom 应为字符串", "请参考以下示例值:\"10\"")
|
|
85
|
+
}]
|
|
69
86
|
}]
|
|
70
87
|
},
|
|
71
88
|
{
|
|
@@ -73,7 +90,11 @@ var Position_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
73
90
|
name: "zIndex",
|
|
74
91
|
text: "zIndex",
|
|
75
92
|
type: "data-source-field-select",
|
|
76
|
-
fieldConfig: { type: "text" }
|
|
93
|
+
fieldConfig: { type: "text" },
|
|
94
|
+
rules: [{
|
|
95
|
+
typeMatch: true,
|
|
96
|
+
message: appendValidateSuggestion("zIndex 应为数字", "请参考以下示例值:10")
|
|
97
|
+
}]
|
|
77
98
|
}
|
|
78
99
|
]);
|
|
79
100
|
const change = (value, eventData) => {
|
package/dist/es/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { IdleTask } from "./utils/dep/idle-task.js";
|
|
|
31
31
|
import { ScrollViewer } from "./utils/scroll-viewer.js";
|
|
32
32
|
import codeBlock_default from "./services/codeBlock.js";
|
|
33
33
|
import dataSource_default from "./services/dataSource.js";
|
|
34
|
-
import { ALL_COND_OPS, editorTypeMatchRules } from "./utils/type-match-rules.js";
|
|
34
|
+
import { ALL_COND_OPS, editorTypeMatchRules, validateDataSourceFieldSelectValue } from "./utils/type-match-rules.js";
|
|
35
35
|
import events_default from "./services/events.js";
|
|
36
36
|
import { EVENT_NAME_VALUE_SEPARATOR, collectEventNameOptionValues, getCompActionAllowedValues, getCompActionOptions, getEventNameAllowedValues, getEventNameOptions, isEventNameCheckStrictly, normalizeCompActionValue } from "./utils/event.js";
|
|
37
37
|
import monaco_editor_default from "./utils/monaco-editor.js";
|
|
@@ -92,4 +92,4 @@ export * from "@tmagic/table";
|
|
|
92
92
|
export * from "@tmagic/stage";
|
|
93
93
|
export * from "@tmagic/design";
|
|
94
94
|
export * from "@tmagic/utils";
|
|
95
|
-
export { ALL_COND_OPS, CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, CodeBlockEditor_default as CodeBlockEditor, CodeBlockList_default as CodeBlockList, CodeBlockListPanel_default as CodeBlockListPanel, CodeDeleteErrorType, CodeSelect_default as CodeSelect, CodeSelectCol_default as CodeSelectCol, ColumnLayout, CompareForm_default as CompareForm, ComponentListPanel_default as ComponentListPanel, CondOpSelect_default as CondOpSelect, ContentMenu_default as ContentMenu, DEFAULT_LEFT_COLUMN_WIDTH, DEFAULT_RIGHT_COLUMN_WIDTH, DataSourceAddButton_default as DataSourceAddButton, DataSourceConfigPanel_default as DataSourceConfigPanel, Index_default as DataSourceFieldSelect, DataSourceFields_default as DataSourceFields, DataSourceInput_default as DataSourceInput, DataSourceMethodSelect_default as DataSourceMethodSelect, DataSourceMethods_default as DataSourceMethods, DataSourceMocks_default as DataSourceMocks, DataSourceSelect_default as DataSourceSelect, DepTargetType, DisplayConds_default as DisplayConds, DragType, EVENT_NAME_VALUE_SEPARATOR, EventSelect_default as EventSelect, Fixed2Other, FloatingBox_default as FloatingBox, H_GUIDE_LINE_STORAGE_KEY, HistoryDiffDialog_default as HistoryDiffDialog, Bucket_default as HistoryListBucket, BucketTab_default as HistoryListBucketTab, Icon_default as Icon, IdleTask, KeyBindingCommand, KeyValue_default as KeyValue, Keys, LEFT_COLUMN_WIDTH_STORAGE_KEY, LayerNodeContent_default as LayerNodeContent, LayerOffset, LayerPanel_default as LayerPanel, Layout, SplitView_default as LayoutContainer, MIN_CENTER_COLUMN_WIDTH, MIN_LEFT_COLUMN_WIDTH, MIN_RIGHT_COLUMN_WIDTH, PROPS_PANEL_WIDTH_STORAGE_KEY, PageFragmentSelect_default as PageFragmentSelect, FormPanel_default as PropsFormPanel, PropsPanel_default as PropsPanel, RIGHT_COLUMN_WIDTH_STORAGE_KEY, Resizer_default as Resizer, ScrollViewer, SideItemKey, SplitView_default as SplitView, StageCore, Index_default$1 as StyleSetter, CodeEditor_default as TMagicCodeEditor, Editor_default as TMagicEditor, ToolButton_default as ToolButton, Tree_default as Tree, TreeNode_default as TreeNode, UI_SELECT_MODE_EVENT_NAME, UndoRedo, V_GUIDE_LINE_STORAGE_KEY, ViewForm_default as ViewForm, advancedTabConfig, arrayOptions, beforePaste, booleanOptions, buildChangeRecords, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, canUsePluginMethods, change2Fixed, classifyDragSources, codeBlock_default as codeBlockService, collectEventNameOptionValues, collectRelatedNodes, componentList_default as componentListService, confirmHistoryAction, createStackStep, dataSource_default as dataSourceService, debug, plugin_default as default, defaultIsExpandable, dep_default as depService, describeRevertStep, describeStepForRevert, deserializeStacks, designPlugin, detectStackOpType, detectTargetId, detectTargetName, displayTabConfig, editorNodeMergeCustomizer, editor_default as editorService, editorTypeMatchRules, eqOptions, error, eventTabConfig, events_default as eventsService, fillConfig, fixNodeLeft, fixNodePosition, formPlugin, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getCodeBlockFormConfig, getCompActionAllowedValues, getCompActionOptions, getCondOpOptionsByFieldType, getDefaultConfig, getDisplayField, getEditorConfig, getEventNameAllowedValues, getEventNameOptions, getFieldType, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getLastPushedHistoryIds, getNodeIndex, getOrCreateStack, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, history_default as historyService, idbDelete, idbGet, idbSet, info, isEventNameCheckStrictly, isGlobalFlat, isIncludeDataSource, isIndexedDBSupported, keybinding_default as keybindingService, monaco_editor_default as loadMonaco, log, markStackSaved, mergeSteps, moveItemsInContainer, normalizeCompActionValue, numberOptions, openIndexedDB, props_default as propsService, removeStyleDisplayConfig, resolveFieldByPath, resolveSelectedNode, serializeConfig, serializeStacks, setChildrenLayout, setEditorConfig, setLayout, stageOverlay_default as stageOverlayService, storage_default as storageService, styleTabConfig, tablePlugin, toggleFixedPosition, ui_default as uiService, undoFloor, updateStatus, useCodeBlockEdit, useCompareForm, useEditorContentHeight, useFilter, useFloatBox, useGetSo, useHistoryRevert, useNextFloatBoxPosition, useNodeStatus, useServices, useStage, useWindowRect, warn };
|
|
95
|
+
export { ALL_COND_OPS, CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, CodeBlockEditor_default as CodeBlockEditor, CodeBlockList_default as CodeBlockList, CodeBlockListPanel_default as CodeBlockListPanel, CodeDeleteErrorType, CodeSelect_default as CodeSelect, CodeSelectCol_default as CodeSelectCol, ColumnLayout, CompareForm_default as CompareForm, ComponentListPanel_default as ComponentListPanel, CondOpSelect_default as CondOpSelect, ContentMenu_default as ContentMenu, DEFAULT_LEFT_COLUMN_WIDTH, DEFAULT_RIGHT_COLUMN_WIDTH, DataSourceAddButton_default as DataSourceAddButton, DataSourceConfigPanel_default as DataSourceConfigPanel, Index_default as DataSourceFieldSelect, DataSourceFields_default as DataSourceFields, DataSourceInput_default as DataSourceInput, DataSourceMethodSelect_default as DataSourceMethodSelect, DataSourceMethods_default as DataSourceMethods, DataSourceMocks_default as DataSourceMocks, DataSourceSelect_default as DataSourceSelect, DepTargetType, DisplayConds_default as DisplayConds, DragType, EVENT_NAME_VALUE_SEPARATOR, EventSelect_default as EventSelect, Fixed2Other, FloatingBox_default as FloatingBox, H_GUIDE_LINE_STORAGE_KEY, HistoryDiffDialog_default as HistoryDiffDialog, Bucket_default as HistoryListBucket, BucketTab_default as HistoryListBucketTab, Icon_default as Icon, IdleTask, KeyBindingCommand, KeyValue_default as KeyValue, Keys, LEFT_COLUMN_WIDTH_STORAGE_KEY, LayerNodeContent_default as LayerNodeContent, LayerOffset, LayerPanel_default as LayerPanel, Layout, SplitView_default as LayoutContainer, MIN_CENTER_COLUMN_WIDTH, MIN_LEFT_COLUMN_WIDTH, MIN_RIGHT_COLUMN_WIDTH, PROPS_PANEL_WIDTH_STORAGE_KEY, PageFragmentSelect_default as PageFragmentSelect, FormPanel_default as PropsFormPanel, PropsPanel_default as PropsPanel, RIGHT_COLUMN_WIDTH_STORAGE_KEY, Resizer_default as Resizer, ScrollViewer, SideItemKey, SplitView_default as SplitView, StageCore, Index_default$1 as StyleSetter, CodeEditor_default as TMagicCodeEditor, Editor_default as TMagicEditor, ToolButton_default as ToolButton, Tree_default as Tree, TreeNode_default as TreeNode, UI_SELECT_MODE_EVENT_NAME, UndoRedo, V_GUIDE_LINE_STORAGE_KEY, ViewForm_default as ViewForm, advancedTabConfig, arrayOptions, beforePaste, booleanOptions, buildChangeRecords, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, canUsePluginMethods, change2Fixed, classifyDragSources, codeBlock_default as codeBlockService, collectEventNameOptionValues, collectRelatedNodes, componentList_default as componentListService, confirmHistoryAction, createStackStep, dataSource_default as dataSourceService, debug, plugin_default as default, defaultIsExpandable, dep_default as depService, describeRevertStep, describeStepForRevert, deserializeStacks, designPlugin, detectStackOpType, detectTargetId, detectTargetName, displayTabConfig, editorNodeMergeCustomizer, editor_default as editorService, editorTypeMatchRules, eqOptions, error, eventTabConfig, events_default as eventsService, fillConfig, fixNodeLeft, fixNodePosition, formPlugin, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getCodeBlockFormConfig, getCompActionAllowedValues, getCompActionOptions, getCondOpOptionsByFieldType, getDefaultConfig, getDisplayField, getEditorConfig, getEventNameAllowedValues, getEventNameOptions, getFieldType, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getLastPushedHistoryIds, getNodeIndex, getOrCreateStack, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, history_default as historyService, idbDelete, idbGet, idbSet, info, isEventNameCheckStrictly, isGlobalFlat, isIncludeDataSource, isIndexedDBSupported, keybinding_default as keybindingService, monaco_editor_default as loadMonaco, log, markStackSaved, mergeSteps, moveItemsInContainer, normalizeCompActionValue, numberOptions, openIndexedDB, props_default as propsService, removeStyleDisplayConfig, resolveFieldByPath, resolveSelectedNode, serializeConfig, serializeStacks, setChildrenLayout, setEditorConfig, setLayout, stageOverlay_default as stageOverlayService, storage_default as storageService, styleTabConfig, tablePlugin, toggleFixedPosition, ui_default as uiService, undoFloor, updateStatus, useCodeBlockEdit, useCompareForm, useEditorContentHeight, useFilter, useFloatBox, useGetSo, useHistoryRevert, useNextFloatBoxPosition, useNodeStatus, useServices, useStage, useWindowRect, validateDataSourceFieldSelectValue, warn };
|
package/dist/es/initService.js
CHANGED
|
@@ -329,7 +329,8 @@ var initServiceEvents = (props, emit, { editorService, codeBlockService, dataSou
|
|
|
329
329
|
const root = editorService.get("root");
|
|
330
330
|
if (!root) return;
|
|
331
331
|
const handler = async () => {
|
|
332
|
-
const
|
|
332
|
+
const nodeIds = Object.keys(root.dataSourceDeps?.[id] || {});
|
|
333
|
+
const nodes = getNodes(nodeIds, root.items);
|
|
333
334
|
if (!(await Promise.all([
|
|
334
335
|
collectIdle(nodes, false, DepTargetType.DATA_SOURCE),
|
|
335
336
|
collectIdle(nodes, false, DepTargetType.DATA_SOURCE_COND),
|
|
@@ -68,22 +68,33 @@ var PropsPanel_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
68
68
|
const submit = async (v, eventData, error, source = "props") => {
|
|
69
69
|
try {
|
|
70
70
|
if (!v.id) v.id = values.value.id;
|
|
71
|
-
const newValue = {
|
|
72
|
-
...v,
|
|
73
|
-
style: {}
|
|
74
|
-
};
|
|
75
|
-
if (v.style) if (eventData) {
|
|
76
|
-
Object.entries(v.style).forEach(([key, value]) => {
|
|
77
|
-
if (value !== "" && newValue.style) newValue.style[key] = value;
|
|
78
|
-
});
|
|
79
|
-
eventData.changeRecords?.forEach((record) => {
|
|
80
|
-
if (record.propPath?.startsWith("style") && record.value === "") setValueByKeyPath(record.propPath, record.value, newValue);
|
|
81
|
-
});
|
|
82
|
-
} else newValue.style = { ...v.style };
|
|
83
71
|
const historySource = eventData ? "props" : "code";
|
|
72
|
+
const replace = historySource === "code";
|
|
73
|
+
let newValue;
|
|
74
|
+
if (replace) if (source === "style") newValue = {
|
|
75
|
+
...values.value,
|
|
76
|
+
id: v.id || values.value.id,
|
|
77
|
+
style: { ...v.style || {} }
|
|
78
|
+
};
|
|
79
|
+
else newValue = { ...v };
|
|
80
|
+
else {
|
|
81
|
+
newValue = {
|
|
82
|
+
...v,
|
|
83
|
+
style: {}
|
|
84
|
+
};
|
|
85
|
+
if (v.style) {
|
|
86
|
+
Object.entries(v.style).forEach(([key, value]) => {
|
|
87
|
+
if (value !== "" && newValue.style) newValue.style[key] = value;
|
|
88
|
+
});
|
|
89
|
+
eventData?.changeRecords?.forEach((record) => {
|
|
90
|
+
if (record.propPath?.startsWith("style") && record.value === "") setValueByKeyPath(record.propPath, record.value, newValue);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
84
94
|
editorService.update(newValue, {
|
|
85
95
|
changeRecords: eventData?.changeRecords,
|
|
86
96
|
historySource,
|
|
97
|
+
replace,
|
|
87
98
|
...enablePropsFormValidate && error ? { invalidInfo: {
|
|
88
99
|
id: newValue.id,
|
|
89
100
|
source,
|
|
@@ -23,7 +23,7 @@ var ComponentListPanel_vue_vue_type_script_setup_true_lang_default = /*@__PURE__
|
|
|
23
23
|
const stage = computed(() => editorService.get("stage"));
|
|
24
24
|
const list = computed(() => componentListService.getList().map((group) => ({
|
|
25
25
|
...group,
|
|
26
|
-
items: group.items.filter((item) => item.text.includes(searchText.value))
|
|
26
|
+
items: group.items.filter((item) => `${item.text || ""}${item.desc || ""}${item.type}`.toLocaleLowerCase().includes(searchText.value.toLocaleLowerCase()))
|
|
27
27
|
})));
|
|
28
28
|
const collapseValue = ref();
|
|
29
29
|
watch(list, () => {
|
|
@@ -145,7 +145,8 @@ var Sidebar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
|
|
|
145
145
|
watch(() => props.data.status, (status) => {
|
|
146
146
|
activeTabName.value = status || "0";
|
|
147
147
|
});
|
|
148
|
-
const
|
|
148
|
+
const slideKeys = computed(() => sideBarItems.value.map((sideBarItem) => sideBarItem.$key));
|
|
149
|
+
const { dragstartHandler, dragendHandler, floatBoxStates, showingBoxKeys } = useFloatBox(slideKeys);
|
|
149
150
|
watch(() => showingBoxKeys.value.length, () => {
|
|
150
151
|
if (!showingBoxKeys.value.some((key) => activeTabName.value === sideBarItems.value.find((v) => v.$key === key)?.text) && activeTabName.value) return;
|
|
151
152
|
const nextSlideBarItem = sideBarItems.value.find((sideBarItem) => !showingBoxKeys.value.includes(sideBarItem.$key));
|
|
@@ -38,7 +38,8 @@ var DataSourceConfigPanel_vue_vue_type_script_setup_true_lang_default = /*@__PUR
|
|
|
38
38
|
const initValues = ref({});
|
|
39
39
|
const dataSourceConfig = ref([]);
|
|
40
40
|
const { height: editorHeight } = useEditorContentHeight();
|
|
41
|
-
const
|
|
41
|
+
const parentFloating = inject("parentFloating", ref(null));
|
|
42
|
+
const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(uiService, parentFloating);
|
|
42
43
|
const frameworkWidth = computed(() => uiService.get("frameworkRect")?.width || 0);
|
|
43
44
|
/** 供「方法定义」tab 内的字段消费,用于打开数据源详情后自动打开指定方法 */
|
|
44
45
|
provide("editingDataSourceMethodName", computed(() => props.editMethodName));
|
|
@@ -39,7 +39,7 @@ var LayerPanel_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
39
39
|
let name = "";
|
|
40
40
|
if (data.name) name = data.name;
|
|
41
41
|
else if (data.items) name = "container";
|
|
42
|
-
return `${data.id}${name}${data.type}`.includes(v);
|
|
42
|
+
return `${data.id}${name}${data.type || ""}`.toLocaleLowerCase().includes(v.toLocaleLowerCase());
|
|
43
43
|
};
|
|
44
44
|
const { filterTextChangeHandler } = useFilter(nodeData, nodeStatusMap, filterNodeMethod);
|
|
45
45
|
const collapseAllHandler = () => {
|
|
@@ -51,7 +51,8 @@ var LayerPanel_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
const { handleDragStart, handleDragEnd, handleDragLeave, handleDragOver } = useDrag(services, { canDropIn: (sourceIds, targetId) => props.canDropIn?.(sourceIds, targetId, "layer") });
|
|
54
|
-
const
|
|
54
|
+
const menuRef = useTemplateRef("menu");
|
|
55
|
+
const { nodeClickHandler, nodeDblclickHandler, nodeContentMenuHandler, highlightHandler: mouseenterHandler } = useClick(services, isCtrlKeyDown, nodeStatusMap, menuRef);
|
|
55
56
|
const dblclickHandler = async (event, data) => {
|
|
56
57
|
if (props.beforeNodeDblclick) {
|
|
57
58
|
if (await props.beforeNodeDblclick(event, data) === false) return;
|
|
@@ -141,7 +141,8 @@ var CodeBlock = class extends BaseService {
|
|
|
141
141
|
* @returns {CodeBlockDSL}
|
|
142
142
|
*/
|
|
143
143
|
getCodeDslByIds(ids) {
|
|
144
|
-
|
|
144
|
+
const codeDsl = this.getCodeDsl();
|
|
145
|
+
return pick(codeDsl, ids);
|
|
145
146
|
}
|
|
146
147
|
/**
|
|
147
148
|
* 获取编辑状态
|
|
@@ -371,7 +372,8 @@ var CodeBlock = class extends BaseService {
|
|
|
371
372
|
*/
|
|
372
373
|
async getUniqueId() {
|
|
373
374
|
const newId = `code_${Math.random().toString(10).substring(2).substring(0, 4)}`;
|
|
374
|
-
|
|
375
|
+
const dsl = await this.getCodeDsl();
|
|
376
|
+
if (!keys(dsl).includes(newId)) return newId;
|
|
375
377
|
return await this.getUniqueId();
|
|
376
378
|
}
|
|
377
379
|
/**
|
|
@@ -467,14 +467,14 @@ var Editor = class extends BaseService {
|
|
|
467
467
|
remove: removedPages
|
|
468
468
|
});
|
|
469
469
|
}
|
|
470
|
-
async doUpdate(config, { changeRecords = [], historySource } = {}) {
|
|
470
|
+
async doUpdate(config, { changeRecords = [], historySource, replace = false } = {}) {
|
|
471
471
|
if (!this.get("root")) throw new Error("root为空");
|
|
472
472
|
if (!config?.id) throw new Error("没有配置或者配置缺少id值");
|
|
473
473
|
const info = this.getNodeInfo(config.id, false);
|
|
474
474
|
if (!info.node) throw new Error(`获取不到id为${config.id}的节点`);
|
|
475
475
|
const node = toRaw(info.node);
|
|
476
|
-
let newConfig = await toggleFixedPosition(toRaw(config), node, info.path, this.getLayout);
|
|
477
|
-
newConfig = mergeWith(cloneDeep$1(node), newConfig, editorNodeMergeCustomizer);
|
|
476
|
+
let newConfig = replace ? cloneDeep$1(toRaw(config)) : await toggleFixedPosition(toRaw(config), node, info.path, this.getLayout);
|
|
477
|
+
if (!replace) newConfig = mergeWith(cloneDeep$1(node), newConfig, editorNodeMergeCustomizer);
|
|
478
478
|
if (!newConfig.type) throw new Error("配置缺少type值");
|
|
479
479
|
if (newConfig.type === NodeType.ROOT) {
|
|
480
480
|
this.set("root", newConfig, { historySource });
|
|
@@ -489,9 +489,11 @@ var Editor = class extends BaseService {
|
|
|
489
489
|
const parentNodeItems = parent.items;
|
|
490
490
|
const index = getNodeIndex(newConfig.id, parent);
|
|
491
491
|
if (!parentNodeItems || typeof index === "undefined" || index === -1) throw new Error("更新的节点未找到");
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
492
|
+
if (!replace) {
|
|
493
|
+
const newLayout = await this.getLayout(newConfig);
|
|
494
|
+
const layout = await this.getLayout(node);
|
|
495
|
+
if (Array.isArray(newConfig.items) && newLayout !== layout) newConfig = setChildrenLayout(newConfig, newLayout);
|
|
496
|
+
}
|
|
495
497
|
parentNodeItems[index] = newConfig;
|
|
496
498
|
const selectedNodes = this.get("nodes");
|
|
497
499
|
const targetIndex = selectedNodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
|
|
@@ -519,17 +521,19 @@ var Editor = class extends BaseService {
|
|
|
519
521
|
* @param data.changeRecordList 多节点 form 端变更记录列表,按 config 数组同序对应每个节点;优先级高于 changeRecords
|
|
520
522
|
* @param data.doNotPushHistory 是否不写入历史记录(默认 false)
|
|
521
523
|
* @param data.historyDescription 入栈时附带的人类可读描述,用于历史面板展示(不影响 undo/redo 行为)
|
|
524
|
+
* @param data.replace 是否整节点替换:为 true 时跳过 mergeWith / toggleFixedPosition / setChildrenLayout,直接用传入配置覆盖(默认 false)
|
|
522
525
|
* @returns 更新后的节点配置
|
|
523
526
|
*/
|
|
524
527
|
async update(config, data = {}) {
|
|
525
528
|
this.captureSelectionBeforeOp();
|
|
526
|
-
const { doNotPushHistory = false, changeRecordList, changeRecords, historyDescription, historySource, invalidInfo } = data;
|
|
529
|
+
const { doNotPushHistory = false, changeRecordList, changeRecords, historyDescription, historySource, replace = false, invalidInfo } = data;
|
|
527
530
|
const nodes = Array.isArray(config) ? config : [config];
|
|
528
531
|
const updateData = await Promise.all(nodes.map((node, index) => {
|
|
529
532
|
const recordsForNode = changeRecordList ? changeRecordList[index] ?? [] : changeRecords ?? [];
|
|
530
533
|
return this.doUpdate(node, {
|
|
531
534
|
changeRecords: recordsForNode,
|
|
532
|
-
historySource
|
|
535
|
+
historySource,
|
|
536
|
+
replace
|
|
533
537
|
});
|
|
534
538
|
}));
|
|
535
539
|
this.applyInvalidInfo(config, invalidInfo);
|
|
@@ -10,11 +10,17 @@ import serialize from "serialize-javascript";
|
|
|
10
10
|
*
|
|
11
11
|
* 全量收集与增量收集共用一个常驻 worker:增量收集调用频繁(每次节点更新都会触发),
|
|
12
12
|
* 按次创建 worker 的启动开销无法接受,也容易漏掉销毁导致线程泄漏。
|
|
13
|
+
*
|
|
14
|
+
* 请求在主线程侧排队后逐个投递(worker 本身也是串行处理),这样 abort 时能直接丢掉尚未投递的请求,
|
|
15
|
+
* 无需销毁线程:worker 只在真正异常或销毁时才重建。
|
|
13
16
|
*/
|
|
14
17
|
var CollectWorkerClient = class {
|
|
15
18
|
worker = null;
|
|
16
19
|
seed = 0;
|
|
17
|
-
|
|
20
|
+
/** 等待投递给 worker 的请求 */
|
|
21
|
+
queue = [];
|
|
22
|
+
/** 已投递、等待 worker 响应的请求,worker 串行处理,同一时刻最多一个 */
|
|
23
|
+
inflight = null;
|
|
18
24
|
get isSupported() {
|
|
19
25
|
return typeof Worker !== "undefined";
|
|
20
26
|
}
|
|
@@ -44,34 +50,63 @@ var CollectWorkerClient = class {
|
|
|
44
50
|
terminate() {
|
|
45
51
|
this.worker?.terminate();
|
|
46
52
|
this.worker = null;
|
|
47
|
-
this.
|
|
53
|
+
this.settleAll();
|
|
48
54
|
}
|
|
49
55
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
56
|
+
* 丢弃在途请求,但保留常驻 worker
|
|
57
|
+
*
|
|
58
|
+
* clearIdleTasks / reset 中断收集时调用。这里不能销毁 worker:worker 重建要重新加载并启动整份收集逻辑,
|
|
59
|
+
* 而 clearIdleTasks / reset 触发频繁(root 更新、数据源变更、历史回滚等),一旦下一次 abort 落在
|
|
60
|
+
* 上一个 worker 还没启动完的窗口内,就会陷入「加载中被销毁 → 重建 → 又被销毁」的循环,
|
|
61
|
+
* 表现为 worker 反复加载且依赖始终收集不完。
|
|
62
|
+
*
|
|
63
|
+
* 因此 abort 只做「不要这些结果」:尚未投递的请求直接丢掉,已投递的那一个标记为丢弃,
|
|
64
|
+
* 结果回来后忽略(不写回主线程),worker 继续复用。
|
|
52
65
|
*/
|
|
53
66
|
abort() {
|
|
54
|
-
this
|
|
67
|
+
const { queue } = this;
|
|
68
|
+
this.queue = [];
|
|
69
|
+
for (const task of queue) task.resolve(null);
|
|
70
|
+
if (this.inflight && !this.inflight.discarded) {
|
|
71
|
+
this.inflight.discarded = true;
|
|
72
|
+
this.inflight.resolve(null);
|
|
73
|
+
}
|
|
55
74
|
}
|
|
56
|
-
/**
|
|
57
|
-
* worker 按收到的顺序逐个处理请求,因此请求间不会互相打断,用 id 把结果分发回各自的调用方
|
|
58
|
-
*/
|
|
59
75
|
request(createRequest) {
|
|
60
|
-
|
|
61
|
-
if (!worker) return Promise.resolve(null);
|
|
76
|
+
if (!this.isSupported) return Promise.resolve(null);
|
|
62
77
|
this.seed += 1;
|
|
63
78
|
const id = this.seed;
|
|
64
79
|
return new Promise((resolve) => {
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
80
|
+
this.queue.push({
|
|
81
|
+
id,
|
|
82
|
+
createRequest,
|
|
83
|
+
resolve,
|
|
84
|
+
discarded: false
|
|
85
|
+
});
|
|
86
|
+
this.flush();
|
|
73
87
|
});
|
|
74
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* 投递队首请求,worker 串行处理,因此同一时刻只投递一个,用 id 把结果分发回各自的调用方
|
|
91
|
+
*/
|
|
92
|
+
flush() {
|
|
93
|
+
if (this.inflight || !this.queue.length) return;
|
|
94
|
+
const worker = this.getWorker();
|
|
95
|
+
if (!worker) {
|
|
96
|
+
this.settleAll();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const task = this.queue.shift();
|
|
100
|
+
this.inflight = task;
|
|
101
|
+
try {
|
|
102
|
+
worker.postMessage(task.createRequest(task.id));
|
|
103
|
+
} catch (e) {
|
|
104
|
+
error("magic editor: 依赖收集 worker 通信失败", e);
|
|
105
|
+
this.inflight = null;
|
|
106
|
+
if (!task.discarded) task.resolve(null);
|
|
107
|
+
this.flush();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
75
110
|
getWorker() {
|
|
76
111
|
if (!this.isSupported) return null;
|
|
77
112
|
if (this.worker) return this.worker;
|
|
@@ -94,20 +129,25 @@ var CollectWorkerClient = class {
|
|
|
94
129
|
return this.worker;
|
|
95
130
|
}
|
|
96
131
|
handleResponse(response) {
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
99
|
-
this.
|
|
100
|
-
resolve(response.failed ? null : response);
|
|
132
|
+
const task = this.inflight;
|
|
133
|
+
if (task?.id !== response?.id) return;
|
|
134
|
+
this.inflight = null;
|
|
135
|
+
if (!task.discarded) task.resolve(response.failed ? null : response);
|
|
136
|
+
this.flush();
|
|
101
137
|
}
|
|
102
138
|
handleFatalError() {
|
|
103
139
|
this.worker?.terminate();
|
|
104
140
|
this.worker = null;
|
|
105
|
-
this.
|
|
141
|
+
this.settleAll();
|
|
106
142
|
}
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
this.
|
|
110
|
-
|
|
143
|
+
settleAll() {
|
|
144
|
+
const tasks = this.queue;
|
|
145
|
+
this.queue = [];
|
|
146
|
+
if (this.inflight) {
|
|
147
|
+
tasks.push(this.inflight);
|
|
148
|
+
this.inflight = null;
|
|
149
|
+
}
|
|
150
|
+
for (const task of tasks) if (!task.discarded) task.resolve(null);
|
|
111
151
|
}
|
|
112
152
|
};
|
|
113
153
|
//#endregion
|