@tmagic/editor 1.8.0-manmanyu.8 → 1.8.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/es/Editor.vue_vue_type_script_setup_true_lang.js +22 -13
- package/dist/es/components/CodeBlockEditor.vue_vue_type_script_setup_true_lang.js +10 -5
- package/dist/es/components/CodeParams.vue_vue_type_script_setup_true_lang.js +7 -6
- package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +21 -119
- package/dist/es/components/ContentMenu.vue_vue_type_script_setup_true_lang.js +21 -5
- package/dist/es/components/FloatingBox.vue_vue_type_script_setup_true_lang.js +62 -16
- package/dist/es/components/Icon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/Resizer.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/es/components/ScrollBar.js +0 -1
- package/dist/es/components/ScrollBar.vue_vue_type_script_setup_true_lang.js +5 -4
- package/dist/es/components/ScrollViewer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/SearchInput.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/SplitView.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ToolButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/Tree.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/TreeNode.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ViewForm.js +5 -0
- package/dist/es/components/ViewForm.vue_vue_type_script_setup_true_lang.js +56 -0
- package/dist/es/editorProps.js +7 -1
- package/dist/es/fields/Code.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/CodeLink.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +30 -113
- package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +7 -19
- package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +7 -6
- package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +12 -4
- package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +9 -20
- package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +2 -2
- package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +5 -3
- package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +9 -4
- package/dist/es/fields/DataSourceSelect.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +10 -110
- package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +52 -363
- package/dist/es/fields/KeyValue.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/PageFragmentSelect.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +3 -6
- package/dist/es/fields/StyleSetter/components/BackgroundPosition.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +4 -35
- package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/fields/StyleSetter/configs.js +663 -0
- package/dist/es/fields/StyleSetter/icons/align-items/Center.js +1 -1
- package/dist/es/fields/StyleSetter/icons/align-items/FlexEnd.js +1 -1
- package/dist/es/fields/StyleSetter/icons/align-items/FlexStart.js +1 -1
- package/dist/es/fields/StyleSetter/icons/align-items/SpaceAround.js +1 -1
- package/dist/es/fields/StyleSetter/icons/align-items/SpaceBetween.js +1 -1
- package/dist/es/fields/StyleSetter/icons/background-repeat/NoRepeat.js +1 -1
- package/dist/es/fields/StyleSetter/icons/background-repeat/Repeat.js +1 -1
- package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatX.js +1 -1
- package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatY.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/Block.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/Flex.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/Inline.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/InlineBlock.js +1 -1
- package/dist/es/fields/StyleSetter/icons/display/None.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/Column.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/ColumnReverse.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/Row.js +1 -1
- package/dist/es/fields/StyleSetter/icons/flex-direction/RowReverse.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/Center.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/FlexEnd.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/FlexStart.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/SpaceAround.js +1 -1
- package/dist/es/fields/StyleSetter/icons/justify-content/SpaceBetween.js +1 -1
- package/dist/es/fields/StyleSetter/icons/text-align/Center.js +1 -1
- package/dist/es/fields/StyleSetter/icons/text-align/Left.js +1 -1
- package/dist/es/fields/StyleSetter/icons/text-align/Right.js +1 -1
- package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +29 -106
- package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +8 -11
- package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +30 -89
- package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +29 -297
- package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +29 -82
- package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +8 -24
- package/dist/es/fields/UISelect.js +0 -1
- package/dist/es/fields/UISelect.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/configs/codeSelect.js +98 -0
- package/dist/es/fields/configs/displayConds.js +158 -0
- package/dist/es/fields/configs/eventSelect.js +225 -0
- package/dist/es/fields/configs/stickyAddButton.js +21 -0
- package/dist/es/fields/headless-validation.js +139 -0
- package/dist/es/headless.js +2 -0
- package/dist/es/hooks/use-code-block-edit.js +4 -2
- package/dist/es/hooks/use-compare-form.js +101 -0
- package/dist/es/hooks/use-form-context.js +29 -0
- package/dist/es/hooks/use-stage.js +1 -0
- package/dist/es/icons/CenterIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/icons/CodeIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/icons/DatasourceIcon.js +1 -1
- package/dist/es/icons/FolderMinusIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/index.js +17 -9
- package/dist/es/initService.js +52 -16
- package/dist/es/layouts/AddPageBox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +26 -10
- package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +11 -8
- package/dist/es/layouts/NavMenu.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/layouts/NavMenuColumn.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/BucketTab.vue_vue_type_script_setup_true_lang.js +8 -5
- package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +26 -10
- package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +36 -28
- package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/composables.js +1 -1
- package/dist/es/layouts/history-list/useHistoryList.js +4 -4
- package/dist/es/layouts/history-list/useHistoryRevert.js +38 -33
- package/dist/es/layouts/page-bar/AddButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/PageBar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/PageBarScrollContainer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/PageList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/page-bar/Search.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +50 -20
- package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +53 -35
- package/dist/es/layouts/props-panel/use-style-panel.js +3 -2
- package/dist/es/layouts/sidebar/ComponentListPanel.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +21 -36
- package/dist/es/layouts/sidebar/code-block/CodeBlockList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/es/layouts/sidebar/code-block/useContentMenu.js +19 -4
- package/dist/es/layouts/sidebar/data-source/DataSourceAddButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceConfigPanel.vue_vue_type_script_setup_true_lang.js +9 -4
- package/dist/es/layouts/sidebar/data-source/DataSourceList.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/es/layouts/sidebar/data-source/useContentMenu.js +19 -4
- package/dist/es/layouts/sidebar/layer/LayerMenu.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/layouts/sidebar/layer/LayerNodeContent.js +5 -0
- package/dist/es/layouts/sidebar/layer/LayerNodeContent.vue_vue_type_script_setup_true_lang.js +46 -0
- package/dist/es/layouts/sidebar/layer/LayerNodeTool.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +6 -4
- package/dist/es/layouts/sidebar/layer/use-click.js +3 -3
- package/dist/es/layouts/sidebar/layer/use-drag.js +11 -10
- package/dist/es/layouts/sidebar/layer/use-node-status.js +2 -2
- package/dist/es/layouts/workspace/Breadcrumb.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/Workspace.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/viewer/NodeListMenu.vue_vue_type_script_setup_true_lang.js +9 -3
- package/dist/es/layouts/workspace/viewer/Stage.vue_vue_type_script_setup_true_lang.js +55 -9
- package/dist/es/layouts/workspace/viewer/StageOverlay.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/workspace/viewer/ViewerMenu.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/es/plugin.js +35 -23
- package/dist/es/services/codeBlock.js +40 -31
- package/dist/es/services/dataSource.js +46 -34
- package/dist/es/services/dep.js +162 -41
- package/dist/es/services/editor.js +373 -137
- package/dist/es/services/events.js +4 -4
- package/dist/es/services/history.js +275 -392
- package/dist/es/services/keybinding.js +3 -3
- package/dist/es/services/props.js +2 -1
- package/dist/es/services/storage.js +2 -2
- package/dist/es/services/ui.js +7 -2
- package/dist/es/style.css +277 -114
- package/dist/es/utils/code-block.js +14 -7
- package/dist/es/utils/config.js +4 -1
- package/dist/es/utils/const.js +2 -2
- package/dist/es/utils/content-menu.js +2 -2
- package/dist/es/utils/data-source/index.js +34 -12
- package/dist/es/utils/dep/collect-worker-client.js +154 -0
- package/dist/es/utils/dep/idle-task.js +70 -22
- package/dist/es/utils/dep/worker.js +1 -1
- package/dist/es/utils/editor.js +4 -2
- package/dist/es/utils/event.js +135 -0
- package/dist/es/utils/history.js +35 -47
- package/dist/es/utils/monaco-editor.js +22 -6
- package/dist/es/utils/operator.js +2 -2
- package/dist/es/utils/props.js +50 -106
- package/dist/es/utils/type-match-rules.js +356 -0
- package/dist/style.css +277 -114
- package/dist/themes/magic-admin.css +978 -175
- package/dist/tmagic-editor-headless.umd.cjs +10880 -0
- package/dist/tmagic-editor.umd.cjs +13047 -11363
- package/package.json +18 -13
- package/src/Editor.vue +23 -6
- package/src/components/CodeBlockEditor.vue +3 -0
- package/src/components/CodeParams.vue +10 -4
- package/src/components/CompareForm.vue +20 -190
- package/src/components/ContentMenu.vue +34 -6
- package/src/components/FloatingBox.vue +71 -7
- package/src/components/ScrollBar.vue +0 -67
- package/src/components/ViewForm.vue +54 -0
- package/src/editorProps.ts +23 -10
- package/src/fields/Code.vue +1 -1
- package/src/fields/CodeSelect.vue +20 -113
- package/src/fields/CodeSelectCol.vue +1 -1
- package/src/fields/CondOpSelect.vue +5 -26
- package/src/fields/DataSourceFieldSelect/FieldSelect.vue +2 -2
- package/src/fields/DataSourceFieldSelect/Index.vue +4 -1
- package/src/fields/DataSourceFields.vue +5 -1
- package/src/fields/DataSourceInput.vue +10 -28
- package/src/fields/DataSourceMethodSelect.vue +1 -1
- package/src/fields/DataSourceMethods.vue +6 -2
- package/src/fields/DataSourceMocks.vue +3 -0
- package/src/fields/DataSourceSelect.vue +1 -1
- package/src/fields/DisplayConds.vue +17 -139
- package/src/fields/EventSelect.vue +29 -416
- package/src/fields/KeyValue.vue +1 -1
- package/src/fields/StyleSetter/Index.vue +2 -8
- package/src/fields/StyleSetter/components/Border.vue +4 -38
- package/src/fields/StyleSetter/components/Box.vue +1 -1
- package/src/fields/StyleSetter/components/Position.vue +1 -1
- package/src/fields/StyleSetter/configs.ts +690 -0
- package/src/fields/StyleSetter/pro/Background.vue +9 -64
- package/src/fields/StyleSetter/pro/Border.vue +5 -16
- package/src/fields/StyleSetter/pro/Font.vue +11 -71
- package/src/fields/StyleSetter/pro/Layout.vue +10 -230
- package/src/fields/StyleSetter/pro/Position.vue +11 -82
- package/src/fields/StyleSetter/pro/Transform.vue +6 -34
- package/src/fields/UISelect.vue +0 -12
- package/src/fields/configs/codeSelect.ts +127 -0
- package/src/fields/configs/displayConds.ts +184 -0
- package/src/fields/configs/eventSelect.ts +309 -0
- package/src/fields/configs/stickyAddButton.ts +32 -0
- package/src/fields/headless-validation.ts +177 -0
- package/src/headless.ts +33 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-compare-form.ts +166 -0
- package/src/hooks/use-form-context.ts +56 -0
- package/src/hooks/use-stage.ts +1 -0
- package/src/index.ts +9 -0
- package/src/initService.ts +73 -18
- package/src/layouts/CodeEditor.vue +32 -6
- package/src/layouts/Framework.vue +7 -6
- package/src/layouts/history-list/BucketTab.vue +2 -2
- package/src/layouts/history-list/HistoryDiffDialog.vue +33 -15
- package/src/layouts/history-list/HistoryListPanel.vue +16 -18
- package/src/layouts/history-list/useHistoryRevert.ts +57 -41
- package/src/layouts/props-panel/FormPanel.vue +75 -20
- package/src/layouts/props-panel/PropsPanel.vue +81 -30
- package/src/layouts/props-panel/use-style-panel.ts +4 -3
- package/src/layouts/sidebar/ComponentListPanel.vue +6 -2
- package/src/layouts/sidebar/Sidebar.vue +5 -3
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +5 -2
- package/src/layouts/sidebar/code-block/useContentMenu.ts +14 -2
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +3 -0
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +3 -3
- package/src/layouts/sidebar/data-source/useContentMenu.ts +14 -2
- package/src/layouts/sidebar/layer/LayerMenu.vue +2 -2
- package/src/layouts/sidebar/layer/LayerNodeContent.vue +57 -0
- package/src/layouts/sidebar/layer/LayerPanel.vue +5 -2
- package/src/layouts/sidebar/layer/use-click.ts +3 -3
- package/src/layouts/sidebar/layer/use-node-status.ts +2 -2
- package/src/layouts/workspace/viewer/NodeListMenu.vue +4 -1
- package/src/layouts/workspace/viewer/Stage.vue +80 -10
- package/src/layouts/workspace/viewer/ViewerMenu.vue +7 -7
- package/src/plugin.ts +35 -25
- package/src/services/codeBlock.ts +4 -0
- package/src/services/dataSource.ts +3 -0
- package/src/services/dep.ts +292 -47
- package/src/services/editor.ts +383 -120
- package/src/services/events.ts +8 -7
- package/src/services/history.ts +22 -1
- package/src/services/keybinding.ts +3 -3
- package/src/services/ui.ts +26 -5
- package/src/theme/code-block.scss +0 -37
- package/src/theme/display-conds.scss +4 -0
- package/src/theme/event.scss +25 -33
- package/src/theme/floating-box.scss +9 -1
- package/src/theme/framework.scss +4 -1
- package/src/theme/layer-node-content.scss +14 -0
- package/src/theme/nav-menu.scss +5 -1
- package/src/theme/props-panel.scss +17 -3
- package/src/theme/scroll-bar.scss +64 -0
- package/src/theme/theme.scss +3 -0
- package/src/theme/themes/magic-admin/index.scss +109 -9
- package/src/theme/ui-select.scss +9 -0
- package/src/type.ts +216 -6
- package/src/utils/code-block.ts +1 -0
- package/src/utils/config.ts +9 -1
- package/src/utils/const.ts +3 -3
- package/src/utils/content-menu.ts +2 -2
- package/src/utils/data-source/index.ts +31 -12
- package/src/utils/dep/collect-worker-client.ts +215 -0
- package/src/utils/dep/idle-task.ts +104 -35
- package/src/utils/dep/worker.ts +113 -9
- package/src/utils/event.ts +237 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/monaco-editor.ts +27 -0
- package/src/utils/operator.ts +2 -2
- package/src/utils/props.ts +61 -122
- package/src/utils/type-match-rules.ts +697 -0
- package/types/headless.d.ts +17 -0
- package/types/index.d.ts +1494 -978
- package/src/fields/StyleSetter/icons/align-items/index copy.ts +0 -5
package/src/plugin.ts
CHANGED
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import type
|
|
19
|
+
import { type App } from 'vue';
|
|
20
20
|
|
|
21
21
|
import type { DesignPluginOptions } from '@tmagic/design';
|
|
22
22
|
import designPlugin from '@tmagic/design';
|
|
23
|
-
import type { FormInstallOptions } from '@tmagic/form';
|
|
24
|
-
import formPlugin from '@tmagic/form';
|
|
23
|
+
import type { FieldOptions, FormInstallOptions } from '@tmagic/form';
|
|
24
|
+
import formPlugin, { mergeFieldOptions } from '@tmagic/form';
|
|
25
25
|
import tablePlugin from '@tmagic/table';
|
|
26
26
|
|
|
27
27
|
import Code from './fields/Code.vue';
|
|
@@ -38,6 +38,7 @@ import DataSourceMocks from './fields/DataSourceMocks.vue';
|
|
|
38
38
|
import DataSourceSelect from './fields/DataSourceSelect.vue';
|
|
39
39
|
import DisplayConds from './fields/DisplayConds.vue';
|
|
40
40
|
import EventSelect from './fields/EventSelect.vue';
|
|
41
|
+
import { editorFields } from './fields/headless-validation';
|
|
41
42
|
import KeyValue from './fields/KeyValue.vue';
|
|
42
43
|
import PageFragmentSelect from './fields/PageFragmentSelect.vue';
|
|
43
44
|
import StyleSetter from './fields/StyleSetter/Index.vue';
|
|
@@ -55,38 +56,47 @@ const defaultInstallOpt: EditorInstallOptions = {
|
|
|
55
56
|
customCreateMonacoEditor: (monaco, codeEditorEl, options) => monaco.editor.create(codeEditorEl, options),
|
|
56
57
|
customCreateMonacoDiffEditor: (monaco, codeEditorEl, options) =>
|
|
57
58
|
monaco.editor.createDiffEditor(codeEditorEl, options),
|
|
59
|
+
|
|
60
|
+
flat: false,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const editorFieldVue: Record<string, Pick<FieldOptions, 'component' | 'container'>> = {
|
|
64
|
+
'vs-code': { component: Code },
|
|
65
|
+
'ui-select': { component: uiSelect },
|
|
66
|
+
'cond-op-select': { component: CondOpSelect },
|
|
67
|
+
'page-fragment-select': { component: PageFragmentSelect },
|
|
68
|
+
'data-source-select': { component: DataSourceSelect },
|
|
69
|
+
'data-source-input': { component: DataSourceInput },
|
|
70
|
+
'code-link': { component: CodeLink },
|
|
71
|
+
'key-value': { component: KeyValue },
|
|
72
|
+
'code-select-col': { component: CodeSelectCol },
|
|
73
|
+
'data-source-fields': { component: DataSourceFields },
|
|
74
|
+
'data-source-mocks': { component: DataSourceMocks },
|
|
75
|
+
'data-source-methods': { component: DataSourceMethods },
|
|
76
|
+
'data-source-method-select': { component: DataSourceMethodSelect },
|
|
77
|
+
'data-source-field-select': { component: DataSourceFieldSelect },
|
|
78
|
+
'code-select': { component: CodeSelect },
|
|
79
|
+
'display-conds': { component: DisplayConds },
|
|
80
|
+
'event-select': { component: EventSelect },
|
|
81
|
+
'style-setter': { container: StyleSetter },
|
|
58
82
|
};
|
|
59
83
|
|
|
60
84
|
export default {
|
|
61
85
|
install: (app: App, opt?: Partial<EditorInstallOptions | DesignPluginOptions | FormInstallOptions>): void => {
|
|
62
|
-
const
|
|
86
|
+
const incoming = opt || {};
|
|
87
|
+
const option = { ...defaultInstallOpt, ...incoming };
|
|
88
|
+
const formOpt = incoming as FormInstallOptions;
|
|
63
89
|
|
|
64
|
-
app.use(designPlugin,
|
|
65
|
-
app.use(formPlugin,
|
|
90
|
+
app.use(designPlugin, incoming);
|
|
91
|
+
app.use(formPlugin, {
|
|
92
|
+
...formOpt,
|
|
93
|
+
fields: mergeFieldOptions(editorFields, editorFieldVue, formOpt.fields),
|
|
94
|
+
});
|
|
66
95
|
app.use(tablePlugin);
|
|
67
96
|
|
|
68
97
|
app.config.globalProperties.$TMAGIC_EDITOR = option;
|
|
69
98
|
setEditorConfig(option);
|
|
70
|
-
|
|
71
99
|
app.component(`${Editor.name || 'MEditor'}`, Editor);
|
|
72
100
|
app.component('magic-code-editor', CodeEditor);
|
|
73
|
-
app.component('m-fields-ui-select', uiSelect);
|
|
74
|
-
app.component('m-fields-code-link', CodeLink);
|
|
75
|
-
app.component('m-fields-vs-code', Code);
|
|
76
|
-
app.component('m-fields-code-select', CodeSelect);
|
|
77
|
-
app.component('m-fields-code-select-col', CodeSelectCol);
|
|
78
|
-
app.component('m-fields-event-select', EventSelect);
|
|
79
|
-
app.component('m-fields-data-source-fields', DataSourceFields);
|
|
80
|
-
app.component('m-fields-data-source-mocks', DataSourceMocks);
|
|
81
|
-
app.component('m-fields-key-value', KeyValue);
|
|
82
|
-
app.component('m-fields-data-source-input', DataSourceInput);
|
|
83
|
-
app.component('m-fields-data-source-select', DataSourceSelect);
|
|
84
|
-
app.component('m-fields-data-source-methods', DataSourceMethods);
|
|
85
|
-
app.component('m-fields-data-source-method-select', DataSourceMethodSelect);
|
|
86
|
-
app.component('m-fields-data-source-field-select', DataSourceFieldSelect);
|
|
87
|
-
app.component('m-fields-page-fragment-select', PageFragmentSelect);
|
|
88
|
-
app.component('m-fields-display-conds', DisplayConds);
|
|
89
|
-
app.component('m-fields-cond-op-select', CondOpSelect);
|
|
90
|
-
app.component('m-form-style-setter', StyleSetter);
|
|
91
101
|
},
|
|
92
102
|
};
|
|
@@ -85,6 +85,7 @@ class CodeBlock extends BaseService {
|
|
|
85
85
|
public async setCodeDsl(codeDsl: CodeBlockDSL): Promise<void> {
|
|
86
86
|
this.state.codeDsl = codeDsl;
|
|
87
87
|
this.emit('code-dsl-change', this.state.codeDsl);
|
|
88
|
+
this.emit('change', this.state.codeDsl);
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
/**
|
|
@@ -199,6 +200,7 @@ class CodeBlock extends BaseService {
|
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
this.emit('addOrUpdate', id, codeDsl[id]);
|
|
203
|
+
this.emit('change', this.getCodeDsl());
|
|
202
204
|
}
|
|
203
205
|
|
|
204
206
|
/**
|
|
@@ -318,6 +320,8 @@ class CodeBlock extends BaseService {
|
|
|
318
320
|
|
|
319
321
|
this.emit('remove', id);
|
|
320
322
|
});
|
|
323
|
+
|
|
324
|
+
this.emit('change', this.getCodeDsl());
|
|
321
325
|
}
|
|
322
326
|
|
|
323
327
|
// #region AndGetHistoryId
|
|
@@ -147,6 +147,7 @@ class DataSource extends BaseService {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
this.emit('add', newConfig);
|
|
150
|
+
this.emit('change', this.get('dataSources'));
|
|
150
151
|
|
|
151
152
|
return newConfig;
|
|
152
153
|
}
|
|
@@ -192,6 +193,7 @@ class DataSource extends BaseService {
|
|
|
192
193
|
oldConfig,
|
|
193
194
|
changeRecords,
|
|
194
195
|
});
|
|
196
|
+
this.emit('change', this.get('dataSources'));
|
|
195
197
|
|
|
196
198
|
return newConfig;
|
|
197
199
|
}
|
|
@@ -220,6 +222,7 @@ class DataSource extends BaseService {
|
|
|
220
222
|
}
|
|
221
223
|
|
|
222
224
|
this.emit('remove', id);
|
|
225
|
+
this.emit('change', this.get('dataSources'));
|
|
223
226
|
}
|
|
224
227
|
|
|
225
228
|
// #region AndGetHistoryId
|
package/src/services/dep.ts
CHANGED
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { reactive, shallowReactive } from 'vue';
|
|
19
19
|
import { throttle } from 'lodash-es';
|
|
20
|
-
import serialize from 'serialize-javascript';
|
|
21
20
|
|
|
22
|
-
import type { DepData, DepExtendedData, Id, MApp, MNode, Target
|
|
21
|
+
import type { DepData, DepExtendedData, Id, MApp, MNode, Target } from '@tmagic/core';
|
|
23
22
|
import { DepTargetType, traverseTarget, Watcher } from '@tmagic/core';
|
|
24
23
|
import { isPage } from '@tmagic/utils';
|
|
25
24
|
|
|
25
|
+
import { CollectWorkerClient } from '@editor/utils/dep/collect-worker-client';
|
|
26
26
|
import { IdleTask } from '@editor/utils/dep/idle-task';
|
|
27
|
-
import
|
|
27
|
+
import type { DepsData } from '@editor/utils/dep/worker';
|
|
28
28
|
|
|
29
29
|
import BaseService from './BaseService';
|
|
30
30
|
|
|
@@ -42,18 +42,42 @@ interface State {
|
|
|
42
42
|
|
|
43
43
|
type StateKey = keyof State;
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* 一次 collectIdle 调用对应一个批次。批次自行统计入队/完成的任务数,在自身任务全部完成或被中断时
|
|
47
|
+
* 结算对应的 Promise,避免多次快速触发时共用 idleTask 的 finish 事件造成的串扰、提前 resolve,
|
|
48
|
+
* 以及 clearTasks 后 Promise 永不 resolve(collecting 卡死、监听器泄漏)。
|
|
49
|
+
*/
|
|
50
|
+
interface CollectBatch {
|
|
51
|
+
nodes: MNode[];
|
|
52
|
+
deep: boolean;
|
|
53
|
+
pending: number;
|
|
54
|
+
dsPending: number;
|
|
55
|
+
collectedEmitted: boolean;
|
|
56
|
+
dsSettled: boolean;
|
|
57
|
+
aborted: boolean;
|
|
58
|
+
resolve: (completed: boolean) => void;
|
|
59
|
+
}
|
|
60
|
+
|
|
45
61
|
class Dep extends BaseService {
|
|
46
62
|
private state = shallowReactive<State>({
|
|
47
63
|
collecting: false,
|
|
48
64
|
taskLength: 0,
|
|
49
65
|
});
|
|
50
66
|
|
|
51
|
-
private idleTask = new IdleTask<
|
|
67
|
+
private idleTask = new IdleTask<void>();
|
|
68
|
+
|
|
69
|
+
private collectWorker = new CollectWorkerClient();
|
|
52
70
|
|
|
53
71
|
private watcher = new Watcher({ initialTargets: reactive({}) });
|
|
54
72
|
|
|
55
73
|
private waitingWorker?: Promise<void>;
|
|
56
74
|
|
|
75
|
+
private resolveWaitingWorker?: () => void;
|
|
76
|
+
|
|
77
|
+
private workerGeneration = 0;
|
|
78
|
+
|
|
79
|
+
private activeBatches = new Set<CollectBatch>();
|
|
80
|
+
|
|
57
81
|
constructor() {
|
|
58
82
|
super();
|
|
59
83
|
|
|
@@ -132,56 +156,77 @@ class Dep extends BaseService {
|
|
|
132
156
|
this.emit('ds-collected', nodes, deep);
|
|
133
157
|
}
|
|
134
158
|
|
|
159
|
+
/**
|
|
160
|
+
* 空闲收集依赖
|
|
161
|
+
*
|
|
162
|
+
* 遍历匹配是整个收集过程中最耗时的部分(要深度遍历节点树并对每个属性做 target 匹配),
|
|
163
|
+
* 节点/数据源多时在主线程执行会长时间卡死页面,因此优先交给 worker 执行,主线程只负责把结果写回 target。
|
|
164
|
+
* 自定义 target 的 isTarget 是无法跨线程传递的闭包函数(没有 descriptor),仍走主线程空闲队列;
|
|
165
|
+
* worker 不可用(如 SSR)或执行失败时也会回退到主线程空闲队列。
|
|
166
|
+
*/
|
|
135
167
|
public async collectIdle(nodes: MNode[], depExtendedData: DepExtendedData = {}, deep = false, type?: DepTargetType) {
|
|
136
168
|
if (this.waitingWorker) {
|
|
137
169
|
await this.waitingWorker;
|
|
138
170
|
}
|
|
139
171
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
172
|
+
const batch: CollectBatch = {
|
|
173
|
+
nodes,
|
|
174
|
+
deep,
|
|
175
|
+
pending: 0,
|
|
176
|
+
dsPending: 0,
|
|
177
|
+
collectedEmitted: false,
|
|
178
|
+
dsSettled: false,
|
|
179
|
+
aborted: false,
|
|
180
|
+
resolve: () => {},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const workerTargets: Target[] = [];
|
|
184
|
+
|
|
185
|
+
for (const target of this.watcher.getCollectableTargets(type)) {
|
|
186
|
+
if (target.descriptor && this.collectWorker.isSupported) {
|
|
187
|
+
workerTargets.push(target);
|
|
188
|
+
} else {
|
|
189
|
+
this.enqueueTasks(nodes, target, depExtendedData, deep, batch);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
144
192
|
|
|
145
|
-
|
|
146
|
-
|
|
193
|
+
if (workerTargets.length && nodes.length) {
|
|
194
|
+
this.collectByCollectWorker(nodes, workerTargets, depExtendedData, deep, batch);
|
|
195
|
+
}
|
|
147
196
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
this.emit('ds-collected', nodes, deep);
|
|
161
|
-
resolve();
|
|
162
|
-
});
|
|
197
|
+
// 没有命中任何 target,无需收集,直接完成
|
|
198
|
+
if (batch.pending === 0) {
|
|
199
|
+
this.emit('collected', nodes, deep);
|
|
200
|
+
this.updateCollectingState();
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.activeBatches.add(batch);
|
|
205
|
+
this.set('collecting', true);
|
|
206
|
+
|
|
207
|
+
return new Promise<boolean>((resolve) => {
|
|
208
|
+
batch.resolve = resolve;
|
|
163
209
|
});
|
|
164
210
|
}
|
|
165
211
|
|
|
166
212
|
public collectByWorker(dsl: MApp) {
|
|
167
213
|
this.set('collecting', true);
|
|
214
|
+
this.workerGeneration += 1;
|
|
215
|
+
const generation = this.workerGeneration;
|
|
168
216
|
|
|
169
217
|
const { promise, resolve: waitingResolve } = Promise.withResolvers<void>();
|
|
170
218
|
|
|
171
219
|
this.waitingWorker = promise;
|
|
220
|
+
this.resolveWaitingWorker = waitingResolve;
|
|
221
|
+
|
|
222
|
+
return this.collectWorker.collectDsl(dsl).then((deps) => {
|
|
223
|
+
const depsData: DepsData = deps || {};
|
|
224
|
+
|
|
225
|
+
if (generation !== this.workerGeneration) {
|
|
226
|
+
waitingResolve();
|
|
227
|
+
return depsData;
|
|
228
|
+
}
|
|
172
229
|
|
|
173
|
-
return new Promise<Record<string, Record<string, DepData>>>((resolve) => {
|
|
174
|
-
const worker = new Work();
|
|
175
|
-
worker.postMessage({
|
|
176
|
-
dsl: serialize(dsl),
|
|
177
|
-
});
|
|
178
|
-
worker.onmessage = (e) => {
|
|
179
|
-
resolve(e.data);
|
|
180
|
-
};
|
|
181
|
-
worker.onerror = () => {
|
|
182
|
-
resolve({});
|
|
183
|
-
};
|
|
184
|
-
}).then((depsData) => {
|
|
185
230
|
traverseTarget(this.watcher.getTargetsList(), (target) => {
|
|
186
231
|
if (depsData[target.type]?.[target.id]) {
|
|
187
232
|
target.deps = reactive(depsData[target.type][target.id]);
|
|
@@ -200,6 +245,10 @@ class Dep extends BaseService {
|
|
|
200
245
|
this.emit('collected', dsl.items, true);
|
|
201
246
|
this.emit('ds-collected', dsl.items, true);
|
|
202
247
|
waitingResolve();
|
|
248
|
+
if (this.waitingWorker === promise) {
|
|
249
|
+
this.waitingWorker = undefined;
|
|
250
|
+
this.resolveWaitingWorker = undefined;
|
|
251
|
+
}
|
|
203
252
|
|
|
204
253
|
return depsData;
|
|
205
254
|
});
|
|
@@ -209,8 +258,12 @@ class Dep extends BaseService {
|
|
|
209
258
|
// 先删除原有依赖,重新收集
|
|
210
259
|
if (isPage(node)) {
|
|
211
260
|
this.removePageDep(target, depExtendedData);
|
|
212
|
-
} else {
|
|
261
|
+
} else if (deep) {
|
|
262
|
+
// deep 收集会覆盖整棵子树,删除也要同步清掉子孙旧依赖
|
|
213
263
|
this.watcher.removeTargetDep(target, node);
|
|
264
|
+
} else {
|
|
265
|
+
// 非 deep 只动当前节点,避免误清子节点上其他尚未重收的依赖
|
|
266
|
+
target.removeDep(node.id);
|
|
214
267
|
}
|
|
215
268
|
|
|
216
269
|
this.watcher.collectItem(node, target, depExtendedData, deep);
|
|
@@ -233,7 +286,10 @@ class Dep extends BaseService {
|
|
|
233
286
|
}
|
|
234
287
|
|
|
235
288
|
public clearIdleTasks() {
|
|
289
|
+
this.abortActiveBatches();
|
|
236
290
|
this.idleTask.clearTasks();
|
|
291
|
+
// 丢掉 worker 在途任务,避免 abort 后的长任务继续占着常驻 worker
|
|
292
|
+
this.collectWorker.abort();
|
|
237
293
|
}
|
|
238
294
|
|
|
239
295
|
public on<Name extends keyof DepEvents, Param extends DepEvents[Name]>(
|
|
@@ -251,7 +307,13 @@ class Dep extends BaseService {
|
|
|
251
307
|
}
|
|
252
308
|
|
|
253
309
|
public reset() {
|
|
310
|
+
this.abortActiveBatches();
|
|
311
|
+
this.workerGeneration += 1;
|
|
312
|
+
this.resolveWaitingWorker?.();
|
|
313
|
+
this.resolveWaitingWorker = undefined;
|
|
314
|
+
this.waitingWorker = undefined;
|
|
254
315
|
this.idleTask.clearTasks();
|
|
316
|
+
this.collectWorker.abort();
|
|
255
317
|
|
|
256
318
|
for (const type of Object.keys(this.watcher.getTargetsList())) {
|
|
257
319
|
this.removeTargets(type);
|
|
@@ -267,6 +329,7 @@ class Dep extends BaseService {
|
|
|
267
329
|
this.reset();
|
|
268
330
|
this.removeAllPlugins();
|
|
269
331
|
this.idleTask.removeAllListeners();
|
|
332
|
+
this.collectWorker.terminate();
|
|
270
333
|
}
|
|
271
334
|
|
|
272
335
|
public emit<Name extends keyof DepEvents, Param extends DepEvents[Name]>(eventName: Name, ...args: Param) {
|
|
@@ -286,25 +349,207 @@ class Dep extends BaseService {
|
|
|
286
349
|
}
|
|
287
350
|
}
|
|
288
351
|
|
|
289
|
-
|
|
352
|
+
/**
|
|
353
|
+
* 把遍历匹配交给 worker,结果回来后按 target 分片写回主线程
|
|
354
|
+
*/
|
|
355
|
+
private collectByCollectWorker(
|
|
356
|
+
nodes: MNode[],
|
|
357
|
+
targets: Target[],
|
|
358
|
+
depExtendedData: DepExtendedData,
|
|
359
|
+
deep: boolean,
|
|
360
|
+
batch: CollectBatch,
|
|
361
|
+
) {
|
|
362
|
+
const hasDataSource = targets.some((target) => target.type === DepTargetType.DATA_SOURCE);
|
|
363
|
+
|
|
364
|
+
// 先占位,避免 worker 返回前批次被误判为已完成(提前 resolve、collecting 提前复位)
|
|
365
|
+
this.beginBatchTask(batch, hasDataSource);
|
|
366
|
+
|
|
367
|
+
this.collectWorker
|
|
368
|
+
.collect({
|
|
369
|
+
nodes,
|
|
370
|
+
targets: targets.map((target) => target.descriptor!),
|
|
371
|
+
depExtendedData,
|
|
372
|
+
deep,
|
|
373
|
+
})
|
|
374
|
+
.then((result) => {
|
|
375
|
+
if (batch.aborted) return;
|
|
376
|
+
|
|
377
|
+
for (const target of targets) {
|
|
378
|
+
if (result) {
|
|
379
|
+
// 写回是纯字典操作,但数据量大时同样会占用主线程,因此按 target 拆成空闲任务
|
|
380
|
+
this.enqueueApplyTask(target, result.deps[target.type]?.[target.id] || {}, result.nodeIds, batch, {
|
|
381
|
+
nodes,
|
|
382
|
+
depExtendedData,
|
|
383
|
+
deep,
|
|
384
|
+
});
|
|
385
|
+
} else {
|
|
386
|
+
this.enqueueTasks(nodes, target, depExtendedData, deep, batch);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
})
|
|
390
|
+
.finally(() => {
|
|
391
|
+
// 释放占位:必须在新任务入队之后,否则批次会在中途被判定为完成
|
|
392
|
+
this.onBatchTaskDone(batch, hasDataSource);
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* 用 worker 的收集结果替换 target 上这批节点的依赖
|
|
398
|
+
*/
|
|
399
|
+
private enqueueApplyTask(
|
|
400
|
+
target: Target,
|
|
401
|
+
deps: DepData,
|
|
402
|
+
nodeIds: Id[],
|
|
403
|
+
batch: CollectBatch,
|
|
404
|
+
{ nodes, depExtendedData, deep }: { nodes: MNode[]; depExtendedData: DepExtendedData; deep: boolean },
|
|
405
|
+
) {
|
|
406
|
+
const isDataSource = target.type === DepTargetType.DATA_SOURCE;
|
|
407
|
+
|
|
408
|
+
this.beginBatchTask(batch, isDataSource);
|
|
409
|
+
|
|
290
410
|
this.idleTask.enqueueTask(
|
|
291
|
-
(
|
|
292
|
-
|
|
411
|
+
() => {
|
|
412
|
+
try {
|
|
413
|
+
// target 可能在 worker 收集期间被移除或重建(如修改数据源字段)
|
|
414
|
+
const current = this.watcher.getTarget(target.id, target.type);
|
|
415
|
+
if (current !== target) {
|
|
416
|
+
// 已被同 id 的新 target 替换时,用当前 target 在主线程补收,避免依赖空窗
|
|
417
|
+
if (current) {
|
|
418
|
+
this.enqueueTasks(nodes, current, depExtendedData, deep, batch);
|
|
419
|
+
}
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// 页面按 pageId 匹配删除,可清掉页面内已被删除节点的残留依赖
|
|
424
|
+
if (nodes.some((node) => isPage(node))) {
|
|
425
|
+
this.removePageDep(target, depExtendedData);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
for (const id of nodeIds) {
|
|
429
|
+
target.removeDep(id);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
for (const [id, dep] of Object.entries(deps)) {
|
|
433
|
+
target.deps[id] = dep;
|
|
434
|
+
}
|
|
435
|
+
} finally {
|
|
436
|
+
this.onBatchTaskDone(batch, isDataSource);
|
|
437
|
+
}
|
|
293
438
|
},
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
439
|
+
undefined,
|
|
440
|
+
isDataSource,
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
private enqueueTasks(
|
|
445
|
+
nodes: MNode[],
|
|
446
|
+
target: Target,
|
|
447
|
+
depExtendedData: DepExtendedData,
|
|
448
|
+
deep: boolean,
|
|
449
|
+
batch: CollectBatch,
|
|
450
|
+
) {
|
|
451
|
+
for (const node of nodes) {
|
|
452
|
+
this.enqueueTask(node, target, depExtendedData, deep, batch);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
private enqueueTask(
|
|
457
|
+
node: MNode,
|
|
458
|
+
target: Target,
|
|
459
|
+
depExtendedData: DepExtendedData,
|
|
460
|
+
deep: boolean,
|
|
461
|
+
batch: CollectBatch,
|
|
462
|
+
) {
|
|
463
|
+
const isDataSource = target.type === DepTargetType.DATA_SOURCE;
|
|
464
|
+
|
|
465
|
+
this.beginBatchTask(batch, isDataSource);
|
|
466
|
+
|
|
467
|
+
this.idleTask.enqueueTask(
|
|
468
|
+
() => {
|
|
469
|
+
try {
|
|
470
|
+
this.collectNode(node, target, depExtendedData);
|
|
471
|
+
} finally {
|
|
472
|
+
this.onBatchTaskDone(batch, isDataSource);
|
|
473
|
+
}
|
|
298
474
|
},
|
|
299
|
-
|
|
475
|
+
undefined,
|
|
476
|
+
isDataSource,
|
|
300
477
|
);
|
|
301
478
|
|
|
302
479
|
if (deep && Array.isArray(node.items) && node.items.length) {
|
|
303
480
|
node.items.forEach((item) => {
|
|
304
|
-
this.enqueueTask(item, target, depExtendedData, deep);
|
|
481
|
+
this.enqueueTask(item, target, depExtendedData, deep, batch);
|
|
305
482
|
});
|
|
306
483
|
}
|
|
307
484
|
}
|
|
485
|
+
|
|
486
|
+
private beginBatchTask(batch: CollectBatch, isDataSource: boolean) {
|
|
487
|
+
batch.pending += 1;
|
|
488
|
+
if (isDataSource) {
|
|
489
|
+
batch.dsPending += 1;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
private onBatchTaskDone(batch: CollectBatch, isDataSource: boolean) {
|
|
494
|
+
if (batch.aborted) return;
|
|
495
|
+
|
|
496
|
+
if (isDataSource) {
|
|
497
|
+
batch.dsPending -= 1;
|
|
498
|
+
// 数据源依赖收集完先 resolve,让 stage 尽快更新,其余依赖继续在后台收集
|
|
499
|
+
if (batch.dsPending === 0) {
|
|
500
|
+
this.settleBatchDs(batch);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
batch.pending -= 1;
|
|
505
|
+
if (batch.pending === 0) {
|
|
506
|
+
this.finishBatch(batch);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
private settleBatchDs(batch: CollectBatch) {
|
|
511
|
+
if (batch.dsSettled) return;
|
|
512
|
+
batch.dsSettled = true;
|
|
513
|
+
this.emit('ds-collected', batch.nodes, batch.deep);
|
|
514
|
+
batch.resolve(true);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
private finishBatch(batch: CollectBatch) {
|
|
518
|
+
if (!batch.collectedEmitted) {
|
|
519
|
+
batch.collectedEmitted = true;
|
|
520
|
+
this.emit('collected', batch.nodes, batch.deep);
|
|
521
|
+
}
|
|
522
|
+
// 没有数据源任务的批次在此结算 Promise
|
|
523
|
+
this.settleBatchDs(batch);
|
|
524
|
+
this.activeBatches.delete(batch);
|
|
525
|
+
this.updateCollectingState();
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* idleTask 被清空时,在途批次的任务不会再执行,必须主动结算,
|
|
530
|
+
* 否则对应的 collectIdle Promise 永远不会 resolve(collecting 卡在 true、once 监听器泄漏)。
|
|
531
|
+
* 收集被中断(通常紧跟一次全量重新收集),因此不再 emit collected/ds-collected,仅结算 Promise。
|
|
532
|
+
*/
|
|
533
|
+
private abortActiveBatches() {
|
|
534
|
+
if (!this.activeBatches.size) {
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const batches = [...this.activeBatches];
|
|
539
|
+
this.activeBatches.clear();
|
|
540
|
+
|
|
541
|
+
for (const batch of batches) {
|
|
542
|
+
// 标记中断:worker 结果可能在之后才返回,此时不能再写回依赖,也不能再结算批次
|
|
543
|
+
batch.aborted = true;
|
|
544
|
+
batch.resolve(false);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
this.updateCollectingState();
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
private updateCollectingState() {
|
|
551
|
+
this.set('collecting', this.activeBatches.size > 0);
|
|
552
|
+
}
|
|
308
553
|
}
|
|
309
554
|
|
|
310
555
|
export type DepService = Dep;
|