@nocobase/flow-engine 2.0.0-alpha.3 → 2.0.0-alpha.30
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/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/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/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 +19 -13
- 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 +135 -100
- package/lib/flowContext.d.ts +33 -5
- package/lib/flowContext.js +193 -76
- package/lib/flowEngine.d.ts +8 -1
- package/lib/flowEngine.js +18 -6
- package/lib/flowSettings.d.ts +2 -1
- package/lib/flowSettings.js +12 -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 +2 -0
- package/lib/models/CollectionFieldModel.js +43 -3
- package/lib/models/flowModel.d.ts +28 -29
- package/lib/models/flowModel.js +114 -92
- package/lib/models/forkFlowModel.d.ts +4 -4
- package/lib/models/forkFlowModel.js +32 -8
- 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/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 +183 -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 +161 -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 +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/types.d.ts +28 -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/createEphemeralContext.d.ts +13 -0
- package/lib/utils/createEphemeralContext.js +140 -0
- package/lib/utils/index.d.ts +3 -2
- package/lib/utils/index.js +5 -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/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/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 +338 -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 +5 -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__/createViewMeta.popup.test.ts +132 -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/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/StepSettingsDialog.tsx +14 -1
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +424 -0
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +5 -7
- 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 +17 -11
- package/src/data-source/sortCollectionsByInherits.ts +61 -0
- package/src/executor/FlowExecutor.ts +178 -121
- package/src/executor/__tests__/ctx-defs-injection.test.ts +197 -0
- package/src/executor/__tests__/flowExecutor.test.ts +151 -5
- package/src/flowContext.ts +266 -97
- package/src/flowEngine.ts +21 -6
- package/src/flowSettings.ts +9 -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 +43 -4
- package/src/models/__tests__/flowModel.getFlows.sort.test.ts +4 -4
- package/src/models/__tests__/flowModel.test.ts +234 -111
- package/src/models/__tests__/forkFlowModel.test.ts +22 -7
- package/src/models/flowModel.tsx +149 -125
- package/src/models/forkFlowModel.ts +41 -8
- package/src/provider.tsx +10 -7
- package/src/resources/multiRecordResource.ts +2 -0
- package/src/resources/singleRecordResource.ts +1 -0
- 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 +171 -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 +177 -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-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/types.ts +34 -0
- package/src/utils/__tests__/jsxTransform.test.ts +38 -0
- package/src/utils/__tests__/safeGlobals.test.ts +22 -1
- package/src/utils/buildSettingsViewInputArgs.ts +72 -0
- package/src/utils/createEphemeralContext.ts +142 -0
- package/src/utils/index.ts +2 -2
- package/src/utils/jsxTransform.ts +39 -0
- package/src/utils/params-resolvers.ts +2 -2
- 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/variablesParams.ts +50 -38
- package/src/views/PageComponent.tsx +1 -1
- package/src/views/createViewMeta.ts +393 -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-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-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
package/lib/views/useDrawer.js
CHANGED
|
@@ -50,12 +50,31 @@ var import_DrawerComponent = __toESM(require("./DrawerComponent"));
|
|
|
50
50
|
var import_usePatchElement = __toESM(require("./usePatchElement"));
|
|
51
51
|
var import_provider = require("../provider");
|
|
52
52
|
var import_ViewScopedFlowEngine = require("../ViewScopedFlowEngine");
|
|
53
|
-
let uuid = 0;
|
|
54
53
|
function useDrawer() {
|
|
55
54
|
const holderRef = React.useRef(null);
|
|
55
|
+
const drawerList = React.useMemo(() => import__.observable.shallow({ value: [] }), []);
|
|
56
|
+
const RenderNestedDrawer = React.memo((props) => {
|
|
57
|
+
const { index } = props;
|
|
58
|
+
const [RenderDrawer, setRenderDrawer] = React.useState(null);
|
|
59
|
+
React.useEffect(() => {
|
|
60
|
+
(0, import__.autorun)(() => {
|
|
61
|
+
const list = drawerList.value;
|
|
62
|
+
if (list[index] && RenderDrawer !== list[index]) {
|
|
63
|
+
setRenderDrawer(list[index]);
|
|
64
|
+
}
|
|
65
|
+
if (!list[index]) {
|
|
66
|
+
setRenderDrawer(null);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}, [RenderDrawer, index]);
|
|
70
|
+
if (!RenderDrawer) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return /* @__PURE__ */ React.createElement(RenderDrawer, null, /* @__PURE__ */ React.createElement(RenderNestedDrawer, { index: index + 1 }));
|
|
74
|
+
});
|
|
75
|
+
RenderNestedDrawer.displayName = "RenderNestedDrawer";
|
|
56
76
|
const open = /* @__PURE__ */ __name((config, flowContext) => {
|
|
57
77
|
var _a, _b;
|
|
58
|
-
uuid += 1;
|
|
59
78
|
const drawerRef = React.createRef();
|
|
60
79
|
let closeFunc;
|
|
61
80
|
let resolvePromise;
|
|
@@ -64,7 +83,7 @@ function useDrawer() {
|
|
|
64
83
|
});
|
|
65
84
|
let currentFooter = null;
|
|
66
85
|
let currentHeader = null;
|
|
67
|
-
const FooterComponent = /* @__PURE__ */ __name(({ children
|
|
86
|
+
const FooterComponent = /* @__PURE__ */ __name(({ children }) => {
|
|
68
87
|
React.useEffect(() => {
|
|
69
88
|
var _a2;
|
|
70
89
|
currentFooter = children;
|
|
@@ -77,7 +96,7 @@ function useDrawer() {
|
|
|
77
96
|
}, [children]);
|
|
78
97
|
return null;
|
|
79
98
|
}, "FooterComponent");
|
|
80
|
-
const HeaderComponent = /* @__PURE__ */ __name((
|
|
99
|
+
const HeaderComponent = /* @__PURE__ */ __name((props) => {
|
|
81
100
|
React.useEffect(() => {
|
|
82
101
|
var _a2;
|
|
83
102
|
currentHeader = props;
|
|
@@ -126,11 +145,6 @@ function useDrawer() {
|
|
|
126
145
|
navigation: (_a = config.inputArgs) == null ? void 0 : _a.navigation
|
|
127
146
|
};
|
|
128
147
|
const ctx = new import_flowContext.FlowContext();
|
|
129
|
-
ctx.defineProperty("view", {
|
|
130
|
-
get: /* @__PURE__ */ __name(() => currentDrawer, "get"),
|
|
131
|
-
meta: (0, import_createViewMeta.createViewMeta)(ctx, () => currentDrawer),
|
|
132
|
-
resolveOnServer: /* @__PURE__ */ __name((p) => p === "record" || p.startsWith("record."), "resolveOnServer")
|
|
133
|
-
});
|
|
134
148
|
const scopedEngine = (0, import_ViewScopedFlowEngine.createViewScopedEngine)(flowContext.engine);
|
|
135
149
|
ctx.defineProperty("engine", { value: scopedEngine });
|
|
136
150
|
ctx.addDelegate(scopedEngine.context);
|
|
@@ -139,8 +153,14 @@ function useDrawer() {
|
|
|
139
153
|
} else {
|
|
140
154
|
ctx.addDelegate(flowContext.engine.context);
|
|
141
155
|
}
|
|
142
|
-
|
|
143
|
-
(
|
|
156
|
+
ctx.defineProperty("view", {
|
|
157
|
+
get: /* @__PURE__ */ __name(() => currentDrawer, "get"),
|
|
158
|
+
// meta: createViewMeta(ctx),
|
|
159
|
+
resolveOnServer: /* @__PURE__ */ __name((p) => p === "record" || p.startsWith("record."), "resolveOnServer")
|
|
160
|
+
});
|
|
161
|
+
(0, import_createViewMeta.registerPopupVariable)(ctx, currentDrawer);
|
|
162
|
+
const DrawerWithContext = React.memo(
|
|
163
|
+
(0, import__.observer)((props) => {
|
|
144
164
|
var _a2, _b2, _c, _d;
|
|
145
165
|
const mountedRef = React.useRef(false);
|
|
146
166
|
const rawContent = typeof config.content === "function" ? config.content(currentDrawer, ctx) : config.content;
|
|
@@ -172,13 +192,12 @@ function useDrawer() {
|
|
|
172
192
|
content,
|
|
173
193
|
props.children
|
|
174
194
|
);
|
|
175
|
-
}
|
|
176
|
-
{
|
|
177
|
-
displayName: "DrawerWithContext"
|
|
178
|
-
}
|
|
195
|
+
})
|
|
179
196
|
);
|
|
180
|
-
|
|
181
|
-
|
|
197
|
+
DrawerWithContext.displayName = "DrawerWithContext";
|
|
198
|
+
const RenderDrawer = React.memo(({ children }) => /* @__PURE__ */ React.createElement(import_provider.FlowEngineProvider, { engine: scopedEngine }, /* @__PURE__ */ React.createElement(import_FlowContextProvider.FlowViewContextProvider, { context: ctx }, /* @__PURE__ */ React.createElement(DrawerWithContext, null, children))));
|
|
199
|
+
RenderDrawer.displayName = "RenderDrawer";
|
|
200
|
+
closeFunc = (_b = holderRef.current) == null ? void 0 : _b.patchElement(RenderDrawer);
|
|
182
201
|
return Object.assign(promise, currentDrawer);
|
|
183
202
|
}, "open");
|
|
184
203
|
const api = React.useMemo(() => ({ open }), []);
|
|
@@ -186,15 +205,10 @@ function useDrawer() {
|
|
|
186
205
|
React.forwardRef((props, ref) => {
|
|
187
206
|
const [elements, patchElement] = (0, import_usePatchElement.default)();
|
|
188
207
|
React.useImperativeHandle(ref, () => ({ patchElement }), [patchElement]);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return elements.reduceRight((children, renderElement) => {
|
|
194
|
-
return renderElement(children);
|
|
195
|
-
}, null);
|
|
196
|
-
}, "renderNestedElements");
|
|
197
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, renderNestedElements());
|
|
208
|
+
React.useEffect(() => {
|
|
209
|
+
drawerList.value = elements;
|
|
210
|
+
}, [elements]);
|
|
211
|
+
return /* @__PURE__ */ React.createElement(RenderNestedDrawer, { index: 0 });
|
|
198
212
|
})
|
|
199
213
|
);
|
|
200
214
|
return [api, /* @__PURE__ */ React.createElement(ElementsHolder, { key: "drawer-holder", ref: holderRef })];
|
package/lib/views/usePage.d.ts
CHANGED
|
@@ -9,19 +9,19 @@
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
export declare function usePage(): (React.JSX.Element | {
|
|
11
11
|
open: (config: any, flowContext: any) => Promise<unknown> & {
|
|
12
|
-
type:
|
|
12
|
+
type: "embed";
|
|
13
13
|
inputArgs: any;
|
|
14
14
|
preventClose: boolean;
|
|
15
15
|
destroy: () => void;
|
|
16
16
|
update: (newConfig: any) => void;
|
|
17
17
|
close: (result?: any, force?: boolean) => void;
|
|
18
|
-
Header:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
children
|
|
24
|
-
}
|
|
18
|
+
Header: React.FC<{
|
|
19
|
+
title?: React.ReactNode;
|
|
20
|
+
extra?: React.ReactNode;
|
|
21
|
+
}>;
|
|
22
|
+
Footer: React.FC<{
|
|
23
|
+
children?: React.ReactNode;
|
|
24
|
+
}>;
|
|
25
25
|
setFooter: (footer: React.ReactNode) => void;
|
|
26
26
|
setHeader: (header: {
|
|
27
27
|
title?: React.ReactNode;
|
package/lib/views/usePage.js
CHANGED
|
@@ -69,7 +69,7 @@ function usePage() {
|
|
|
69
69
|
const promise = new Promise((resolve) => {
|
|
70
70
|
resolvePromise = resolve;
|
|
71
71
|
});
|
|
72
|
-
const FooterComponent = /* @__PURE__ */ __name(({ children
|
|
72
|
+
const FooterComponent = /* @__PURE__ */ __name(({ children }) => {
|
|
73
73
|
import_react.default.useEffect(() => {
|
|
74
74
|
var _a2;
|
|
75
75
|
(_a2 = pageRef.current) == null ? void 0 : _a2.setFooter(children);
|
|
@@ -80,7 +80,7 @@ function usePage() {
|
|
|
80
80
|
}, [children]);
|
|
81
81
|
return null;
|
|
82
82
|
}, "FooterComponent");
|
|
83
|
-
const HeaderComponent = /* @__PURE__ */ __name((
|
|
83
|
+
const HeaderComponent = /* @__PURE__ */ __name((props) => {
|
|
84
84
|
import_react.default.useEffect(() => {
|
|
85
85
|
var _a2;
|
|
86
86
|
(_a2 = pageRef.current) == null ? void 0 : _a2.setHeader(props);
|
|
@@ -126,11 +126,6 @@ function usePage() {
|
|
|
126
126
|
navigation: (_a = config.inputArgs) == null ? void 0 : _a.navigation
|
|
127
127
|
};
|
|
128
128
|
const ctx = new import_flowContext.FlowContext();
|
|
129
|
-
ctx.defineProperty("view", {
|
|
130
|
-
get: /* @__PURE__ */ __name(() => currentPage, "get"),
|
|
131
|
-
meta: (0, import_createViewMeta.createViewMeta)(ctx, () => currentPage),
|
|
132
|
-
resolveOnServer: /* @__PURE__ */ __name((p) => p === "record" || p.startsWith("record."), "resolveOnServer")
|
|
133
|
-
});
|
|
134
129
|
const scopedEngine = (0, import_ViewScopedFlowEngine.createViewScopedEngine)(flowContext.engine);
|
|
135
130
|
ctx.defineProperty("engine", { value: scopedEngine });
|
|
136
131
|
ctx.addDelegate(scopedEngine.context);
|
|
@@ -139,6 +134,12 @@ function usePage() {
|
|
|
139
134
|
} else {
|
|
140
135
|
ctx.addDelegate(flowContext.engine.context);
|
|
141
136
|
}
|
|
137
|
+
ctx.defineProperty("view", {
|
|
138
|
+
get: /* @__PURE__ */ __name(() => currentPage, "get"),
|
|
139
|
+
// meta: createViewMeta(ctx),
|
|
140
|
+
resolveOnServer: /* @__PURE__ */ __name((p) => p === "record" || p.startsWith("record."), "resolveOnServer")
|
|
141
|
+
});
|
|
142
|
+
(0, import_createViewMeta.registerPopupVariable)(ctx, currentPage);
|
|
142
143
|
const PageWithContext = (0, import__.observer)(
|
|
143
144
|
() => {
|
|
144
145
|
var _a2, _b2, _c2, _d;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/flow-engine",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.30",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A standalone flow engine for NocoBase, managing workflows, models, and actions.",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@formily/antd-v5": "1.x",
|
|
10
10
|
"@formily/reactive": "2.x",
|
|
11
|
-
"@nocobase/sdk": "
|
|
11
|
+
"@nocobase/sdk": "2.0.0-alpha.30",
|
|
12
|
+
"@nocobase/shared": "2.0.0-alpha.30",
|
|
12
13
|
"ahooks": "^3.7.2",
|
|
13
14
|
"dompurify": "^3.0.2",
|
|
14
15
|
"lodash": "^4.x",
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
"slate": "^0.103.0",
|
|
18
19
|
"slate-history": "^0.109.0",
|
|
19
20
|
"slate-react": "^0.110.3",
|
|
21
|
+
"sucrase": "^3.35.0",
|
|
20
22
|
"uid": "^2.0.2"
|
|
21
23
|
},
|
|
22
24
|
"peerDependencies": {
|
|
@@ -33,5 +35,5 @@
|
|
|
33
35
|
],
|
|
34
36
|
"author": "NocoBase Team",
|
|
35
37
|
"license": "AGPL-3.0",
|
|
36
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "cdac55c9cdf0dbdbe57a21815f323b975792bfc0"
|
|
37
39
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { FlowEngine } from './flowEngine';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* BlockScopedFlowEngine(区块作用域引擎)
|
|
14
|
+
*
|
|
15
|
+
* 设计目标:
|
|
16
|
+
* - 仅在“区块”作用域内隔离“模型实例表”和“事件缓存”;
|
|
17
|
+
* - 其余能力(动作/事件/模型类/资源/仓库/设置/日志/翻译等)全部直接代理到父引擎;
|
|
18
|
+
* - 使用 Proxy 实现“最小代理”,保持与父引擎的全局一致性。
|
|
19
|
+
*
|
|
20
|
+
* 注意:
|
|
21
|
+
* - 本地化的字段仅有:`_modelInstances`、`_applyFlowCache`、`executor`、`context`、栈指针;
|
|
22
|
+
* - 其它字段/方法均通过 Proxy 转发到父引擎;
|
|
23
|
+
* - 这样可满足“同一 uid 的模型可在不同区块隔离出现(实例/缓存隔离)”与“共享全局注册/仓库”的诉求。
|
|
24
|
+
*/
|
|
25
|
+
export function createBlockScopedEngine(parent: FlowEngine): FlowEngine {
|
|
26
|
+
const local = new FlowEngine();
|
|
27
|
+
if (parent.modelRepository) {
|
|
28
|
+
local.setModelRepository(parent.modelRepository);
|
|
29
|
+
}
|
|
30
|
+
// 继承父级上下文能力
|
|
31
|
+
local.context.addDelegate(parent.context);
|
|
32
|
+
|
|
33
|
+
// 覆盖 unlinkFromStack:BlockScoped 引擎被移除时,修复前后指针,避免“截断”后续视图/作用域
|
|
34
|
+
const originalUnlink = local.unlinkFromStack.bind(local);
|
|
35
|
+
local.unlinkFromStack = function () {
|
|
36
|
+
// 修复指针:prev -> next,next -> prev,然后清理自身指针
|
|
37
|
+
// 若不这么做,移除位于中间的 block 引擎会导致后续整段链丢失
|
|
38
|
+
const prev = (local as any)._previousEngine as FlowEngine | undefined;
|
|
39
|
+
const next = (local as any)._nextEngine as FlowEngine | undefined;
|
|
40
|
+
if (prev) (prev as any)._nextEngine = next;
|
|
41
|
+
if (next) (next as any)._previousEngine = prev;
|
|
42
|
+
(local as any)._previousEngine = undefined as any;
|
|
43
|
+
(local as any)._nextEngine = undefined as any;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// 默认全部代理到父引擎,只有少数字段(实例/缓存/执行器/上下文/链表指针)使用本地值
|
|
47
|
+
const localOnly = new Set<keyof FlowEngine | string>([
|
|
48
|
+
'_modelInstances',
|
|
49
|
+
'_applyFlowCache',
|
|
50
|
+
'executor',
|
|
51
|
+
'context',
|
|
52
|
+
'previousEngine',
|
|
53
|
+
'nextEngine',
|
|
54
|
+
// 栈指针维护方法需要在本地执行,而非代理到父引擎
|
|
55
|
+
'unlinkFromStack',
|
|
56
|
+
'linkAfter',
|
|
57
|
+
'_previousEngine',
|
|
58
|
+
'_nextEngine',
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
const handler: ProxyHandler<FlowEngine> = {
|
|
62
|
+
get(target, prop: string, receiver) {
|
|
63
|
+
if (localOnly.has(prop)) {
|
|
64
|
+
return Reflect.get(target, prop, receiver);
|
|
65
|
+
}
|
|
66
|
+
const value = Reflect.get(parent, prop, receiver);
|
|
67
|
+
if (prop === 'registerModels' && typeof value === 'function') {
|
|
68
|
+
return value.bind(parent);
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
},
|
|
72
|
+
set(target, prop: string, value: unknown) {
|
|
73
|
+
if (localOnly.has(prop)) {
|
|
74
|
+
return Reflect.set(target, prop, value);
|
|
75
|
+
}
|
|
76
|
+
return Reflect.set(parent, prop, value);
|
|
77
|
+
},
|
|
78
|
+
has(target, prop: string) {
|
|
79
|
+
return prop in target || prop in parent;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// 与父引擎形成栈式关系,便于在多层作用域间进行全局查找
|
|
84
|
+
local.linkAfter(parent);
|
|
85
|
+
return new Proxy(local, handler) as FlowEngine;
|
|
86
|
+
}
|
|
@@ -18,13 +18,15 @@ export function FlowContextProvider(props: { children: React.ReactNode; context:
|
|
|
18
18
|
return <FlowReactContext.Provider value={props.context}>{props.children}</FlowReactContext.Provider>;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export
|
|
21
|
+
export const FlowViewContextProvider = React.memo((props: { children: React.ReactNode; context: FlowContext }) => {
|
|
22
22
|
return (
|
|
23
23
|
<FlowViewContext.Provider value={props.context}>
|
|
24
24
|
<FlowReactContext.Provider value={props.context}>{props.children}</FlowReactContext.Provider>
|
|
25
25
|
</FlowViewContext.Provider>
|
|
26
26
|
);
|
|
27
|
-
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
FlowViewContextProvider.displayName = 'FlowViewContextProvider';
|
|
28
30
|
|
|
29
31
|
export function useFlowContext<T = FlowEngineContext>() {
|
|
30
32
|
return useContext(FlowReactContext) as T;
|
package/src/JSRunner.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { FlowEngine } from './flowEngine';
|
|
|
13
13
|
* ViewScopedFlowEngine(视图作用域引擎)
|
|
14
14
|
*
|
|
15
15
|
* 设计目标:
|
|
16
|
-
* - 仅在视图(dialog/drawer/embed
|
|
16
|
+
* - 仅在视图(dialog/drawer/embed)作用域内隔离“模型实例表”和“事件缓存”;
|
|
17
17
|
* - 其余能力(动作/事件/模型类/资源/仓库/设置/日志/翻译等)全部直接代理到父引擎;
|
|
18
18
|
* - 使用 Proxy 实现“最小代理”,保持与父引擎的全局一致性。
|
|
19
19
|
*
|
|
@@ -7,86 +7,95 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
10
11
|
import { JSRunner } from '../JSRunner';
|
|
11
12
|
|
|
12
13
|
describe('JSRunner', () => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return x + 5;
|
|
18
|
-
`);
|
|
19
|
-
expect(result.success).toBe(true);
|
|
20
|
-
expect(result.value).toBe(15);
|
|
14
|
+
let originalSearch: string;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
originalSearch = globalThis.location?.search || '';
|
|
21
18
|
});
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
// 恢复 URL 查询参数,避免影响其他用例
|
|
22
|
+
try {
|
|
23
|
+
if (typeof window !== 'undefined' && typeof window.history?.replaceState === 'function') {
|
|
24
|
+
window.history.replaceState({}, '', originalSearch || '');
|
|
25
|
+
}
|
|
26
|
+
} catch (_) {
|
|
27
|
+
// ignore
|
|
28
|
+
}
|
|
29
|
+
vi.restoreAllMocks();
|
|
28
30
|
});
|
|
29
31
|
|
|
30
|
-
it('
|
|
32
|
+
it('executes simple code and returns value', async () => {
|
|
31
33
|
const runner = new JSRunner();
|
|
32
|
-
const result = await runner.run(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
`);
|
|
36
|
-
expect(result.success).toBe(false);
|
|
37
|
-
expect(result.error).toBeInstanceOf(Error);
|
|
38
|
-
expect(result.error.message).toBe('Test error');
|
|
34
|
+
const result = await runner.run('return 1 + 2 + 3');
|
|
35
|
+
expect(result.success).toBe(true);
|
|
36
|
+
expect(result.value).toBe(6);
|
|
39
37
|
});
|
|
40
38
|
|
|
41
|
-
it('
|
|
42
|
-
const runner = new JSRunner({
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
expect(
|
|
50
|
-
expect(
|
|
39
|
+
it('injects custom globals and supports register()', async () => {
|
|
40
|
+
const runner = new JSRunner({ globals: { foo: 42 } });
|
|
41
|
+
const res1 = await runner.run('return foo');
|
|
42
|
+
expect(res1.success).toBe(true);
|
|
43
|
+
expect(res1.value).toBe(42);
|
|
44
|
+
|
|
45
|
+
runner.register('bar', 'baz');
|
|
46
|
+
const res2 = await runner.run('return bar');
|
|
47
|
+
expect(res2.success).toBe(true);
|
|
48
|
+
expect(res2.value).toBe('baz');
|
|
51
49
|
});
|
|
52
50
|
|
|
53
|
-
it('
|
|
51
|
+
it('exposes console in sandbox by default', async () => {
|
|
54
52
|
const runner = new JSRunner();
|
|
55
|
-
runner.
|
|
56
|
-
const result = await runner.run(`
|
|
57
|
-
return globalVar + 8;
|
|
58
|
-
`);
|
|
53
|
+
const result = await runner.run('return typeof console !== "undefined"');
|
|
59
54
|
expect(result.success).toBe(true);
|
|
60
|
-
expect(result.value).toBe(
|
|
55
|
+
expect(result.value).toBe(true);
|
|
61
56
|
});
|
|
62
57
|
|
|
63
|
-
it('
|
|
58
|
+
it('supports timers (setTimeout) inside evaluated code', async () => {
|
|
64
59
|
const runner = new JSRunner();
|
|
65
60
|
const result = await runner.run(`
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
const data = await fetchData();
|
|
70
|
-
return data + 50;
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
setTimeout(() => resolve('ok'), 20);
|
|
63
|
+
});
|
|
71
64
|
`);
|
|
72
65
|
expect(result.success).toBe(true);
|
|
73
|
-
expect(result.value).toBe(
|
|
66
|
+
expect(result.value).toBe('ok');
|
|
74
67
|
});
|
|
75
68
|
|
|
76
|
-
it('
|
|
69
|
+
it('handles thrown errors and marks as non-timeout', async () => {
|
|
70
|
+
const spy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
77
71
|
const runner = new JSRunner();
|
|
78
|
-
const result = await runner.run('');
|
|
79
|
-
expect(result.success).toBe(
|
|
80
|
-
expect(result.
|
|
72
|
+
const result = await runner.run('throw new Error("boom")');
|
|
73
|
+
expect(result.success).toBe(false);
|
|
74
|
+
expect(result.timeout).toBe(false);
|
|
75
|
+
expect(result.error).toBeInstanceOf(Error);
|
|
76
|
+
expect((result.error as Error).message).toBe('boom');
|
|
77
|
+
expect(spy).toHaveBeenCalled();
|
|
81
78
|
});
|
|
82
79
|
|
|
83
|
-
it('
|
|
84
|
-
const runner = new JSRunner();
|
|
80
|
+
it('respects timeout setting and marks timeout=true', async () => {
|
|
81
|
+
const runner = new JSRunner({ timeoutMs: 10 });
|
|
85
82
|
const result = await runner.run(`
|
|
86
|
-
|
|
87
|
-
return undefined;
|
|
83
|
+
return new Promise((resolve) => setTimeout(() => resolve('late'), 100));
|
|
88
84
|
`);
|
|
85
|
+
expect(result.success).toBe(false);
|
|
86
|
+
expect(result.timeout).toBe(true);
|
|
87
|
+
expect(result.error).toBeInstanceOf(Error);
|
|
88
|
+
expect((result.error as Error).message).toBe('Execution timed out');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('skips execution when URL contains skipRunJs=true', async () => {
|
|
92
|
+
// 模拟预览模式下通过 URL 参数跳过代码执行
|
|
93
|
+
if (typeof window !== 'undefined' && typeof window.history?.pushState === 'function') {
|
|
94
|
+
window.history.pushState({}, '', '?skipRunJs=true');
|
|
95
|
+
}
|
|
96
|
+
const runner = new JSRunner();
|
|
97
|
+
const result = await runner.run('throw new Error("should not run")');
|
|
89
98
|
expect(result.success).toBe(true);
|
|
90
|
-
expect(result.value).
|
|
99
|
+
expect(result.value).toBeNull();
|
|
91
100
|
});
|
|
92
101
|
});
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
11
|
+
import { APIClient as SDKApiClient } from '@nocobase/sdk';
|
|
12
|
+
import { FlowEngine } from '../flowEngine';
|
|
13
|
+
import { createBlockScopedEngine } from '../BlockScopedFlowEngine';
|
|
14
|
+
import { FlowModel } from '../models';
|
|
15
|
+
|
|
16
|
+
describe('BlockScopedFlowEngine', () => {
|
|
17
|
+
it('shares global actions/events and model classes with parent', async () => {
|
|
18
|
+
const parent = new FlowEngine();
|
|
19
|
+
// 在运行时 host app 会注入 api,这里补一个最小 mock,避免偶发访问 ctx.auth 抛错
|
|
20
|
+
const api = new SDKApiClient({ storageType: 'memory' });
|
|
21
|
+
api.auth.role = 'guest';
|
|
22
|
+
api.auth.locale = 'en-US';
|
|
23
|
+
api.auth.token = 't';
|
|
24
|
+
parent.context.defineProperty('api', { value: api });
|
|
25
|
+
parent.registerActions({
|
|
26
|
+
ping: {
|
|
27
|
+
name: 'ping',
|
|
28
|
+
handler: () => 'pong',
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
const child = createBlockScopedEngine(parent);
|
|
32
|
+
|
|
33
|
+
// child can read parent's action
|
|
34
|
+
expect(child.getAction('ping')).toBeDefined();
|
|
35
|
+
|
|
36
|
+
// registering via child should affect parent
|
|
37
|
+
child.registerActions({ pong: { name: 'pong', handler: () => 'ok' } });
|
|
38
|
+
expect(parent.getAction('pong')).toBeDefined();
|
|
39
|
+
|
|
40
|
+
// model class resolution is proxied
|
|
41
|
+
class TestModel extends FlowModel {}
|
|
42
|
+
parent.registerModels({ TestModel });
|
|
43
|
+
expect(child.getModelClass('TestModel')).toBeDefined();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('isolates model instances map and beforeRender cache across engines with identical model uid', async () => {
|
|
47
|
+
const parent = new FlowEngine();
|
|
48
|
+
// 提供最小 api mock,满足 ctx.auth 相关 getter
|
|
49
|
+
const api = new SDKApiClient({ storageType: 'memory' });
|
|
50
|
+
api.auth.role = 'guest';
|
|
51
|
+
api.auth.locale = 'en-US';
|
|
52
|
+
api.auth.token = 't';
|
|
53
|
+
parent.context.defineProperty('api', { value: api });
|
|
54
|
+
const child = createBlockScopedEngine(parent);
|
|
55
|
+
|
|
56
|
+
let count = 0;
|
|
57
|
+
class CounterModel extends FlowModel {}
|
|
58
|
+
CounterModel.registerFlow({
|
|
59
|
+
key: 'autoCounter',
|
|
60
|
+
steps: {
|
|
61
|
+
s1: {
|
|
62
|
+
handler: async () => {
|
|
63
|
+
count += 1;
|
|
64
|
+
return count;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const uid = 'model-uid-cache';
|
|
71
|
+
const pm = parent.createModel<CounterModel>({ use: CounterModel, uid });
|
|
72
|
+
const cm = child.createModel<CounterModel>({ use: CounterModel, uid });
|
|
73
|
+
|
|
74
|
+
await pm.dispatchEvent('beforeRender');
|
|
75
|
+
expect(count).toBe(1);
|
|
76
|
+
|
|
77
|
+
// If cache was shared, the next call would hit cache and not increment.
|
|
78
|
+
await cm.dispatchEvent('beforeRender');
|
|
79
|
+
expect(count).toBe(2);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('stacks engines and repairs chain when unlinking a middle block-scoped engine', () => {
|
|
83
|
+
const root = new FlowEngine();
|
|
84
|
+
// 提供最小 api mock,满足 ctx.auth 相关 getter
|
|
85
|
+
const api = new SDKApiClient({ storageType: 'memory' });
|
|
86
|
+
api.auth.role = 'guest';
|
|
87
|
+
api.auth.locale = 'en-US';
|
|
88
|
+
api.auth.token = 't';
|
|
89
|
+
root.context.defineProperty('api', { value: api });
|
|
90
|
+
const c1 = createBlockScopedEngine(root);
|
|
91
|
+
const c2 = createBlockScopedEngine(root);
|
|
92
|
+
const c3 = createBlockScopedEngine(root);
|
|
93
|
+
|
|
94
|
+
// chain root -> c1 -> c2 -> c3
|
|
95
|
+
expect(root.nextEngine).toBeTruthy();
|
|
96
|
+
expect(root.nextEngine?.nextEngine).toBeTruthy();
|
|
97
|
+
expect(root.nextEngine?.nextEngine?.nextEngine).toBeTruthy();
|
|
98
|
+
|
|
99
|
+
// unlink middle (c2) should link c1 <-> c3 and keep the tail intact
|
|
100
|
+
c2.unlinkFromStack();
|
|
101
|
+
|
|
102
|
+
// root.nextEngine 指向的是被代理的本地 FlowEngine 实例,不与 c1 的 Proxy 引用相等
|
|
103
|
+
// 这里通过前后指针关系来校验链修复是否正确
|
|
104
|
+
const first = root.nextEngine;
|
|
105
|
+
const second = first?.nextEngine;
|
|
106
|
+
expect(first?.previousEngine).toBe(root);
|
|
107
|
+
expect(second?.previousEngine).toBe(first);
|
|
108
|
+
expect(second?.nextEngine).toBeUndefined();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('global model lookup traverses from top to root across stack', () => {
|
|
112
|
+
const root = new FlowEngine();
|
|
113
|
+
// 提供最小 api mock,满足 ctx.auth 相关 getter
|
|
114
|
+
const api = new SDKApiClient({ storageType: 'memory' });
|
|
115
|
+
api.auth.role = 'guest';
|
|
116
|
+
api.auth.locale = 'en-US';
|
|
117
|
+
api.auth.token = 't';
|
|
118
|
+
root.context.defineProperty('api', { value: api });
|
|
119
|
+
const c1 = createBlockScopedEngine(root);
|
|
120
|
+
const c2 = createBlockScopedEngine(root);
|
|
121
|
+
|
|
122
|
+
class TM extends FlowModel {}
|
|
123
|
+
const uid = 'same-uid-global-lookup';
|
|
124
|
+
const mRoot = root.createModel<TM>({ use: TM, uid });
|
|
125
|
+
const m1 = c1.createModel<TM>({ use: TM, uid });
|
|
126
|
+
const m2 = c2.createModel<TM>({ use: TM, uid });
|
|
127
|
+
|
|
128
|
+
// sanity: each scope returns its own when not global
|
|
129
|
+
expect(root.getModel(uid)).toBe(mRoot);
|
|
130
|
+
expect(c1.getModel(uid)).toBe(m1);
|
|
131
|
+
expect(c2.getModel(uid)).toBe(m2);
|
|
132
|
+
|
|
133
|
+
// global search from any engine hits the top-most engine's instance first
|
|
134
|
+
expect(root.getModel(uid, true)).toBe(m2);
|
|
135
|
+
expect(c1.getModel(uid, true)).toBe(m2);
|
|
136
|
+
expect(c2.getModel(uid, true)).toBe(m2);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('delegates saveModel to parent (concurrency gate sharing)', async () => {
|
|
140
|
+
const parent = new FlowEngine();
|
|
141
|
+
// 提供最小 api mock,满足 ctx.auth 相关 getter
|
|
142
|
+
const api = new SDKApiClient({ storageType: 'memory' });
|
|
143
|
+
api.auth.role = 'guest';
|
|
144
|
+
api.auth.locale = 'en-US';
|
|
145
|
+
api.auth.token = 't';
|
|
146
|
+
parent.context.defineProperty('api', { value: api });
|
|
147
|
+
const child = createBlockScopedEngine(parent);
|
|
148
|
+
const spy = vi.spyOn(parent, 'saveModel').mockResolvedValueOnce(true);
|
|
149
|
+
class T extends FlowModel {}
|
|
150
|
+
const m = child.createModel<T>({ use: T });
|
|
151
|
+
await child.saveModel(m);
|
|
152
|
+
expect(spy).toHaveBeenCalledOnce();
|
|
153
|
+
});
|
|
154
|
+
});
|