@nocobase/flow-engine 2.0.0-alpha.4 → 2.0.0-alpha.41
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 +4 -2
- package/lib/JSRunner.js +3 -0
- package/lib/ViewScopedFlowEngine.d.ts +1 -1
- package/lib/ViewScopedFlowEngine.js +12 -0
- package/lib/acl/Acl.d.ts +1 -0
- package/lib/acl/Acl.js +11 -0
- package/lib/components/FieldModelRenderer.js +14 -6
- 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 +3 -6
- package/lib/components/FlowModelRenderer.js +16 -47
- package/lib/components/FormItem.js +5 -1
- package/lib/components/MobilePopup.d.ts +20 -0
- package/lib/components/MobilePopup.js +102 -0
- package/lib/components/MobilePopup.style.d.ts +17 -0
- package/lib/components/MobilePopup.style.js +186 -0
- package/lib/components/index.d.ts +1 -0
- package/lib/components/index.js +3 -1
- package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +2 -2
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +17 -5
- package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +2 -2
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +2 -2
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +35 -6
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +7 -1
- package/lib/components/variables/VariableInput.js +19 -5
- package/lib/components/variables/VariableTag.js +43 -2
- package/lib/components/variables/types.d.ts +2 -0
- package/lib/data-source/index.d.ts +15 -4
- package/lib/data-source/index.js +42 -13
- package/lib/data-source/sortCollectionsByInherits.d.ts +10 -0
- package/lib/data-source/sortCollectionsByInherits.js +71 -0
- package/lib/emitter.d.ts +6 -0
- package/lib/emitter.js +12 -0
- package/lib/executor/FlowExecutor.d.ts +4 -5
- package/lib/executor/FlowExecutor.js +168 -99
- package/lib/flow-registry/GlobalFlowRegistry.d.ts +1 -0
- package/lib/flow-registry/GlobalFlowRegistry.js +3 -0
- package/lib/flow-registry/InstanceFlowRegistry.d.ts +1 -0
- package/lib/flow-registry/InstanceFlowRegistry.js +3 -0
- package/lib/flowContext.d.ts +37 -5
- package/lib/flowContext.js +224 -87
- package/lib/flowEngine.d.ts +24 -1
- package/lib/flowEngine.js +81 -8
- package/lib/flowSettings.d.ts +2 -1
- package/lib/flowSettings.js +16 -8
- package/lib/hooks/useApplyAutoFlows.js +2 -1
- package/lib/index.d.ts +7 -1
- package/lib/index.js +32 -3
- package/lib/locale/en-US.json +4 -2
- package/lib/locale/index.d.ts +4 -0
- package/lib/locale/zh-CN.json +4 -2
- package/lib/models/CollectionFieldModel.d.ts +3 -0
- package/lib/models/CollectionFieldModel.js +52 -6
- package/lib/models/flowModel.d.ts +30 -29
- package/lib/models/flowModel.js +153 -100
- package/lib/models/forkFlowModel.d.ts +8 -4
- package/lib/models/forkFlowModel.js +38 -8
- package/lib/provider.d.ts +3 -1
- package/lib/provider.js +7 -5
- package/lib/resources/multiRecordResource.js +25 -1
- package/lib/resources/singleRecordResource.js +19 -1
- package/lib/resources/sqlResource.d.ts +1 -0
- package/lib/resources/sqlResource.js +20 -24
- 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 +205 -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 +162 -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-antd-icons.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.js +65 -0
- 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 +17 -9
- 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 +71 -0
- package/lib/runjs-context/snippets/scene/block/render-react-jsx.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.js → block/render-react-jsx.snippet.js} +26 -13
- 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 +18 -17
- 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 +95 -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 +84 -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/scheduler/ModelOperationScheduler.d.ts +51 -0
- package/lib/scheduler/ModelOperationScheduler.js +262 -0
- package/lib/types.d.ts +28 -3
- package/lib/types.js +4 -3
- package/lib/utils/associationObjectVariable.d.ts +32 -0
- package/lib/utils/associationObjectVariable.js +157 -0
- package/lib/utils/buildSettingsViewInputArgs.d.ts +19 -0
- package/lib/utils/buildSettingsViewInputArgs.js +75 -0
- package/lib/utils/createEphemeralContext.d.ts +13 -0
- package/lib/utils/createEphemeralContext.js +140 -0
- package/lib/utils/flows.d.ts +10 -0
- package/lib/{runjs-context/snippets/global/api-request-post.snippet.js → utils/flows.js} +21 -15
- package/lib/utils/index.d.ts +7 -2
- package/lib/utils/index.js +21 -2
- package/lib/utils/jsxTransform.d.ts +15 -0
- package/lib/utils/jsxTransform.js +68 -0
- package/lib/utils/params-resolvers.js +3 -3
- package/lib/utils/parsePathnameToViewParams.d.ts +1 -1
- package/lib/utils/parsePathnameToViewParams.js +41 -5
- package/lib/utils/pruneFilter.d.ts +21 -0
- package/lib/{runjs-context/snippets/global/try-catch-async.snippet.js → utils/pruneFilter.js} +24 -16
- package/lib/utils/safeGlobals.d.ts +5 -3
- package/lib/utils/safeGlobals.js +40 -0
- package/lib/utils/schema-utils.js +2 -2
- package/lib/utils/serverContextParams.d.ts +1 -0
- package/lib/utils/translation.d.ts +4 -1
- package/lib/utils/translation.js +6 -2
- package/lib/utils/variablesParams.d.ts +22 -5
- package/lib/utils/variablesParams.js +132 -36
- package/lib/views/DrawerComponent.js +21 -2
- package/lib/views/PageComponent.js +2 -1
- package/lib/views/ViewNavigation.d.ts +3 -9
- package/lib/views/ViewNavigation.js +16 -2
- package/lib/views/createViewMeta.d.ts +29 -1
- package/lib/views/createViewMeta.js +338 -72
- package/lib/views/index.d.ts +1 -0
- package/lib/views/index.js +3 -0
- package/lib/views/useDialog.d.ts +9 -8
- package/lib/views/useDialog.js +19 -14
- package/lib/views/useDrawer.d.ts +9 -8
- package/lib/views/useDrawer.js +54 -35
- package/lib/views/usePage.d.ts +9 -8
- package/lib/views/usePage.js +20 -14
- package/package.json +6 -3
- package/src/BlockScopedFlowEngine.ts +86 -0
- package/src/FlowContextProvider.tsx +4 -2
- package/src/JSRunner.ts +3 -0
- package/src/ViewScopedFlowEngine.ts +15 -1
- package/src/__tests__/JSRunner.test.ts +62 -53
- package/src/__tests__/blockScopedFlowEngine.test.ts +154 -0
- package/src/__tests__/createViewMeta.popup.test.ts +132 -0
- package/src/__tests__/flow-engine.test.ts +3 -0
- package/src/__tests__/flowContext.test.ts +52 -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__/flowSettings.open.test.tsx +2 -0
- package/src/__tests__/flowSettings.test.ts +2 -0
- package/src/__tests__/globalFlowRegistry.test.ts +1 -1
- package/src/__tests__/modelOperationScheduler.test.ts +346 -0
- package/src/__tests__/objectVariable.test.ts +464 -0
- 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 +461 -0
- package/src/__tests__/runjsSnippets.test.ts +140 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +3 -3
- package/src/acl/Acl.tsx +14 -0
- package/src/acl/__tests__/Acl.test.tsx +43 -0
- package/src/components/DynamicFlowsEditor.tsx +3 -4
- package/src/components/FieldModelRenderer.tsx +20 -7
- package/src/components/FieldSkeleton.tsx +27 -0
- package/src/components/FlowContextSelector.tsx +6 -2
- package/src/components/FlowModelRenderer.tsx +33 -81
- package/src/components/FormItem.tsx +8 -1
- package/src/components/MobilePopup.style.ts +220 -0
- package/src/components/MobilePopup.tsx +86 -0
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +6 -6
- package/src/components/index.ts +1 -0
- package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +1 -1
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +17 -4
- package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +1 -1
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +39 -10
- package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +14 -1
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +425 -0
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +5 -7
- package/src/components/variables/VariableInput.tsx +25 -5
- 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 +42 -11
- package/src/data-source/sortCollectionsByInherits.ts +61 -0
- package/src/emitter.ts +14 -0
- package/src/executor/FlowExecutor.ts +213 -119
- package/src/executor/__tests__/ctx-defs-injection.test.ts +197 -0
- package/src/executor/__tests__/flowExecutor.test.ts +151 -5
- package/src/flow-registry/GlobalFlowRegistry.ts +1 -0
- package/src/flow-registry/InstanceFlowRegistry.ts +1 -0
- package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +54 -0
- package/src/flowContext.ts +303 -104
- package/src/flowEngine.ts +96 -6
- package/src/flowSettings.ts +12 -4
- package/src/hooks/useApplyAutoFlows.ts +3 -1
- package/src/index.ts +12 -1
- package/src/locale/en-US.json +4 -2
- package/src/locale/zh-CN.json +4 -2
- package/src/models/CollectionFieldModel.tsx +60 -8
- package/src/models/__tests__/dispatchEvent.behavior.test.ts +169 -0
- package/src/models/__tests__/flowModel.getFlows.sort.test.ts +33 -9
- package/src/models/__tests__/flowModel.scheduleModelOperation.test.tsx +129 -0
- package/src/models/__tests__/flowModel.test.ts +234 -111
- package/src/models/__tests__/forkFlowModel.test.ts +40 -7
- package/src/models/flowModel.tsx +197 -132
- package/src/models/forkFlowModel.ts +48 -8
- package/src/provider.tsx +10 -7
- package/src/resources/multiRecordResource.ts +28 -1
- package/src/resources/singleRecordResource.ts +19 -1
- package/src/resources/sqlResource.ts +20 -25
- 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 +196 -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 +178 -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/block/render-antd-icons.snippet.ts +46 -0
- package/src/runjs-context/snippets/scene/block/render-button-handler.snippet.ts +35 -0
- 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 +52 -0
- package/src/runjs-context/snippets/scene/block/render-react-jsx.snippet.ts +39 -0
- package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +38 -0
- package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +76 -0
- package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +65 -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/scheduler/ModelOperationScheduler.ts +304 -0
- package/src/types.ts +34 -0
- package/src/utils/__tests__/flows.test.ts +65 -0
- package/src/utils/__tests__/jsxTransform.test.ts +38 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +25 -0
- package/src/utils/__tests__/pruneFilter.test.ts +38 -0
- package/src/utils/__tests__/safeGlobals.test.ts +22 -1
- package/src/utils/__tests__/variablesParams.test.ts +63 -0
- package/src/utils/associationObjectVariable.ts +180 -0
- package/src/utils/buildSettingsViewInputArgs.ts +72 -0
- package/src/utils/createEphemeralContext.ts +142 -0
- package/src/utils/flows.ts +23 -0
- package/src/utils/index.ts +11 -2
- package/src/utils/jsxTransform.ts +39 -0
- package/src/utils/params-resolvers.ts +2 -2
- package/src/utils/parsePathnameToViewParams.ts +50 -6
- package/src/utils/pruneFilter.ts +41 -0
- package/src/utils/safeGlobals.ts +49 -3
- package/src/utils/schema-utils.ts +1 -1
- package/src/utils/serverContextParams.ts +1 -0
- package/src/utils/translation.ts +7 -2
- package/src/utils/variablesParams.ts +156 -38
- package/src/views/DrawerComponent.tsx +21 -2
- package/src/views/PageComponent.tsx +1 -1
- package/src/views/ViewNavigation.ts +20 -12
- package/src/views/__tests__/ViewNavigation.test.ts +10 -0
- package/src/views/createViewMeta.ts +393 -70
- package/src/views/index.tsx +1 -0
- package/src/views/useDialog.tsx +24 -18
- package/src/views/useDrawer.tsx +74 -45
- package/src/views/usePage.tsx +26 -17
- 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/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/requireAsync.snippet.d.ts +0 -16
- 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/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-mount.snippet.js +0 -46
- 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-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/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-button-handler.snippet.ts +0 -24
- package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +0 -30
- package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +0 -34
- 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: true }),
|
|
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: true }),
|
|
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: true }),
|
|
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
|
|
|
@@ -1415,8 +1523,6 @@ describe('FlowModel', () => {
|
|
|
1415
1523
|
const fork1 = model.createFork();
|
|
1416
1524
|
const fork2 = model.createFork();
|
|
1417
1525
|
|
|
1418
|
-
expect(fork1.forkId).toBe(0);
|
|
1419
|
-
expect(fork2.forkId).toBe(1);
|
|
1420
1526
|
expect(model.forks.size).toBe(2);
|
|
1421
1527
|
expect(model.forks.has(fork1)).toBe(true);
|
|
1422
1528
|
expect(model.forks.has(fork2)).toBe(true);
|
|
@@ -1435,8 +1541,6 @@ describe('FlowModel', () => {
|
|
|
1435
1541
|
const fork2 = model.createFork({}, 'key2');
|
|
1436
1542
|
|
|
1437
1543
|
expect(fork1).not.toBe(fork2);
|
|
1438
|
-
expect(fork1.forkId).toBe(0);
|
|
1439
|
-
expect(fork2.forkId).toBe(1);
|
|
1440
1544
|
});
|
|
1441
1545
|
|
|
1442
1546
|
test('should create fork with local props', () => {
|
|
@@ -1627,7 +1731,7 @@ describe('FlowModel', () => {
|
|
|
1627
1731
|
});
|
|
1628
1732
|
|
|
1629
1733
|
describe('rendering operations', () => {
|
|
1630
|
-
test('should not pre-call render for RenderFunction mode and call exactly once on render', () => {
|
|
1734
|
+
test('should not pre-call render for RenderFunction mode and call exactly once on render', async () => {
|
|
1631
1735
|
const renderSpy = vi.fn(() => vi.fn());
|
|
1632
1736
|
|
|
1633
1737
|
class CallbackRenderModel extends FlowModel {
|
|
@@ -1645,17 +1749,20 @@ describe('FlowModel', () => {
|
|
|
1645
1749
|
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
1646
1750
|
try {
|
|
1647
1751
|
const { unmount } = render(
|
|
1648
|
-
React.createElement(
|
|
1752
|
+
React.createElement(
|
|
1753
|
+
FlowEngineProvider,
|
|
1754
|
+
{ engine: callbackModel.flowEngine },
|
|
1755
|
+
React.createElement(FlowModelRenderer, { model: callbackModel }),
|
|
1756
|
+
),
|
|
1649
1757
|
);
|
|
1650
|
-
|
|
1651
|
-
expect(renderSpy).toHaveBeenCalledTimes(1);
|
|
1758
|
+
await waitFor(() => expect(renderSpy).toHaveBeenCalledTimes(1));
|
|
1652
1759
|
unmount();
|
|
1653
1760
|
} finally {
|
|
1654
1761
|
warnSpy.mockRestore();
|
|
1655
1762
|
}
|
|
1656
1763
|
});
|
|
1657
1764
|
|
|
1658
|
-
test('should not pre-call render for ReactElement mode and call exactly once on actual render', () => {
|
|
1765
|
+
test('should not pre-call render for ReactElement mode and call exactly once on actual render', async () => {
|
|
1659
1766
|
const renderSpy = vi.fn(() => React.createElement('div', { 'data-testid': 'elt' }, 'Elt'));
|
|
1660
1767
|
|
|
1661
1768
|
class ElementRenderModel extends FlowModel {
|
|
@@ -1670,11 +1777,15 @@ describe('FlowModel', () => {
|
|
|
1670
1777
|
expect(renderSpy).toHaveBeenCalledTimes(0);
|
|
1671
1778
|
|
|
1672
1779
|
const { getByTestId, unmount } = render(
|
|
1673
|
-
React.createElement(
|
|
1780
|
+
React.createElement(
|
|
1781
|
+
FlowEngineProvider,
|
|
1782
|
+
{ engine: elementModel.flowEngine },
|
|
1783
|
+
React.createElement(FlowModelRenderer, { model: elementModel }),
|
|
1784
|
+
),
|
|
1674
1785
|
);
|
|
1675
1786
|
|
|
1676
1787
|
// Render should be called exactly once during mount
|
|
1677
|
-
expect(renderSpy).toHaveBeenCalledTimes(1);
|
|
1788
|
+
await waitFor(() => expect(renderSpy).toHaveBeenCalledTimes(1));
|
|
1678
1789
|
expect(getByTestId('elt')).toBeTruthy();
|
|
1679
1790
|
|
|
1680
1791
|
unmount();
|
|
@@ -1690,13 +1801,15 @@ describe('FlowModel', () => {
|
|
|
1690
1801
|
expect(result.type.displayName).toBe('ReactiveWrapper(FlowModel)');
|
|
1691
1802
|
});
|
|
1692
1803
|
|
|
1693
|
-
test('should rerender
|
|
1804
|
+
test('should rerender triggers beforeRender without cache', async () => {
|
|
1694
1805
|
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
1695
|
-
model.
|
|
1806
|
+
model.dispatchEvent = vi.fn().mockResolvedValue(undefined) as any;
|
|
1696
1807
|
|
|
1697
1808
|
try {
|
|
1698
1809
|
await expect(model.rerender()).resolves.not.toThrow();
|
|
1699
|
-
expect(model.
|
|
1810
|
+
expect(model.dispatchEvent).toHaveBeenCalledWith('beforeRender', undefined, {
|
|
1811
|
+
useCache: false,
|
|
1812
|
+
});
|
|
1700
1813
|
} finally {
|
|
1701
1814
|
consoleSpy.mockRestore();
|
|
1702
1815
|
}
|
|
@@ -1713,12 +1826,14 @@ describe('FlowModel', () => {
|
|
|
1713
1826
|
|
|
1714
1827
|
const serialized = model.serialize();
|
|
1715
1828
|
|
|
1716
|
-
expect(serialized).toEqual(
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1829
|
+
expect(serialized).toEqual(
|
|
1830
|
+
expect.objectContaining({
|
|
1831
|
+
uid: model.uid,
|
|
1832
|
+
stepParams: expect.objectContaining({ flow1: { step1: { param1: 'value1' } } }),
|
|
1833
|
+
sortIndex: 5,
|
|
1834
|
+
subModels: expect.any(Object),
|
|
1835
|
+
}),
|
|
1836
|
+
);
|
|
1722
1837
|
// props should be excluded from serialization
|
|
1723
1838
|
expect(serialized.props).toBeUndefined();
|
|
1724
1839
|
expect(serialized.flowEngine).toBeUndefined();
|
|
@@ -1736,12 +1851,14 @@ describe('FlowModel', () => {
|
|
|
1736
1851
|
|
|
1737
1852
|
const serialized = emptyModel.serialize();
|
|
1738
1853
|
|
|
1739
|
-
expect(serialized).toEqual(
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1854
|
+
expect(serialized).toEqual(
|
|
1855
|
+
expect.objectContaining({
|
|
1856
|
+
uid: 'empty-model',
|
|
1857
|
+
stepParams: expect.any(Object),
|
|
1858
|
+
sortIndex: expect.any(Number),
|
|
1859
|
+
subModels: expect.any(Object),
|
|
1860
|
+
}),
|
|
1861
|
+
);
|
|
1745
1862
|
expect(serialized.flowEngine).toBeUndefined();
|
|
1746
1863
|
});
|
|
1747
1864
|
});
|
|
@@ -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
|
});
|