@nocobase/flow-engine 2.0.0-alpha.2 → 2.0.0-alpha.20
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/lib/BlockScopedFlowEngine.d.ts +23 -0
- package/lib/BlockScopedFlowEngine.js +90 -0
- package/lib/FlowContextProvider.d.ts +2 -2
- package/lib/FlowContextProvider.js +3 -3
- package/lib/FlowDefinition.d.ts +2 -2
- package/lib/JSRunner.js +3 -0
- package/lib/ViewScopedFlowEngine.d.ts +1 -1
- package/lib/components/FieldModelRenderer.js +10 -4
- package/lib/components/FieldSkeleton.d.ts +10 -0
- package/lib/components/FieldSkeleton.js +64 -0
- package/lib/components/FlowContextSelector.js +7 -2
- package/lib/components/FlowModelRenderer.d.ts +2 -5
- package/lib/components/FlowModelRenderer.js +16 -47
- package/lib/components/FormItem.js +5 -1
- package/lib/{runjs-context/snippets/global/requireAsync.snippet.d.ts → components/dnd/findModelUidPosition.d.ts} +4 -7
- package/lib/{runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js → components/dnd/findModelUidPosition.js} +23 -19
- package/lib/components/dnd/gridDragPlanner.d.ts +130 -0
- package/lib/components/dnd/gridDragPlanner.js +497 -0
- package/lib/components/dnd/index.d.ts +2 -2
- package/lib/components/dnd/index.js +5 -5
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +7 -1
- package/lib/components/variables/VariableInput.js +16 -2
- package/lib/components/variables/VariableTag.js +43 -2
- package/lib/components/variables/types.d.ts +2 -0
- package/lib/data-source/index.d.ts +12 -4
- package/lib/data-source/index.js +18 -12
- package/lib/data-source/sortCollectionsByInherits.d.ts +10 -0
- package/lib/data-source/sortCollectionsByInherits.js +71 -0
- package/lib/executor/FlowExecutor.d.ts +4 -5
- package/lib/executor/FlowExecutor.js +122 -94
- package/lib/flowContext.d.ts +33 -5
- package/lib/flowContext.js +145 -74
- package/lib/flowEngine.d.ts +8 -1
- package/lib/flowEngine.js +12 -2
- package/lib/flowSettings.d.ts +2 -1
- package/lib/flowSettings.js +7 -3
- package/lib/hooks/useApplyAutoFlows.js +2 -1
- package/lib/index.d.ts +6 -1
- package/lib/index.js +29 -3
- package/lib/models/CollectionFieldModel.d.ts +2 -0
- package/lib/models/CollectionFieldModel.js +43 -3
- package/lib/models/flowModel.d.ts +28 -29
- package/lib/models/flowModel.js +110 -88
- package/lib/models/forkFlowModel.d.ts +2 -2
- package/lib/models/forkFlowModel.js +29 -6
- package/lib/provider.d.ts +3 -1
- package/lib/provider.js +7 -5
- package/lib/resources/multiRecordResource.js +2 -0
- package/lib/resources/singleRecordResource.js +1 -0
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +27 -20
- package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSBlockRunJSContext.js +46 -33
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +1 -2
- package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +14 -15
- package/lib/runjs-context/contexts/{LinkageRunJSContext.d.ts → JSColumnRunJSContext.d.ts} +6 -3
- package/lib/runjs-context/contexts/JSColumnRunJSContext.js +78 -0
- package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSFieldRunJSContext.js +28 -24
- package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +1 -6
- package/lib/runjs-context/contexts/JSItemRunJSContext.js +24 -20
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +1 -2
- package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +16 -17
- package/lib/runjs-context/contexts/base.d.ts +9 -0
- package/lib/runjs-context/contexts/base.js +169 -0
- package/lib/runjs-context/helpers.d.ts +5 -2
- package/lib/runjs-context/helpers.js +36 -27
- package/lib/runjs-context/registry.d.ts +7 -4
- package/lib/runjs-context/registry.js +10 -42
- package/lib/runjs-context/setup.d.ts +9 -0
- package/lib/runjs-context/setup.js +82 -0
- package/lib/runjs-context/snippets/global/{copy-record-json.snippet.js → api-request.snippet.js} +25 -10
- package/lib/runjs-context/snippets/global/clipboard-copy-text.snippet.js +61 -0
- package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.js → import-esm.snippet.js} +26 -12
- package/lib/runjs-context/snippets/global/message-error.snippet.js +6 -0
- package/lib/runjs-context/snippets/global/message-success.snippet.js +6 -0
- package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +3 -8
- package/lib/runjs-context/snippets/global/notification-open.snippet.js +8 -1
- package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +10 -3
- package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +10 -3
- package/lib/runjs-context/snippets/global/query-selector.snippet.js +53 -0
- package/lib/runjs-context/snippets/global/require-amd.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/global/{requireAsync.snippet.js → require-amd.snippet.js} +16 -13
- package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +3 -8
- package/lib/runjs-context/snippets/global/window-open.snippet.js +8 -1
- package/lib/runjs-context/snippets/index.d.ts +14 -3
- package/lib/runjs-context/snippets/index.js +160 -40
- package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +99 -0
- package/lib/runjs-context/snippets/{libs → scene/block}/echarts-init.snippet.js +24 -7
- package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/render-button-handler.snippet.js +12 -6
- package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +57 -0
- package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.js +72 -0
- package/lib/runjs-context/snippets/scene/block/render-react.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock → block}/render-react.snippet.js +12 -11
- package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +100 -0
- package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +85 -0
- package/lib/runjs-context/snippets/scene/block/resource-example.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +60 -0
- package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +283 -0
- package/lib/runjs-context/snippets/scene/block/vue-component.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +124 -0
- package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/color-by-value.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/{global → scene/detail}/copy-to-clipboard.snippet.js +28 -6
- package/lib/runjs-context/snippets/scene/detail/format-number.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/format-number.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsfield → detail}/innerHTML-value.snippet.js +13 -3
- package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +82 -0
- package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +80 -0
- package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +74 -0
- package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.js +63 -0
- package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +81 -0
- package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.js +74 -0
- package/lib/runjs-context/snippets/scene/form/render-basic.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/set-required.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.js +67 -0
- package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.js +12 -3
- package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.js +11 -2
- package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +79 -0
- package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/{global/log-json-record.snippet.js → scene/table/destroy-selected.snippet.js} +24 -11
- package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.js +64 -0
- package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.js +11 -2
- package/lib/runjs-context/snippets/types.d.ts +9 -1
- package/lib/types.d.ts +15 -3
- package/lib/types.js +4 -3
- package/lib/utils/buildSettingsViewInputArgs.d.ts +19 -0
- package/lib/utils/buildSettingsViewInputArgs.js +75 -0
- package/lib/utils/index.d.ts +3 -2
- package/lib/utils/index.js +5 -2
- package/lib/utils/params-resolvers.js +2 -2
- package/lib/utils/safeGlobals.d.ts +5 -3
- package/lib/utils/safeGlobals.js +40 -0
- package/lib/utils/serverContextParams.d.ts +1 -0
- package/lib/utils/variablesParams.d.ts +9 -5
- package/lib/utils/variablesParams.js +47 -36
- package/lib/views/PageComponent.js +2 -1
- package/lib/views/createViewMeta.d.ts +29 -1
- package/lib/views/createViewMeta.js +321 -72
- package/lib/views/index.d.ts +1 -0
- package/lib/views/index.js +3 -0
- package/lib/views/useDialog.d.ts +8 -8
- package/lib/views/useDialog.js +8 -7
- package/lib/views/useDrawer.d.ts +8 -8
- package/lib/views/useDrawer.js +40 -26
- package/lib/views/usePage.d.ts +8 -8
- package/lib/views/usePage.js +8 -7
- package/package.json +4 -3
- package/src/BlockScopedFlowEngine.ts +86 -0
- package/src/FlowContextProvider.tsx +4 -2
- package/src/JSRunner.ts +3 -0
- package/src/ViewScopedFlowEngine.ts +1 -1
- package/src/__tests__/JSRunner.test.ts +62 -53
- package/src/__tests__/blockScopedFlowEngine.test.ts +154 -0
- package/src/__tests__/flow-engine.test.ts +3 -0
- package/src/__tests__/flowContextCreateJSRunner.test.ts +163 -0
- package/src/__tests__/flowEngine.saveModel.test.ts +4 -0
- package/src/__tests__/flowRunJSContextDefine.test.ts +508 -0
- package/src/__tests__/globalFlowRegistry.test.ts +1 -1
- package/src/__tests__/runjsContext.test.ts +216 -35
- package/src/__tests__/runjsContextImplementations.test.ts +217 -0
- package/src/__tests__/runjsContextRuntime.test.ts +269 -0
- package/src/__tests__/runjsEdgeCases.test.ts +281 -0
- package/src/__tests__/runjsLocales.test.ts +36 -0
- package/src/__tests__/runjsRuntimeFeatures.test.ts +449 -0
- package/src/__tests__/runjsSnippets.test.ts +140 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +3 -3
- package/src/components/DynamicFlowsEditor.tsx +3 -4
- package/src/components/FieldModelRenderer.tsx +16 -5
- package/src/components/FieldSkeleton.tsx +27 -0
- package/src/components/FlowContextSelector.tsx +6 -2
- package/src/components/FlowModelRenderer.tsx +30 -78
- package/src/components/FormItem.tsx +8 -1
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +5 -5
- package/src/components/__tests__/gridDragPlanner.test.ts +494 -0
- package/src/components/dnd/README.md +149 -0
- package/src/components/dnd/findModelUidPosition.ts +26 -0
- package/src/components/dnd/gridDragPlanner.ts +659 -0
- package/src/components/dnd/index.tsx +3 -3
- package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +14 -1
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +1 -0
- package/src/components/variables/VariableInput.tsx +22 -2
- package/src/components/variables/VariableTag.tsx +54 -2
- package/src/components/variables/types.ts +2 -0
- package/src/data-source/__tests__/sortCollectionsByInherits.test.ts +125 -0
- package/src/data-source/index.ts +16 -10
- package/src/data-source/sortCollectionsByInherits.ts +61 -0
- package/src/executor/FlowExecutor.ts +160 -114
- package/src/executor/__tests__/flowExecutor.test.ts +151 -5
- package/src/flowContext.ts +196 -93
- package/src/flowEngine.ts +13 -2
- package/src/flowSettings.ts +8 -3
- package/src/hooks/useApplyAutoFlows.ts +3 -1
- package/src/index.ts +11 -1
- package/src/models/CollectionFieldModel.tsx +43 -4
- package/src/models/__tests__/flowModel.getFlows.sort.test.ts +4 -4
- package/src/models/__tests__/flowModel.test.ts +218 -95
- package/src/models/flowModel.tsx +146 -122
- package/src/models/forkFlowModel.ts +37 -5
- package/src/provider.tsx +10 -7
- package/src/resources/multiRecordResource.ts +2 -0
- package/src/resources/singleRecordResource.ts +1 -0
- package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +28 -21
- package/src/runjs-context/contexts/JSBlockRunJSContext.ts +46 -34
- package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +15 -16
- package/src/runjs-context/contexts/JSColumnRunJSContext.ts +58 -0
- package/src/runjs-context/contexts/JSFieldRunJSContext.ts +30 -25
- package/src/runjs-context/contexts/JSItemRunJSContext.ts +25 -21
- package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +17 -18
- package/src/runjs-context/contexts/base.ts +155 -0
- package/src/runjs-context/helpers.ts +32 -30
- package/src/runjs-context/registry.ts +16 -47
- package/src/runjs-context/setup.ts +51 -0
- package/src/runjs-context/snippets/global/api-request.snippet.ts +38 -0
- package/src/runjs-context/snippets/global/clipboard-copy-text.snippet.ts +42 -0
- package/src/runjs-context/snippets/global/import-esm.snippet.ts +39 -0
- package/src/runjs-context/snippets/global/message-error.snippet.ts +6 -0
- package/src/runjs-context/snippets/global/message-success.snippet.ts +6 -0
- package/src/runjs-context/snippets/global/notification-open.snippet.ts +11 -1
- package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +10 -3
- package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +10 -3
- package/src/runjs-context/snippets/global/query-selector.snippet.ts +34 -0
- package/src/runjs-context/snippets/global/require-amd.snippet.ts +30 -0
- package/src/runjs-context/snippets/global/window-open.snippet.ts +11 -1
- package/src/runjs-context/snippets/index.ts +176 -39
- package/src/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +80 -0
- package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +44 -0
- package/src/runjs-context/snippets/scene/{jsblock → block}/render-button-handler.snippet.ts +15 -6
- package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/block/render-info-card.snippet.ts +53 -0
- package/src/runjs-context/snippets/scene/{jsblock → block}/render-react.snippet.ts +15 -11
- package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +81 -0
- package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +66 -0
- package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +46 -0
- package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +264 -0
- package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +105 -0
- package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +33 -0
- package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +32 -0
- package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +31 -0
- package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +63 -0
- package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +61 -0
- package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +55 -0
- package/src/runjs-context/snippets/scene/form/calculate-total.snippet.ts +44 -0
- package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +62 -0
- package/src/runjs-context/snippets/scene/form/conditional-required.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/form/copy-field-values.snippet.ts +55 -0
- package/src/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.ts +48 -0
- package/src/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.ts +15 -3
- package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.ts +14 -2
- package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +60 -0
- package/src/runjs-context/snippets/scene/table/destroy-selected.snippet.ts +36 -0
- package/src/runjs-context/snippets/scene/table/export-selected-json.snippet.ts +45 -0
- package/src/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.ts +14 -2
- package/src/runjs-context/snippets/types.ts +5 -1
- package/src/types.ts +13 -0
- package/src/utils/__tests__/safeGlobals.test.ts +22 -1
- package/src/utils/buildSettingsViewInputArgs.ts +72 -0
- package/src/utils/index.ts +2 -2
- package/src/utils/params-resolvers.ts +1 -1
- package/src/utils/safeGlobals.ts +49 -3
- package/src/utils/serverContextParams.ts +1 -0
- package/src/utils/variablesParams.ts +50 -38
- package/src/views/PageComponent.tsx +1 -1
- package/src/views/createViewMeta.ts +372 -70
- package/src/views/index.tsx +1 -0
- package/src/views/useDialog.tsx +12 -10
- package/src/views/useDrawer.tsx +60 -36
- package/src/views/usePage.tsx +13 -10
- package/lib/components/dnd/getMousePositionOnElement.d.ts +0 -50
- package/lib/components/dnd/getMousePositionOnElement.js +0 -95
- package/lib/components/dnd/moveBlock.d.ts +0 -33
- package/lib/components/dnd/moveBlock.js +0 -302
- package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +0 -38
- package/lib/runjs-context/contexts/FlowRunJSContext.js +0 -217
- package/lib/runjs-context/contexts/LinkageRunJSContext.js +0 -62
- package/lib/runjs-context/index.d.ts +0 -19
- package/lib/runjs-context/index.js +0 -57
- package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/api-request-get.snippet.js +0 -42
- package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/api-request-post.snippet.js +0 -42
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/console-log-ctx.snippet.js +0 -41
- package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/sleep.snippet.js +0 -43
- package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +0 -16
- package/lib/runjs-context/snippets/global/try-catch-async.snippet.js +0 -44
- package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +0 -43
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +0 -40
- package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +0 -42
- package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +0 -41
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +0 -41
- package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.js +0 -45
- package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +0 -15
- package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +0 -15
- package/src/components/dnd/getMousePositionOnElement.ts +0 -115
- package/src/components/dnd/moveBlock.ts +0 -379
- package/src/runjs-context/contexts/FlowRunJSContext.ts +0 -190
- package/src/runjs-context/contexts/LinkageRunJSContext.ts +0 -35
- package/src/runjs-context/index.ts +0 -20
- package/src/runjs-context/snippets/global/api-request-get.snippet.ts +0 -20
- package/src/runjs-context/snippets/global/api-request-post.snippet.ts +0 -20
- package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +0 -19
- package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/log-json-record.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/requireAsync.snippet.ts +0 -24
- package/src/runjs-context/snippets/global/sleep.snippet.ts +0 -21
- package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +0 -22
- package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +0 -23
- package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +0 -21
- package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +0 -18
- package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +0 -20
- package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +0 -19
- package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +0 -30
- package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +0 -20
- package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +0 -19
- package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +0 -18
- /package/lib/runjs-context/snippets/global/{copy-record-json.snippet.d.ts → api-request.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{copy-to-clipboard.snippet.d.ts → clipboard-copy-text.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{log-json-record.snippet.d.ts → import-esm.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.d.ts → query-selector.snippet.d.ts} +0 -0
- /package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.d.ts → block/echarts-init.snippet.d.ts} +0 -0
|
@@ -7,18 +7,17 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
import { APIClient } from '@nocobase/sdk';
|
|
10
|
+
import { reaction } from '@nocobase/flow-engine';
|
|
12
11
|
import { render, waitFor } from '@testing-library/react';
|
|
13
12
|
import React from 'react';
|
|
14
13
|
import { vi } from 'vitest';
|
|
15
14
|
import { FlowModelRenderer } from '../../components/FlowModelRenderer';
|
|
15
|
+
import { FlowEngineProvider } from '../../provider';
|
|
16
16
|
import { FlowEngine } from '../../flowEngine';
|
|
17
|
-
import type { DefaultStructure, FlowDefinitionOptions, FlowModelOptions
|
|
17
|
+
import type { DefaultStructure, FlowDefinitionOptions, FlowModelOptions } from '../../types';
|
|
18
18
|
import { FlowExitException } from '../../utils';
|
|
19
19
|
import { FlowExitAllException } from '../../utils/exceptions';
|
|
20
|
-
import {
|
|
21
|
-
import { ForkFlowModel } from '../forkFlowModel';
|
|
20
|
+
import { FlowModel, ModelRenderMode } from '../flowModel';
|
|
22
21
|
|
|
23
22
|
// 全局处理测试中的未处理 Promise rejection
|
|
24
23
|
const originalUnhandledRejection = process.listeners('unhandledRejection');
|
|
@@ -392,7 +391,7 @@ describe('FlowModel', () => {
|
|
|
392
391
|
TestFlowModel.registerFlow(exitFlow2);
|
|
393
392
|
const loggerSpy = vi.spyOn(model.context.logger, 'info').mockImplementation(() => {});
|
|
394
393
|
|
|
395
|
-
await model.
|
|
394
|
+
await model.dispatchEvent('beforeRender');
|
|
396
395
|
|
|
397
396
|
expect(exitFlow.steps.step2.handler).not.toHaveBeenCalled();
|
|
398
397
|
expect(exitFlow2.steps.step2.handler).toHaveBeenCalled();
|
|
@@ -430,7 +429,7 @@ describe('FlowModel', () => {
|
|
|
430
429
|
TestFlowModel.registerFlow(exitFlow2);
|
|
431
430
|
const loggerSpy = vi.spyOn(model.context.logger, 'info').mockImplementation(() => {});
|
|
432
431
|
|
|
433
|
-
await model.
|
|
432
|
+
await model.dispatchEvent('beforeRender');
|
|
434
433
|
|
|
435
434
|
expect(exitFlow.steps.step2.handler).not.toHaveBeenCalled();
|
|
436
435
|
expect(exitFlow2.steps.step2.handler).not.toHaveBeenCalled();
|
|
@@ -530,7 +529,7 @@ describe('FlowModel', () => {
|
|
|
530
529
|
});
|
|
531
530
|
});
|
|
532
531
|
|
|
533
|
-
describe('
|
|
532
|
+
describe('beforeRender flows', () => {
|
|
534
533
|
test('should execute all auto flows', async () => {
|
|
535
534
|
const autoFlow1 = { ...createAutoFlowDefinition(), key: 'auto1', sort: 1 };
|
|
536
535
|
const autoFlow2 = { ...createAutoFlowDefinition(), key: 'auto2', sort: 2 };
|
|
@@ -540,7 +539,7 @@ describe('FlowModel', () => {
|
|
|
540
539
|
TestFlowModel.registerFlow(autoFlow2);
|
|
541
540
|
TestFlowModel.registerFlow(manualFlow);
|
|
542
541
|
|
|
543
|
-
const results = await model.
|
|
542
|
+
const results = await model.dispatchEvent('beforeRender');
|
|
544
543
|
|
|
545
544
|
expect(results).toHaveLength(2);
|
|
546
545
|
expect(autoFlow1.steps.autoStep.handler).toHaveBeenCalled();
|
|
@@ -594,13 +593,13 @@ describe('FlowModel', () => {
|
|
|
594
593
|
TestFlowModel.registerFlow(autoFlow2);
|
|
595
594
|
TestFlowModel.registerFlow(autoFlow3);
|
|
596
595
|
|
|
597
|
-
await model.
|
|
596
|
+
await model.dispatchEvent('beforeRender');
|
|
598
597
|
|
|
599
598
|
expect(executionOrder).toEqual(['auto2', 'auto3', 'auto1']);
|
|
600
599
|
});
|
|
601
600
|
|
|
602
601
|
test('should no results when no auto flows found', async () => {
|
|
603
|
-
const results = await model.
|
|
602
|
+
const results = await model.dispatchEvent('beforeRender');
|
|
604
603
|
|
|
605
604
|
expect(results).toEqual([]);
|
|
606
605
|
// Note: Log output may be captured in stderr, not console.log
|
|
@@ -617,16 +616,14 @@ describe('FlowModel', () => {
|
|
|
617
616
|
afterHookSpy = vi.fn();
|
|
618
617
|
errorHookSpy = vi.fn();
|
|
619
618
|
TestFlowModelWithHooks = class extends TestFlowModel {
|
|
620
|
-
async
|
|
621
|
-
beforeHookSpy(inputArgs);
|
|
619
|
+
async onDispatchEventStart(eventName: string, _opts?: any, inputArgs?: Record<string, any>) {
|
|
620
|
+
if (eventName === 'beforeRender') beforeHookSpy(inputArgs);
|
|
622
621
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
afterHookSpy(results, inputArgs);
|
|
622
|
+
async onDispatchEventEnd(eventName: string, _opts?: any, inputArgs?: Record<string, any>, results?: any[]) {
|
|
623
|
+
if (eventName === 'beforeRender') afterHookSpy(results, inputArgs);
|
|
626
624
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
errorHookSpy(error, inputArgs);
|
|
625
|
+
async onDispatchEventError(eventName: string, _opts?: any, inputArgs?: Record<string, any>, error?: Error) {
|
|
626
|
+
if (eventName === 'beforeRender') errorHookSpy(error, inputArgs);
|
|
630
627
|
}
|
|
631
628
|
};
|
|
632
629
|
});
|
|
@@ -638,7 +635,7 @@ describe('FlowModel', () => {
|
|
|
638
635
|
const modelWithHooks = new TestFlowModelWithHooks(modelOptions);
|
|
639
636
|
const inputArgs = { test: 'value' };
|
|
640
637
|
|
|
641
|
-
const results = await modelWithHooks.
|
|
638
|
+
const results = await modelWithHooks.dispatchEvent('beforeRender', inputArgs);
|
|
642
639
|
|
|
643
640
|
// Verify hooks were called
|
|
644
641
|
expect(beforeHookSpy).toHaveBeenCalledTimes(1);
|
|
@@ -654,22 +651,22 @@ describe('FlowModel', () => {
|
|
|
654
651
|
);
|
|
655
652
|
});
|
|
656
653
|
|
|
657
|
-
test(
|
|
654
|
+
test("should allow onDispatchEventStart('beforeRender') to terminate flow via ctx.exit()", async () => {
|
|
658
655
|
const autoFlow1 = { ...createAutoFlowDefinition(), key: 'auto1' };
|
|
659
656
|
const autoFlow2 = { ...createAutoFlowDefinition(), key: 'auto2' };
|
|
660
657
|
|
|
661
658
|
const TestFlowModelWithExitHooks = class extends TestFlowModel {
|
|
662
|
-
async
|
|
663
|
-
|
|
664
|
-
|
|
659
|
+
async onDispatchEventStart(eventName: string, _opts?: any, inputArgs?: Record<string, any>) {
|
|
660
|
+
if (eventName === 'beforeRender') {
|
|
661
|
+
beforeHookSpy(inputArgs);
|
|
662
|
+
throw new FlowExitException('beforeRender', this.uid);
|
|
663
|
+
}
|
|
665
664
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
afterHookSpy(results, inputArgs);
|
|
665
|
+
async onDispatchEventEnd(eventName: string, _o?: any, _i?: any, _r?: any[]) {
|
|
666
|
+
if (eventName === 'beforeRender') afterHookSpy(_r, _i);
|
|
669
667
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
errorHookSpy(error, inputArgs);
|
|
668
|
+
async onDispatchEventError(eventName: string, _o?: any, i?: any, e?: Error) {
|
|
669
|
+
if (eventName === 'beforeRender') errorHookSpy(e, i);
|
|
673
670
|
}
|
|
674
671
|
};
|
|
675
672
|
|
|
@@ -678,9 +675,9 @@ describe('FlowModel', () => {
|
|
|
678
675
|
TestFlowModelWithExitHooks.registerFlow(autoFlow2);
|
|
679
676
|
|
|
680
677
|
const modelWithHooks = new TestFlowModelWithExitHooks(modelOptions);
|
|
681
|
-
const results = await modelWithHooks.
|
|
678
|
+
const results = await modelWithHooks.dispatchEvent('beforeRender');
|
|
682
679
|
|
|
683
|
-
// Should have called
|
|
680
|
+
// Should have called onDispatchEventStart but not onDispatchEventEnd
|
|
684
681
|
expect(beforeHookSpy).toHaveBeenCalledTimes(1);
|
|
685
682
|
expect(afterHookSpy).not.toHaveBeenCalled();
|
|
686
683
|
expect(errorHookSpy).not.toHaveBeenCalled();
|
|
@@ -688,12 +685,12 @@ describe('FlowModel', () => {
|
|
|
688
685
|
// Should return empty results since flow was terminated early
|
|
689
686
|
expect(results).toEqual([]);
|
|
690
687
|
|
|
691
|
-
//
|
|
688
|
+
// flows should not have been executed
|
|
692
689
|
expect(autoFlow1.steps.autoStep.handler).not.toHaveBeenCalled();
|
|
693
690
|
expect(autoFlow2.steps.autoStep.handler).not.toHaveBeenCalled();
|
|
694
691
|
});
|
|
695
692
|
|
|
696
|
-
test(
|
|
693
|
+
test("should call onDispatchEventError('beforeRender') when flow execution fails", async () => {
|
|
697
694
|
const errorFlow = {
|
|
698
695
|
key: 'errorFlow',
|
|
699
696
|
|
|
@@ -708,11 +705,8 @@ describe('FlowModel', () => {
|
|
|
708
705
|
TestFlowModelWithHooks.registerFlow(errorFlow);
|
|
709
706
|
|
|
710
707
|
const modelWithHooks = new TestFlowModelWithHooks(modelOptions);
|
|
711
|
-
|
|
712
|
-
//
|
|
713
|
-
await expect(modelWithHooks.applyAutoFlows()).rejects.toThrow('Test error');
|
|
714
|
-
|
|
715
|
-
// Verify hooks were called
|
|
708
|
+
await expect(modelWithHooks.dispatchEvent('beforeRender')).rejects.toThrow('Test error');
|
|
709
|
+
// Verify hooks were called (error path)
|
|
716
710
|
expect(beforeHookSpy).toHaveBeenCalledTimes(1);
|
|
717
711
|
expect(afterHookSpy).not.toHaveBeenCalled();
|
|
718
712
|
expect(errorHookSpy).toHaveBeenCalledTimes(1);
|
|
@@ -726,14 +720,14 @@ describe('FlowModel', () => {
|
|
|
726
720
|
);
|
|
727
721
|
});
|
|
728
722
|
|
|
729
|
-
test('should provide access to step results in
|
|
723
|
+
test('should provide access to step results in onDispatchEventEnd(beforeRender)', async () => {
|
|
730
724
|
const autoFlow1 = { ...createAutoFlowDefinition(), key: 'auto1' };
|
|
731
725
|
const autoFlow2 = { ...createAutoFlowDefinition(), key: 'auto2' };
|
|
732
726
|
TestFlowModelWithHooks.registerFlow(autoFlow1);
|
|
733
727
|
TestFlowModelWithHooks.registerFlow(autoFlow2);
|
|
734
728
|
|
|
735
729
|
const modelWithHooks = new TestFlowModelWithHooks(modelOptions);
|
|
736
|
-
await modelWithHooks.
|
|
730
|
+
await modelWithHooks.dispatchEvent('beforeRender');
|
|
737
731
|
|
|
738
732
|
expect(afterHookSpy).toHaveBeenCalledTimes(1);
|
|
739
733
|
|
|
@@ -777,6 +771,82 @@ describe('FlowModel', () => {
|
|
|
777
771
|
}
|
|
778
772
|
});
|
|
779
773
|
|
|
774
|
+
test('getFlows includes beforeRender and no-on flows; excludes manual and other events', async () => {
|
|
775
|
+
const TestM = class extends FlowModel {};
|
|
776
|
+
const beforeHandler = vi.fn();
|
|
777
|
+
const noOnHandler = vi.fn();
|
|
778
|
+
const manualHandler = vi.fn();
|
|
779
|
+
|
|
780
|
+
TestM.registerFlow({ key: 'beforeA', on: 'beforeRender', sort: 2, steps: { s: { handler: beforeHandler } } });
|
|
781
|
+
TestM.registerFlow({ key: 'noOnB', sort: 1, steps: { s: { handler: noOnHandler } } });
|
|
782
|
+
TestM.registerFlow({ key: 'manualSkip', manual: true, steps: { s: { handler: manualHandler } } });
|
|
783
|
+
TestM.registerFlow({ key: 'otherEvent', on: 'click', steps: { s: { handler: vi.fn() } } });
|
|
784
|
+
|
|
785
|
+
const m = new TestM(modelOptions);
|
|
786
|
+
const autoKeys = m.getEventFlows('beforeRender').map((f) => f.key);
|
|
787
|
+
|
|
788
|
+
// sort 按 1,2 排序:noOnB -> beforeA
|
|
789
|
+
expect(autoKeys).toEqual(['noOnB', 'beforeA']);
|
|
790
|
+
|
|
791
|
+
// beforeRender 会运行两者
|
|
792
|
+
await m.dispatchEvent('beforeRender');
|
|
793
|
+
expect(beforeHandler).toHaveBeenCalledTimes(1);
|
|
794
|
+
expect(noOnHandler).toHaveBeenCalledTimes(1);
|
|
795
|
+
expect(manualHandler).not.toHaveBeenCalled();
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
test('beforeRender executes in sort order mixing no-on and beforeRender', async () => {
|
|
799
|
+
const TestM = class extends FlowModel {};
|
|
800
|
+
const calls: string[] = [];
|
|
801
|
+
TestM.registerFlow({ key: 'noOn1', sort: 1, steps: { s: { handler: () => calls.push('noOn1') } } });
|
|
802
|
+
TestM.registerFlow({
|
|
803
|
+
key: 'before2',
|
|
804
|
+
on: 'beforeRender',
|
|
805
|
+
sort: 2,
|
|
806
|
+
steps: { s: { handler: () => calls.push('before2') } },
|
|
807
|
+
});
|
|
808
|
+
TestM.registerFlow({ key: 'noOn3', sort: 3, steps: { s: { handler: () => calls.push('noOn3') } } });
|
|
809
|
+
|
|
810
|
+
const m = new TestM(modelOptions);
|
|
811
|
+
await m.dispatchEvent('beforeRender');
|
|
812
|
+
expect(calls).toEqual(['noOn1', 'before2', 'noOn3']);
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
test("model.dispatchEvent('beforeRender') uses cache keyed by eventName", async () => {
|
|
816
|
+
const TestM = class extends FlowModel {};
|
|
817
|
+
const handler = vi.fn();
|
|
818
|
+
TestM.registerFlow({ key: 'autoA', steps: { s: { handler } } });
|
|
819
|
+
|
|
820
|
+
const m = new TestM(modelOptions);
|
|
821
|
+
await m.dispatchEvent('beforeRender');
|
|
822
|
+
await m.dispatchEvent('beforeRender');
|
|
823
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
test('invalidFlowCache should clear specific event cache', async () => {
|
|
827
|
+
const TestM = class extends FlowModel {};
|
|
828
|
+
const h1 = vi.fn();
|
|
829
|
+
const h2 = vi.fn();
|
|
830
|
+
TestM.registerFlow({ key: 'onFoo', on: 'foo', steps: { s: { handler: h1 } } });
|
|
831
|
+
TestM.registerFlow({ key: 'onBar', on: 'bar', steps: { s: { handler: h2 } } });
|
|
832
|
+
|
|
833
|
+
const m = new TestM(modelOptions);
|
|
834
|
+
await m.dispatchEvent('foo', {}, { useCache: true });
|
|
835
|
+
await m.dispatchEvent('bar', {}, { useCache: true });
|
|
836
|
+
|
|
837
|
+
// cached
|
|
838
|
+
await m.dispatchEvent('foo', {}, { useCache: true });
|
|
839
|
+
await m.dispatchEvent('bar', {}, { useCache: true });
|
|
840
|
+
expect(h1).toHaveBeenCalledTimes(1);
|
|
841
|
+
expect(h2).toHaveBeenCalledTimes(1);
|
|
842
|
+
|
|
843
|
+
// invalidate foo only
|
|
844
|
+
m.invalidateFlowCache('foo');
|
|
845
|
+
await m.dispatchEvent('foo', {}, { useCache: true });
|
|
846
|
+
await m.dispatchEvent('bar', {}, { useCache: true });
|
|
847
|
+
expect(h1).toHaveBeenCalledTimes(2);
|
|
848
|
+
expect(h2).toHaveBeenCalledTimes(1);
|
|
849
|
+
});
|
|
780
850
|
test('should handle multiple flows for same event', async () => {
|
|
781
851
|
const eventFlow1 = { ...createEventFlowDefinition('sharedEvent'), key: 'event1' };
|
|
782
852
|
const eventFlow2 = { ...createEventFlowDefinition('sharedEvent'), key: 'event2' };
|
|
@@ -802,9 +872,13 @@ describe('FlowModel', () => {
|
|
|
802
872
|
const _dispatchEventWithDebounceSpy = vi.spyOn(model as any, '_dispatchEventWithDebounce');
|
|
803
873
|
|
|
804
874
|
// Test with debounce enabled
|
|
805
|
-
await model.dispatchEvent('debouncedEvent', { data: 'test' }, { debounce: true });
|
|
875
|
+
await model.dispatchEvent('debouncedEvent', { data: 'test' }, { debounce: true, sequential: true });
|
|
806
876
|
|
|
807
|
-
expect(_dispatchEventWithDebounceSpy).toHaveBeenCalledWith(
|
|
877
|
+
expect(_dispatchEventWithDebounceSpy).toHaveBeenCalledWith(
|
|
878
|
+
'debouncedEvent',
|
|
879
|
+
{ data: 'test' },
|
|
880
|
+
expect.objectContaining({ sequential: true }),
|
|
881
|
+
);
|
|
808
882
|
expect(_dispatchEventSpy).not.toHaveBeenCalled();
|
|
809
883
|
|
|
810
884
|
_dispatchEventSpy.mockRestore();
|
|
@@ -821,7 +895,11 @@ describe('FlowModel', () => {
|
|
|
821
895
|
// Test with debounce disabled
|
|
822
896
|
await model.dispatchEvent('normalEvent', { data: 'test' }, { debounce: false });
|
|
823
897
|
|
|
824
|
-
expect(_dispatchEventSpy).toHaveBeenCalledWith(
|
|
898
|
+
expect(_dispatchEventSpy).toHaveBeenCalledWith(
|
|
899
|
+
'normalEvent',
|
|
900
|
+
{ data: 'test' },
|
|
901
|
+
expect.objectContaining({ sequential: undefined }),
|
|
902
|
+
);
|
|
825
903
|
expect(_dispatchEventWithDebounceSpy).not.toHaveBeenCalled();
|
|
826
904
|
|
|
827
905
|
_dispatchEventSpy.mockRestore();
|
|
@@ -838,7 +916,11 @@ describe('FlowModel', () => {
|
|
|
838
916
|
// Test without debounce option
|
|
839
917
|
await model.dispatchEvent('defaultEvent', { data: 'test' });
|
|
840
918
|
|
|
841
|
-
expect(_dispatchEventSpy).toHaveBeenCalledWith(
|
|
919
|
+
expect(_dispatchEventSpy).toHaveBeenCalledWith(
|
|
920
|
+
'defaultEvent',
|
|
921
|
+
{ data: 'test' },
|
|
922
|
+
expect.objectContaining({ sequential: undefined }),
|
|
923
|
+
);
|
|
842
924
|
expect(_dispatchEventWithDebounceSpy).not.toHaveBeenCalled();
|
|
843
925
|
|
|
844
926
|
_dispatchEventSpy.mockRestore();
|
|
@@ -855,7 +937,11 @@ describe('FlowModel', () => {
|
|
|
855
937
|
// Test with undefined options
|
|
856
938
|
await model.dispatchEvent('undefinedOptionsEvent', { data: 'test' }, undefined);
|
|
857
939
|
|
|
858
|
-
expect(_dispatchEventSpy).toHaveBeenCalledWith(
|
|
940
|
+
expect(_dispatchEventSpy).toHaveBeenCalledWith(
|
|
941
|
+
'undefinedOptionsEvent',
|
|
942
|
+
{ data: 'test' },
|
|
943
|
+
expect.objectContaining({ sequential: undefined }),
|
|
944
|
+
);
|
|
859
945
|
expect(_dispatchEventWithDebounceSpy).not.toHaveBeenCalled();
|
|
860
946
|
|
|
861
947
|
_dispatchEventSpy.mockRestore();
|
|
@@ -1265,41 +1351,63 @@ describe('FlowModel', () => {
|
|
|
1265
1351
|
});
|
|
1266
1352
|
});
|
|
1267
1353
|
|
|
1268
|
-
describe('
|
|
1354
|
+
describe('applySubModelsBeforeRenderFlows', () => {
|
|
1269
1355
|
test('should apply auto flows to all array subModels', async () => {
|
|
1270
1356
|
const child1 = new FlowModel({ uid: 'child1', flowEngine });
|
|
1271
1357
|
const child2 = new FlowModel({ uid: 'child2', flowEngine });
|
|
1272
1358
|
|
|
1273
|
-
child1.
|
|
1274
|
-
child2.
|
|
1359
|
+
child1.dispatchEvent = vi.fn().mockResolvedValue(undefined) as any;
|
|
1360
|
+
child2.dispatchEvent = vi.fn().mockResolvedValue(undefined) as any;
|
|
1275
1361
|
|
|
1276
1362
|
parentModel.addSubModel('children', child1);
|
|
1277
1363
|
parentModel.addSubModel('children', child2);
|
|
1278
1364
|
|
|
1279
1365
|
const runtimeData = { test: 'extra' };
|
|
1280
1366
|
|
|
1281
|
-
await parentModel.
|
|
1367
|
+
await parentModel.applySubModelsBeforeRenderFlows('children', runtimeData);
|
|
1282
1368
|
|
|
1283
|
-
expect(child1.
|
|
1284
|
-
expect(child2.
|
|
1369
|
+
expect(child1.dispatchEvent).toHaveBeenCalledWith('beforeRender', runtimeData);
|
|
1370
|
+
expect(child2.dispatchEvent).toHaveBeenCalledWith('beforeRender', runtimeData);
|
|
1285
1371
|
});
|
|
1286
1372
|
|
|
1287
1373
|
test('should apply auto flows to single subModel', async () => {
|
|
1288
1374
|
const child = new FlowModel({ uid: 'child', flowEngine });
|
|
1289
1375
|
|
|
1290
|
-
child.
|
|
1376
|
+
child.dispatchEvent = vi.fn().mockResolvedValue(undefined) as any;
|
|
1291
1377
|
|
|
1292
1378
|
parentModel.setSubModel('child', child);
|
|
1293
1379
|
|
|
1294
1380
|
const runtimeData = { test: 'extra' };
|
|
1295
1381
|
|
|
1296
|
-
await parentModel.
|
|
1382
|
+
await parentModel.applySubModelsBeforeRenderFlows('child', runtimeData);
|
|
1297
1383
|
|
|
1298
|
-
expect(child.
|
|
1384
|
+
expect(child.dispatchEvent).toHaveBeenCalledWith('beforeRender', runtimeData);
|
|
1299
1385
|
});
|
|
1300
1386
|
|
|
1301
1387
|
test('should handle empty subModels gracefully', async () => {
|
|
1302
|
-
await expect(parentModel.
|
|
1388
|
+
await expect(parentModel.applySubModelsBeforeRenderFlows('nonExistent')).resolves.not.toThrow();
|
|
1389
|
+
});
|
|
1390
|
+
});
|
|
1391
|
+
|
|
1392
|
+
describe('beforeRender cache invalidation on inputArgs change', () => {
|
|
1393
|
+
test('should rerun when inputArgs changed and reuse when equal', async () => {
|
|
1394
|
+
const TestM = class extends FlowModel {};
|
|
1395
|
+
const handler = vi.fn();
|
|
1396
|
+
TestM.registerFlow({ key: 'auto1', steps: { s: { handler } } });
|
|
1397
|
+
|
|
1398
|
+
const m = new TestM(modelOptions);
|
|
1399
|
+
|
|
1400
|
+
// First run with {a:1}
|
|
1401
|
+
await m.dispatchEvent('beforeRender', { a: 1 });
|
|
1402
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
1403
|
+
|
|
1404
|
+
// Second run with same args should hit cache -> no extra handler calls
|
|
1405
|
+
await m.dispatchEvent('beforeRender', { a: 1 });
|
|
1406
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
1407
|
+
|
|
1408
|
+
// Different args invalidate cache -> handler called again
|
|
1409
|
+
await m.dispatchEvent('beforeRender', { a: 2 });
|
|
1410
|
+
expect(handler).toHaveBeenCalledTimes(2);
|
|
1303
1411
|
});
|
|
1304
1412
|
});
|
|
1305
1413
|
|
|
@@ -1627,7 +1735,7 @@ describe('FlowModel', () => {
|
|
|
1627
1735
|
});
|
|
1628
1736
|
|
|
1629
1737
|
describe('rendering operations', () => {
|
|
1630
|
-
test('should not pre-call render for RenderFunction mode and call exactly once on render', () => {
|
|
1738
|
+
test('should not pre-call render for RenderFunction mode and call exactly once on render', async () => {
|
|
1631
1739
|
const renderSpy = vi.fn(() => vi.fn());
|
|
1632
1740
|
|
|
1633
1741
|
class CallbackRenderModel extends FlowModel {
|
|
@@ -1645,17 +1753,20 @@ describe('FlowModel', () => {
|
|
|
1645
1753
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
1646
1754
|
try {
|
|
1647
1755
|
const { unmount } = render(
|
|
1648
|
-
React.createElement(
|
|
1756
|
+
React.createElement(
|
|
1757
|
+
FlowEngineProvider,
|
|
1758
|
+
{ engine: callbackModel.flowEngine },
|
|
1759
|
+
React.createElement(FlowModelRenderer, { model: callbackModel }),
|
|
1760
|
+
),
|
|
1649
1761
|
);
|
|
1650
|
-
|
|
1651
|
-
expect(renderSpy).toHaveBeenCalledTimes(1);
|
|
1762
|
+
await waitFor(() => expect(renderSpy).toHaveBeenCalledTimes(1));
|
|
1652
1763
|
unmount();
|
|
1653
1764
|
} finally {
|
|
1654
1765
|
warnSpy.mockRestore();
|
|
1655
1766
|
}
|
|
1656
1767
|
});
|
|
1657
1768
|
|
|
1658
|
-
test('should not pre-call render for ReactElement mode and call exactly once on actual render', () => {
|
|
1769
|
+
test('should not pre-call render for ReactElement mode and call exactly once on actual render', async () => {
|
|
1659
1770
|
const renderSpy = vi.fn(() => React.createElement('div', { 'data-testid': 'elt' }, 'Elt'));
|
|
1660
1771
|
|
|
1661
1772
|
class ElementRenderModel extends FlowModel {
|
|
@@ -1670,11 +1781,15 @@ describe('FlowModel', () => {
|
|
|
1670
1781
|
expect(renderSpy).toHaveBeenCalledTimes(0);
|
|
1671
1782
|
|
|
1672
1783
|
const { getByTestId, unmount } = render(
|
|
1673
|
-
React.createElement(
|
|
1784
|
+
React.createElement(
|
|
1785
|
+
FlowEngineProvider,
|
|
1786
|
+
{ engine: elementModel.flowEngine },
|
|
1787
|
+
React.createElement(FlowModelRenderer, { model: elementModel }),
|
|
1788
|
+
),
|
|
1674
1789
|
);
|
|
1675
1790
|
|
|
1676
1791
|
// Render should be called exactly once during mount
|
|
1677
|
-
expect(renderSpy).toHaveBeenCalledTimes(1);
|
|
1792
|
+
await waitFor(() => expect(renderSpy).toHaveBeenCalledTimes(1));
|
|
1678
1793
|
expect(getByTestId('elt')).toBeTruthy();
|
|
1679
1794
|
|
|
1680
1795
|
unmount();
|
|
@@ -1690,13 +1805,15 @@ describe('FlowModel', () => {
|
|
|
1690
1805
|
expect(result.type.displayName).toBe('ReactiveWrapper(FlowModel)');
|
|
1691
1806
|
});
|
|
1692
1807
|
|
|
1693
|
-
test('should rerender
|
|
1808
|
+
test('should rerender triggers beforeRender without cache', async () => {
|
|
1694
1809
|
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
1695
|
-
model.
|
|
1810
|
+
model.dispatchEvent = vi.fn().mockResolvedValue(undefined) as any;
|
|
1696
1811
|
|
|
1697
1812
|
try {
|
|
1698
1813
|
await expect(model.rerender()).resolves.not.toThrow();
|
|
1699
|
-
expect(model.
|
|
1814
|
+
expect(model.dispatchEvent).toHaveBeenCalledWith('beforeRender', undefined, {
|
|
1815
|
+
useCache: false,
|
|
1816
|
+
});
|
|
1700
1817
|
} finally {
|
|
1701
1818
|
consoleSpy.mockRestore();
|
|
1702
1819
|
}
|
|
@@ -2039,16 +2156,16 @@ describe('FlowModel', () => {
|
|
|
2039
2156
|
vi.restoreAllMocks();
|
|
2040
2157
|
});
|
|
2041
2158
|
|
|
2042
|
-
describe('
|
|
2159
|
+
describe('invalidateFlowCache', () => {
|
|
2043
2160
|
test('should delete auto flow cache for current model', () => {
|
|
2044
|
-
const expectedCacheKey = '
|
|
2161
|
+
const expectedCacheKey = 'event:beforeRender-beforeRender-test-model-uid';
|
|
2045
2162
|
realFlowEngine.applyFlowCache.set(expectedCacheKey, {
|
|
2046
2163
|
status: 'resolved',
|
|
2047
2164
|
data: [],
|
|
2048
2165
|
promise: Promise.resolve([]),
|
|
2049
2166
|
});
|
|
2050
2167
|
|
|
2051
|
-
model.
|
|
2168
|
+
model.invalidateFlowCache('beforeRender');
|
|
2052
2169
|
|
|
2053
2170
|
expect(deleteSpy).toHaveBeenCalledWith(expectedCacheKey);
|
|
2054
2171
|
});
|
|
@@ -2057,8 +2174,8 @@ describe('FlowModel', () => {
|
|
|
2057
2174
|
const fork1 = model.createFork();
|
|
2058
2175
|
const fork2 = model.createFork();
|
|
2059
2176
|
|
|
2060
|
-
const fork1CacheKey =
|
|
2061
|
-
const fork2CacheKey =
|
|
2177
|
+
const fork1CacheKey = `event:beforeRender:${fork1.forkId}-beforeRender-test-model-uid`;
|
|
2178
|
+
const fork2CacheKey = `event:beforeRender:${fork2.forkId}-beforeRender-test-model-uid`;
|
|
2062
2179
|
|
|
2063
2180
|
realFlowEngine.applyFlowCache.set(fork1CacheKey, {
|
|
2064
2181
|
status: 'resolved',
|
|
@@ -2071,7 +2188,7 @@ describe('FlowModel', () => {
|
|
|
2071
2188
|
promise: Promise.resolve([]),
|
|
2072
2189
|
});
|
|
2073
2190
|
|
|
2074
|
-
model.
|
|
2191
|
+
model.invalidateFlowCache('beforeRender');
|
|
2075
2192
|
|
|
2076
2193
|
expect(deleteSpy).toHaveBeenCalledWith(fork1CacheKey);
|
|
2077
2194
|
expect(deleteSpy).toHaveBeenCalledWith(fork2CacheKey);
|
|
@@ -2081,27 +2198,27 @@ describe('FlowModel', () => {
|
|
|
2081
2198
|
const childModel1 = new FlowModel({ uid: 'child1', flowEngine: realFlowEngine });
|
|
2082
2199
|
const childModel2 = new FlowModel({ uid: 'child2', flowEngine: realFlowEngine });
|
|
2083
2200
|
|
|
2084
|
-
const child1Spy = vi.spyOn(childModel1, '
|
|
2085
|
-
const child2Spy = vi.spyOn(childModel2, '
|
|
2201
|
+
const child1Spy = vi.spyOn(childModel1, 'invalidateFlowCache');
|
|
2202
|
+
const child2Spy = vi.spyOn(childModel2, 'invalidateFlowCache');
|
|
2086
2203
|
|
|
2087
2204
|
model.addSubModel('children', childModel1);
|
|
2088
2205
|
model.addSubModel('children', childModel2);
|
|
2089
2206
|
|
|
2090
|
-
model.
|
|
2207
|
+
model.invalidateFlowCache('beforeRender', true);
|
|
2091
2208
|
|
|
2092
|
-
expect(child1Spy).toHaveBeenCalledWith(true);
|
|
2093
|
-
expect(child2Spy).toHaveBeenCalledWith(true);
|
|
2209
|
+
expect(child1Spy).toHaveBeenCalledWith('beforeRender', true);
|
|
2210
|
+
expect(child2Spy).toHaveBeenCalledWith('beforeRender', true);
|
|
2094
2211
|
});
|
|
2095
2212
|
|
|
2096
2213
|
test('should recursively invalidate cache for object subModels', () => {
|
|
2097
2214
|
const childModel = new FlowModel({ uid: 'child', flowEngine: realFlowEngine });
|
|
2098
|
-
const childSpy = vi.spyOn(childModel, '
|
|
2215
|
+
const childSpy = vi.spyOn(childModel, 'invalidateFlowCache');
|
|
2099
2216
|
|
|
2100
2217
|
model.setSubModel('child', childModel);
|
|
2101
2218
|
|
|
2102
|
-
model.
|
|
2219
|
+
model.invalidateFlowCache('beforeRender', true);
|
|
2103
2220
|
|
|
2104
|
-
expect(childSpy).toHaveBeenCalledWith(true);
|
|
2221
|
+
expect(childSpy).toHaveBeenCalledWith('beforeRender', true);
|
|
2105
2222
|
});
|
|
2106
2223
|
|
|
2107
2224
|
test('should handle mixed array and object subModels', () => {
|
|
@@ -2109,25 +2226,31 @@ describe('FlowModel', () => {
|
|
|
2109
2226
|
const arrayChild2 = new FlowModel({ uid: 'arrayChild2', flowEngine: realFlowEngine });
|
|
2110
2227
|
const objectChild = new FlowModel({ uid: 'objectChild', flowEngine: realFlowEngine });
|
|
2111
2228
|
|
|
2112
|
-
const array1Spy = vi.spyOn(arrayChild1, '
|
|
2113
|
-
const array2Spy = vi.spyOn(arrayChild2, '
|
|
2114
|
-
const objectSpy = vi.spyOn(objectChild, '
|
|
2229
|
+
const array1Spy = vi.spyOn(arrayChild1, 'invalidateFlowCache');
|
|
2230
|
+
const array2Spy = vi.spyOn(arrayChild2, 'invalidateFlowCache');
|
|
2231
|
+
const objectSpy = vi.spyOn(objectChild, 'invalidateFlowCache');
|
|
2115
2232
|
|
|
2116
2233
|
model.addSubModel('arrayChildren', arrayChild1);
|
|
2117
2234
|
model.addSubModel('arrayChildren', arrayChild2);
|
|
2118
2235
|
model.setSubModel('objectChild', objectChild);
|
|
2119
2236
|
|
|
2120
|
-
model.
|
|
2237
|
+
model.invalidateFlowCache('beforeRender', true);
|
|
2121
2238
|
|
|
2122
|
-
expect(array1Spy).toHaveBeenCalledWith(true);
|
|
2123
|
-
expect(array2Spy).toHaveBeenCalledWith(true);
|
|
2124
|
-
expect(objectSpy).toHaveBeenCalledWith(true);
|
|
2239
|
+
expect(array1Spy).toHaveBeenCalledWith('beforeRender', true);
|
|
2240
|
+
expect(array2Spy).toHaveBeenCalledWith('beforeRender', true);
|
|
2241
|
+
expect(objectSpy).toHaveBeenCalledWith('beforeRender', true);
|
|
2125
2242
|
});
|
|
2126
2243
|
|
|
2127
2244
|
test('should handle empty subModels without error', () => {
|
|
2128
|
-
|
|
2245
|
+
realFlowEngine.applyFlowCache.set('event:beforeRender-beforeRender-test-model-uid', {
|
|
2246
|
+
status: 'resolved',
|
|
2247
|
+
data: [],
|
|
2248
|
+
promise: Promise.resolve([]),
|
|
2249
|
+
});
|
|
2250
|
+
|
|
2251
|
+
model.invalidateFlowCache('beforeRender');
|
|
2129
2252
|
|
|
2130
|
-
expect(deleteSpy).toHaveBeenCalledWith('
|
|
2253
|
+
expect(deleteSpy).toHaveBeenCalledWith('event:beforeRender-beforeRender-test-model-uid');
|
|
2131
2254
|
});
|
|
2132
2255
|
|
|
2133
2256
|
test('should handle null flowEngine gracefully', () => {
|
|
@@ -2135,19 +2258,19 @@ describe('FlowModel', () => {
|
|
|
2135
2258
|
modelWithValidEngine.flowEngine = null;
|
|
2136
2259
|
|
|
2137
2260
|
expect(() => {
|
|
2138
|
-
modelWithValidEngine.
|
|
2261
|
+
modelWithValidEngine.invalidateFlowCache('beforeRender');
|
|
2139
2262
|
}).not.toThrow();
|
|
2140
2263
|
});
|
|
2141
2264
|
|
|
2142
2265
|
test('should pass deep parameter to recursive calls', () => {
|
|
2143
2266
|
const childModel = new FlowModel({ uid: 'child', flowEngine: realFlowEngine });
|
|
2144
|
-
const childSpy = vi.spyOn(childModel, '
|
|
2267
|
+
const childSpy = vi.spyOn(childModel, 'invalidateFlowCache');
|
|
2145
2268
|
|
|
2146
2269
|
model.setSubModel('child', childModel);
|
|
2147
2270
|
|
|
2148
|
-
model.
|
|
2271
|
+
model.invalidateFlowCache('beforeRender', true);
|
|
2149
2272
|
|
|
2150
|
-
expect(childSpy).toHaveBeenCalledWith(true);
|
|
2273
|
+
expect(childSpy).toHaveBeenCalledWith('beforeRender', true);
|
|
2151
2274
|
});
|
|
2152
2275
|
});
|
|
2153
2276
|
});
|
|
@@ -2198,7 +2321,7 @@ describe('FlowModel', () => {
|
|
|
2198
2321
|
});
|
|
2199
2322
|
|
|
2200
2323
|
const handlerSpy = flow.steps.testStep.handler as any;
|
|
2201
|
-
await model.
|
|
2324
|
+
await model.dispatchEvent('beforeRender');
|
|
2202
2325
|
expect(handlerSpy).toHaveBeenCalled();
|
|
2203
2326
|
});
|
|
2204
2327
|
|
|
@@ -2245,7 +2368,7 @@ describe('FlowModel', () => {
|
|
|
2245
2368
|
});
|
|
2246
2369
|
|
|
2247
2370
|
const handlerSpy = flow.steps.nestedStep.handler as any;
|
|
2248
|
-
await model.
|
|
2371
|
+
await model.dispatchEvent('beforeRender');
|
|
2249
2372
|
expect(handlerSpy).toHaveBeenCalled();
|
|
2250
2373
|
});
|
|
2251
2374
|
});
|