@nocobase/flow-engine 2.0.0-alpha.7 → 2.0.0-alpha.71

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.
Files changed (589) hide show
  1. package/lib/BlockScopedFlowEngine.d.ts +23 -0
  2. package/lib/BlockScopedFlowEngine.js +91 -0
  3. package/lib/FlowContextProvider.d.ts +2 -2
  4. package/lib/FlowContextProvider.js +3 -3
  5. package/lib/FlowDefinition.d.ts +6 -4
  6. package/lib/JSRunner.d.ts +6 -0
  7. package/lib/JSRunner.js +27 -1
  8. package/lib/ViewScopedFlowEngine.d.ts +1 -1
  9. package/lib/ViewScopedFlowEngine.js +18 -1
  10. package/lib/acl/Acl.d.ts +12 -12
  11. package/lib/acl/Acl.js +88 -30
  12. package/lib/components/DynamicFlowsEditor.js +2 -4
  13. package/lib/components/FieldModelRenderer.js +17 -9
  14. package/lib/components/FieldSkeleton.d.ts +10 -0
  15. package/lib/components/FieldSkeleton.js +64 -0
  16. package/lib/components/FlowContextSelector.js +19 -3
  17. package/lib/components/FlowModelRenderer.d.ts +4 -6
  18. package/lib/components/FlowModelRenderer.js +35 -53
  19. package/lib/components/FormItem.js +5 -1
  20. package/lib/components/MobilePopup.d.ts +20 -0
  21. package/lib/components/MobilePopup.js +102 -0
  22. package/lib/components/MobilePopup.style.d.ts +17 -0
  23. package/lib/components/MobilePopup.style.js +186 -0
  24. package/lib/components/common/withFlowDesignMode.d.ts +1 -1
  25. package/lib/components/common/withFlowDesignMode.js +5 -5
  26. package/lib/components/dnd/gridDragPlanner.d.ts +1 -0
  27. package/lib/components/dnd/gridDragPlanner.js +53 -1
  28. package/lib/components/index.d.ts +1 -0
  29. package/lib/components/index.js +3 -1
  30. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +71 -53
  31. package/lib/components/settings/wrappers/component/SelectWithTitle.d.ts +19 -0
  32. package/lib/components/settings/wrappers/component/SelectWithTitle.js +136 -0
  33. package/lib/components/settings/wrappers/component/SwitchWithTitle.d.ts +10 -0
  34. package/lib/components/settings/wrappers/component/SwitchWithTitle.js +111 -0
  35. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +233 -97
  36. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +71 -54
  37. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +2 -2
  38. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +63 -23
  39. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +13 -2
  40. package/lib/components/settings/wrappers/embedded/FlowSettings.js +42 -28
  41. package/lib/components/settings/wrappers/embedded/FlowsSettings.js +3 -3
  42. package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.js +52 -32
  43. package/lib/components/subModel/AddSubModelButton.d.ts +7 -0
  44. package/lib/components/subModel/AddSubModelButton.js +78 -8
  45. package/lib/components/subModel/LazyDropdown.js +14 -15
  46. package/lib/components/subModel/utils.d.ts +1 -1
  47. package/lib/components/subModel/utils.js +21 -11
  48. package/lib/components/variables/VariableInput.js +26 -6
  49. package/lib/components/variables/VariableTag.js +43 -2
  50. package/lib/components/variables/types.d.ts +2 -0
  51. package/lib/components/variables/utils.js +4 -2
  52. package/lib/data-source/index.d.ts +23 -4
  53. package/lib/data-source/index.js +135 -14
  54. package/lib/data-source/jioToJoiSchema.js +1 -0
  55. package/lib/emitter.d.ts +6 -0
  56. package/lib/emitter.js +12 -0
  57. package/lib/executor/FlowExecutor.d.ts +6 -6
  58. package/lib/executor/FlowExecutor.js +302 -99
  59. package/lib/flow-registry/GlobalFlowRegistry.d.ts +1 -0
  60. package/lib/flow-registry/GlobalFlowRegistry.js +3 -0
  61. package/lib/flow-registry/InstanceFlowRegistry.d.ts +1 -0
  62. package/lib/flow-registry/InstanceFlowRegistry.js +3 -0
  63. package/lib/flowContext.d.ts +105 -6
  64. package/lib/flowContext.js +447 -139
  65. package/lib/flowEngine.d.ts +71 -1
  66. package/lib/flowEngine.js +319 -16
  67. package/lib/flowSettings.d.ts +4 -3
  68. package/lib/flowSettings.js +45 -21
  69. package/lib/hooks/useApplyAutoFlows.d.ts +1 -0
  70. package/lib/hooks/useApplyAutoFlows.js +3 -2
  71. package/lib/index.d.ts +14 -3
  72. package/lib/index.js +54 -7
  73. package/lib/locale/de-DE.json +62 -0
  74. package/lib/locale/en-US.json +57 -45
  75. package/lib/locale/es-ES.json +62 -0
  76. package/lib/locale/fr-FR.json +62 -0
  77. package/lib/locale/hu-HU.json +62 -0
  78. package/lib/locale/id-ID.json +62 -0
  79. package/lib/locale/index.d.ts +114 -90
  80. package/lib/locale/it-IT.json +62 -0
  81. package/lib/locale/ja-JP.json +62 -0
  82. package/lib/locale/ko-KR.json +62 -0
  83. package/lib/locale/nl-NL.json +62 -0
  84. package/lib/locale/pt-BR.json +62 -0
  85. package/lib/locale/ru-RU.json +62 -0
  86. package/lib/locale/tr-TR.json +62 -0
  87. package/lib/locale/uk-UA.json +62 -0
  88. package/lib/locale/vi-VN.json +62 -0
  89. package/lib/locale/zh-CN.json +58 -46
  90. package/lib/locale/zh-TW.json +62 -0
  91. package/lib/models/CollectionFieldModel.d.ts +7 -2
  92. package/lib/models/CollectionFieldModel.js +63 -16
  93. package/lib/models/flowModel.d.ts +76 -32
  94. package/lib/models/flowModel.js +300 -112
  95. package/lib/models/forkFlowModel.d.ts +8 -4
  96. package/lib/models/forkFlowModel.js +38 -8
  97. package/lib/provider.d.ts +3 -1
  98. package/lib/provider.js +14 -11
  99. package/lib/reactive/index.d.ts +10 -0
  100. package/lib/{runjs-context/snippets/global/api-request-post.snippet.js → reactive/index.js} +14 -15
  101. package/lib/reactive/observer.d.ts +19 -0
  102. package/lib/reactive/observer.js +109 -0
  103. package/lib/resources/baseRecordResource.d.ts +6 -0
  104. package/lib/resources/baseRecordResource.js +38 -3
  105. package/lib/resources/multiRecordResource.d.ts +5 -2
  106. package/lib/resources/multiRecordResource.js +26 -10
  107. package/lib/resources/singleRecordResource.js +8 -3
  108. package/lib/resources/sqlResource.d.ts +5 -3
  109. package/lib/resources/sqlResource.js +30 -28
  110. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +1 -6
  111. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +37 -20
  112. package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +1 -6
  113. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +46 -33
  114. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +1 -2
  115. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +14 -15
  116. package/lib/runjs-context/contexts/{LinkageRunJSContext.d.ts → JSColumnRunJSContext.d.ts} +6 -3
  117. package/lib/runjs-context/contexts/JSColumnRunJSContext.js +78 -0
  118. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.d.ts +16 -0
  119. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +125 -0
  120. package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +1 -6
  121. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +28 -24
  122. package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +1 -6
  123. package/lib/runjs-context/contexts/JSItemRunJSContext.js +34 -20
  124. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +1 -2
  125. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +16 -17
  126. package/lib/runjs-context/contexts/base.d.ts +9 -0
  127. package/lib/runjs-context/contexts/base.js +879 -0
  128. package/lib/runjs-context/contributions.d.ts +33 -0
  129. package/lib/runjs-context/contributions.js +88 -0
  130. package/lib/runjs-context/helpers.d.ts +5 -2
  131. package/lib/runjs-context/helpers.js +36 -27
  132. package/lib/runjs-context/registry.d.ts +7 -4
  133. package/lib/runjs-context/registry.js +10 -42
  134. package/lib/runjs-context/setup.d.ts +9 -0
  135. package/lib/runjs-context/setup.js +88 -0
  136. package/lib/runjs-context/snippets/global/{copy-record-json.snippet.js → api-request.snippet.js} +25 -10
  137. package/lib/runjs-context/snippets/global/clipboard-copy-text.snippet.js +61 -0
  138. package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.js → import-esm.snippet.js} +26 -12
  139. package/lib/runjs-context/snippets/global/message-error.snippet.js +6 -0
  140. package/lib/runjs-context/snippets/global/message-success.snippet.js +6 -0
  141. package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +3 -8
  142. package/lib/runjs-context/snippets/global/notification-open.snippet.js +8 -1
  143. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +10 -3
  144. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +10 -3
  145. package/lib/runjs-context/snippets/global/query-selector.snippet.js +53 -0
  146. package/lib/runjs-context/snippets/global/require-amd.snippet.d.ts +11 -0
  147. package/lib/runjs-context/snippets/global/{requireAsync.snippet.js → require-amd.snippet.js} +16 -13
  148. package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +3 -8
  149. package/lib/runjs-context/snippets/global/window-open.snippet.js +8 -1
  150. package/lib/runjs-context/snippets/index.d.ts +24 -3
  151. package/lib/runjs-context/snippets/index.js +183 -40
  152. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.d.ts +11 -0
  153. package/lib/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.js +11 -2
  154. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.d.ts +11 -0
  155. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +64 -0
  156. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.d.ts +11 -0
  157. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +99 -0
  158. package/lib/runjs-context/snippets/{libs → scene/block}/echarts-init.snippet.js +24 -7
  159. package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.d.ts +11 -0
  160. package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.js +65 -0
  161. package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.d.ts +11 -0
  162. package/lib/runjs-context/snippets/scene/{jsblock → block}/render-button-handler.snippet.js +17 -9
  163. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.d.ts +11 -0
  164. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +57 -0
  165. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.d.ts +11 -0
  166. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.js +71 -0
  167. package/lib/runjs-context/snippets/scene/block/render-react-jsx.snippet.d.ts +11 -0
  168. package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.js → block/render-react-jsx.snippet.js} +26 -13
  169. package/lib/runjs-context/snippets/scene/block/render-react.snippet.d.ts +11 -0
  170. package/lib/runjs-context/snippets/scene/{jsblock → block}/render-react.snippet.js +18 -17
  171. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.d.ts +11 -0
  172. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +95 -0
  173. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.d.ts +11 -0
  174. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +84 -0
  175. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.d.ts +11 -0
  176. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +60 -0
  177. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.d.ts +11 -0
  178. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +283 -0
  179. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.d.ts +11 -0
  180. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +124 -0
  181. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.d.ts +11 -0
  182. package/lib/runjs-context/snippets/scene/{jsfield → detail}/color-by-value.snippet.js +13 -3
  183. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.d.ts +11 -0
  184. package/lib/runjs-context/snippets/{global → scene/detail}/copy-to-clipboard.snippet.js +28 -6
  185. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.d.ts +11 -0
  186. package/lib/runjs-context/snippets/scene/{jsfield → detail}/format-number.snippet.js +13 -3
  187. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.d.ts +11 -0
  188. package/lib/runjs-context/snippets/scene/{jsfield → detail}/innerHTML-value.snippet.js +13 -3
  189. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.d.ts +11 -0
  190. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +82 -0
  191. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.d.ts +11 -0
  192. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +80 -0
  193. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.d.ts +11 -0
  194. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +74 -0
  195. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.d.ts +11 -0
  196. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.js +63 -0
  197. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.d.ts +11 -0
  198. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +81 -0
  199. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.d.ts +11 -0
  200. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.js +64 -0
  201. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.d.ts +11 -0
  202. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.js +74 -0
  203. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.d.ts +11 -0
  204. package/lib/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.js +11 -2
  205. package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.d.ts +11 -0
  206. package/lib/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.js +12 -3
  207. package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.d.ts +11 -0
  208. package/lib/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.js +12 -3
  209. package/lib/runjs-context/snippets/scene/form/set-required.snippet.d.ts +11 -0
  210. package/lib/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.js +12 -3
  211. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.d.ts +11 -0
  212. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.js +67 -0
  213. package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.d.ts +11 -0
  214. package/lib/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.js +12 -3
  215. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.d.ts +11 -0
  216. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +64 -0
  217. package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.d.ts +11 -0
  218. package/lib/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.js +11 -2
  219. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.d.ts +11 -0
  220. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +79 -0
  221. package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.d.ts +11 -0
  222. package/lib/runjs-context/snippets/{global/log-json-record.snippet.js → scene/table/destroy-selected.snippet.js} +24 -11
  223. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.d.ts +11 -0
  224. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.js +64 -0
  225. package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.d.ts +11 -0
  226. package/lib/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.js +11 -2
  227. package/lib/runjs-context/snippets/types.d.ts +9 -1
  228. package/lib/runjsLibs.d.ts +28 -0
  229. package/lib/runjsLibs.js +532 -0
  230. package/lib/scheduler/ModelOperationScheduler.d.ts +53 -0
  231. package/lib/scheduler/ModelOperationScheduler.js +262 -0
  232. package/lib/types.d.ts +66 -7
  233. package/lib/types.js +4 -3
  234. package/lib/utils/associationObjectVariable.d.ts +32 -0
  235. package/lib/utils/associationObjectVariable.js +157 -0
  236. package/lib/utils/createCollectionContextMeta.d.ts +1 -1
  237. package/lib/utils/createCollectionContextMeta.js +9 -4
  238. package/lib/utils/createEphemeralContext.d.ts +13 -0
  239. package/lib/utils/createEphemeralContext.js +140 -0
  240. package/lib/utils/flows.d.ts +10 -0
  241. package/lib/{runjs-context/snippets/global/console-log-ctx.snippet.js → utils/flows.js} +21 -14
  242. package/lib/utils/index.d.ts +9 -3
  243. package/lib/utils/index.js +30 -2
  244. package/lib/utils/jsxTransform.d.ts +15 -0
  245. package/lib/utils/jsxTransform.js +68 -0
  246. package/lib/utils/params-resolvers.js +19 -12
  247. package/lib/utils/parsePathnameToViewParams.d.ts +1 -1
  248. package/lib/utils/parsePathnameToViewParams.js +41 -5
  249. package/lib/utils/pruneFilter.d.ts +21 -0
  250. package/lib/{runjs-context/snippets/global/try-catch-async.snippet.js → utils/pruneFilter.js} +24 -16
  251. package/lib/utils/resolveModuleUrl.d.ts +58 -0
  252. package/lib/utils/resolveModuleUrl.js +65 -0
  253. package/lib/utils/runjsModuleLoader.d.ts +58 -0
  254. package/lib/utils/runjsModuleLoader.js +422 -0
  255. package/lib/utils/runjsTemplateCompat.d.ts +35 -0
  256. package/lib/utils/runjsTemplateCompat.js +743 -0
  257. package/lib/utils/safeGlobals.d.ts +6 -8
  258. package/lib/utils/safeGlobals.js +169 -14
  259. package/lib/utils/schema-utils.d.ts +6 -0
  260. package/lib/utils/schema-utils.js +71 -6
  261. package/lib/utils/serverContextParams.d.ts +4 -0
  262. package/lib/utils/serverContextParams.js +2 -0
  263. package/lib/utils/translation.d.ts +4 -1
  264. package/lib/utils/translation.js +6 -2
  265. package/lib/utils/variablesParams.d.ts +22 -5
  266. package/lib/utils/variablesParams.js +141 -61
  267. package/lib/views/DialogComponent.js +1 -5
  268. package/lib/views/DrawerComponent.js +18 -9
  269. package/lib/views/PageComponent.js +5 -5
  270. package/lib/views/ViewNavigation.d.ts +11 -15
  271. package/lib/views/ViewNavigation.js +37 -19
  272. package/lib/views/createViewMeta.d.ts +27 -5
  273. package/lib/views/createViewMeta.js +338 -72
  274. package/lib/views/index.d.ts +1 -1
  275. package/lib/views/index.js +4 -0
  276. package/lib/views/useDialog.d.ts +10 -9
  277. package/lib/views/useDialog.js +46 -34
  278. package/lib/views/useDrawer.d.ts +10 -9
  279. package/lib/views/useDrawer.js +74 -48
  280. package/lib/views/usePage.d.ts +14 -9
  281. package/lib/views/usePage.js +82 -33
  282. package/lib/views/usePopover.js +4 -1
  283. package/lib/views/viewEvents.d.ts +17 -0
  284. package/lib/views/viewEvents.js +90 -0
  285. package/package.json +6 -3
  286. package/src/BlockScopedFlowEngine.ts +85 -0
  287. package/src/FlowContextProvider.tsx +4 -2
  288. package/src/JSRunner.ts +39 -1
  289. package/src/ViewScopedFlowEngine.ts +21 -1
  290. package/src/__tests__/JSRunner.test.ts +125 -52
  291. package/src/__tests__/blockScopedFlowEngine.test.ts +154 -0
  292. package/src/__tests__/createViewMeta.popup.test.ts +203 -0
  293. package/src/__tests__/flow-engine.test.ts +3 -0
  294. package/src/__tests__/flowContext.test.ts +160 -0
  295. package/src/__tests__/flowContextCreateJSRunner.test.ts +163 -0
  296. package/src/__tests__/flowEngine.dataSourceDirty.test.ts +63 -0
  297. package/src/__tests__/flowEngine.destroyModel.test.ts +74 -0
  298. package/src/__tests__/flowEngine.moveModel.test.ts +43 -0
  299. package/src/__tests__/flowEngine.removeModel.test.ts +72 -0
  300. package/src/__tests__/flowEngine.saveModel.test.ts +4 -0
  301. package/src/__tests__/flowModel.openView.navigation.test.ts +31 -2
  302. package/src/__tests__/flowRunJSContextDefine.test.ts +508 -0
  303. package/src/__tests__/flowSettings.open.test.tsx +71 -15
  304. package/src/__tests__/flowSettings.test.ts +2 -0
  305. package/src/__tests__/globalFlowRegistry.test.ts +1 -1
  306. package/src/__tests__/modelOperationScheduler.test.ts +346 -0
  307. package/src/__tests__/objectVariable.test.ts +464 -0
  308. package/src/__tests__/provider.test.tsx +0 -5
  309. package/src/__tests__/runjsContext.test.ts +219 -35
  310. package/src/__tests__/runjsContextImplementations.test.ts +217 -0
  311. package/src/__tests__/runjsContextRuntime.test.ts +269 -0
  312. package/src/__tests__/runjsEdgeCases.test.ts +281 -0
  313. package/src/__tests__/runjsExternalLibs.test.ts +242 -0
  314. package/src/__tests__/runjsLibsLazyLoading.test.ts +44 -0
  315. package/src/__tests__/runjsLocales.test.ts +39 -0
  316. package/src/__tests__/runjsPreprocessDefault.test.ts +49 -0
  317. package/src/__tests__/runjsRuntimeFeatures.test.ts +461 -0
  318. package/src/__tests__/runjsSnippets.test.ts +140 -0
  319. package/src/__tests__/viewScopedFlowEngine.test.ts +101 -3
  320. package/src/acl/Acl.tsx +85 -31
  321. package/src/acl/__tests__/Acl.test.tsx +43 -1
  322. package/src/components/DynamicFlowsEditor.tsx +0 -10
  323. package/src/components/FieldModelRenderer.tsx +22 -9
  324. package/src/components/FieldSkeleton.tsx +27 -0
  325. package/src/components/FlowContextSelector.tsx +20 -2
  326. package/src/components/FlowModelRenderer.tsx +52 -84
  327. package/src/components/FormItem.tsx +8 -1
  328. package/src/components/MobilePopup.style.ts +220 -0
  329. package/src/components/MobilePopup.tsx +86 -0
  330. package/src/components/__tests__/FlowModelRenderer.test.tsx +89 -0
  331. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +6 -6
  332. package/src/components/__tests__/gridDragPlanner.test.ts +141 -1
  333. package/src/components/common/withFlowDesignMode.tsx +5 -5
  334. package/src/components/dnd/gridDragPlanner.ts +60 -0
  335. package/src/components/index.ts +1 -0
  336. package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +34 -17
  337. package/src/components/settings/wrappers/component/SelectWithTitle.tsx +110 -0
  338. package/src/components/settings/wrappers/component/SwitchWithTitle.tsx +83 -0
  339. package/src/components/settings/wrappers/component/__tests__/InlineControls.test.tsx +74 -0
  340. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +272 -125
  341. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +34 -18
  342. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +56 -18
  343. package/src/components/settings/wrappers/contextual/StepSettings.tsx +1 -2
  344. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +13 -1
  345. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +624 -0
  346. package/src/components/settings/wrappers/embedded/FlowSettings.tsx +47 -35
  347. package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +1 -1
  348. package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +64 -42
  349. package/src/components/subModel/AddSubModelButton.tsx +104 -9
  350. package/src/components/subModel/LazyDropdown.tsx +14 -14
  351. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +168 -7
  352. package/src/components/subModel/__tests__/utils.test.ts +12 -12
  353. package/src/components/subModel/utils.ts +25 -6
  354. package/src/components/variables/VariableInput.tsx +32 -6
  355. package/src/components/variables/VariableTag.tsx +54 -2
  356. package/src/components/variables/types.ts +2 -0
  357. package/src/components/variables/utils.ts +7 -3
  358. package/src/data-source/index.ts +143 -12
  359. package/src/data-source/jioToJoiSchema.ts +1 -0
  360. package/src/emitter.ts +14 -0
  361. package/src/executor/FlowExecutor.ts +383 -119
  362. package/src/executor/__tests__/ctx-defs-injection.test.ts +197 -0
  363. package/src/executor/__tests__/flowExecutor.test.ts +217 -5
  364. package/src/flow-registry/GlobalFlowRegistry.ts +1 -0
  365. package/src/flow-registry/InstanceFlowRegistry.ts +1 -0
  366. package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +54 -0
  367. package/src/flowContext.ts +646 -158
  368. package/src/flowEngine.ts +385 -14
  369. package/src/flowSettings.ts +59 -30
  370. package/src/hooks/useApplyAutoFlows.ts +5 -3
  371. package/src/index.ts +26 -3
  372. package/src/locale/de-DE.json +62 -0
  373. package/src/locale/en-US.json +57 -45
  374. package/src/locale/es-ES.json +62 -0
  375. package/src/locale/fr-FR.json +62 -0
  376. package/src/locale/hu-HU.json +62 -0
  377. package/src/locale/id-ID.json +62 -0
  378. package/src/locale/it-IT.json +62 -0
  379. package/src/locale/ja-JP.json +62 -0
  380. package/src/locale/ko-KR.json +62 -0
  381. package/src/locale/nl-NL.json +62 -0
  382. package/src/locale/pt-BR.json +62 -0
  383. package/src/locale/ru-RU.json +62 -0
  384. package/src/locale/tr-TR.json +62 -0
  385. package/src/locale/uk-UA.json +62 -0
  386. package/src/locale/vi-VN.json +62 -0
  387. package/src/locale/zh-CN.json +58 -46
  388. package/src/locale/zh-TW.json +62 -0
  389. package/src/models/CollectionFieldModel.tsx +82 -18
  390. package/src/models/__tests__/dispatchEvent.behavior.test.ts +169 -0
  391. package/src/models/__tests__/dispatchEvent.when.test.ts +356 -0
  392. package/src/models/__tests__/flowEngine.resolveUse.test.ts +170 -0
  393. package/src/models/__tests__/flowModel.clone.test.ts +416 -0
  394. package/src/models/__tests__/flowModel.getFlows.sort.test.ts +33 -9
  395. package/src/models/__tests__/flowModel.scheduleModelOperation.test.tsx +129 -0
  396. package/src/models/__tests__/flowModel.test.ts +296 -119
  397. package/src/models/__tests__/forkFlowModel.test.ts +40 -7
  398. package/src/models/flowModel.tsx +426 -148
  399. package/src/models/forkFlowModel.ts +48 -8
  400. package/src/provider.tsx +18 -14
  401. package/src/reactive/__tests__/observer.test.tsx +211 -0
  402. package/src/reactive/index.ts +11 -0
  403. package/src/reactive/observer.tsx +101 -0
  404. package/src/resources/__tests__/multiRecordResource.test.ts +44 -0
  405. package/src/resources/__tests__/sqlResource.test.ts +60 -0
  406. package/src/resources/baseRecordResource.ts +46 -3
  407. package/src/resources/multiRecordResource.ts +28 -12
  408. package/src/resources/singleRecordResource.ts +9 -3
  409. package/src/resources/sqlResource.ts +33 -32
  410. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +38 -21
  411. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +50 -34
  412. package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +15 -16
  413. package/src/runjs-context/contexts/JSColumnRunJSContext.ts +58 -0
  414. package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +106 -0
  415. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +30 -25
  416. package/src/runjs-context/contexts/JSItemRunJSContext.ts +35 -21
  417. package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +17 -18
  418. package/src/runjs-context/contexts/base.ts +871 -0
  419. package/src/runjs-context/contributions.ts +88 -0
  420. package/src/runjs-context/helpers.ts +32 -30
  421. package/src/runjs-context/registry.ts +16 -47
  422. package/src/runjs-context/setup.ts +57 -0
  423. package/src/runjs-context/snippets/global/api-request.snippet.ts +38 -0
  424. package/src/runjs-context/snippets/global/clipboard-copy-text.snippet.ts +42 -0
  425. package/src/runjs-context/snippets/global/import-esm.snippet.ts +39 -0
  426. package/src/runjs-context/snippets/global/message-error.snippet.ts +6 -0
  427. package/src/runjs-context/snippets/global/message-success.snippet.ts +6 -0
  428. package/src/runjs-context/snippets/global/notification-open.snippet.ts +11 -1
  429. package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +10 -3
  430. package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +10 -3
  431. package/src/runjs-context/snippets/global/query-selector.snippet.ts +34 -0
  432. package/src/runjs-context/snippets/global/require-amd.snippet.ts +30 -0
  433. package/src/runjs-context/snippets/global/window-open.snippet.ts +11 -1
  434. package/src/runjs-context/snippets/index.ts +212 -39
  435. package/src/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.ts +14 -2
  436. package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +45 -0
  437. package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +80 -0
  438. package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +44 -0
  439. package/src/runjs-context/snippets/scene/block/render-antd-icons.snippet.ts +46 -0
  440. package/src/runjs-context/snippets/scene/block/render-button-handler.snippet.ts +35 -0
  441. package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +38 -0
  442. package/src/runjs-context/snippets/scene/block/render-info-card.snippet.ts +52 -0
  443. package/src/runjs-context/snippets/scene/block/render-react-jsx.snippet.ts +39 -0
  444. package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +38 -0
  445. package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +76 -0
  446. package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +65 -0
  447. package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +46 -0
  448. package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +264 -0
  449. package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +105 -0
  450. package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +33 -0
  451. package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +45 -0
  452. package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +32 -0
  453. package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +31 -0
  454. package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +63 -0
  455. package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +61 -0
  456. package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +55 -0
  457. package/src/runjs-context/snippets/scene/form/calculate-total.snippet.ts +44 -0
  458. package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +62 -0
  459. package/src/runjs-context/snippets/scene/form/conditional-required.snippet.ts +45 -0
  460. package/src/runjs-context/snippets/scene/form/copy-field-values.snippet.ts +55 -0
  461. package/src/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.ts +14 -2
  462. package/src/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.ts +15 -3
  463. package/src/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.ts +15 -3
  464. package/src/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.ts +15 -3
  465. package/src/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.ts +48 -0
  466. package/src/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.ts +15 -3
  467. package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +45 -0
  468. package/src/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.ts +14 -2
  469. package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +60 -0
  470. package/src/runjs-context/snippets/scene/table/destroy-selected.snippet.ts +36 -0
  471. package/src/runjs-context/snippets/scene/table/export-selected-json.snippet.ts +45 -0
  472. package/src/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.ts +14 -2
  473. package/src/runjs-context/snippets/types.ts +5 -1
  474. package/src/runjsLibs.ts +622 -0
  475. package/src/scheduler/ModelOperationScheduler.ts +306 -0
  476. package/src/types.ts +86 -5
  477. package/src/utils/__tests__/createCollectionContextMeta.test.ts +51 -0
  478. package/src/utils/__tests__/flows.test.ts +65 -0
  479. package/src/utils/__tests__/jsxTransform.test.ts +38 -0
  480. package/src/utils/__tests__/params-resolvers.test.ts +40 -0
  481. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +25 -0
  482. package/src/utils/__tests__/pruneFilter.test.ts +38 -0
  483. package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +38 -0
  484. package/src/utils/__tests__/runjsTemplateCompat.test.ts +159 -0
  485. package/src/utils/__tests__/safeGlobals.test.ts +79 -2
  486. package/src/utils/__tests__/utils.test.ts +114 -15
  487. package/src/utils/__tests__/variablesParams.test.ts +120 -0
  488. package/src/utils/associationObjectVariable.ts +180 -0
  489. package/src/utils/createCollectionContextMeta.ts +9 -3
  490. package/src/utils/createEphemeralContext.ts +142 -0
  491. package/src/utils/flows.ts +23 -0
  492. package/src/utils/index.ts +17 -3
  493. package/src/utils/jsxTransform.ts +39 -0
  494. package/src/utils/params-resolvers.ts +25 -11
  495. package/src/utils/parsePathnameToViewParams.ts +50 -6
  496. package/src/utils/pruneFilter.ts +41 -0
  497. package/src/utils/resolveModuleUrl.ts +91 -0
  498. package/src/utils/runjsModuleLoader.ts +553 -0
  499. package/src/utils/runjsTemplateCompat.ts +828 -0
  500. package/src/utils/safeGlobals.ts +181 -15
  501. package/src/utils/schema-utils.ts +81 -3
  502. package/src/utils/serverContextParams.ts +6 -0
  503. package/src/utils/translation.ts +7 -2
  504. package/src/utils/variablesParams.ts +164 -72
  505. package/src/views/DialogComponent.tsx +1 -4
  506. package/src/views/DrawerComponent.tsx +19 -7
  507. package/src/views/PageComponent.tsx +3 -5
  508. package/src/views/ViewNavigation.ts +49 -43
  509. package/src/views/__tests__/FlowView.usePage.test.tsx +186 -0
  510. package/src/views/__tests__/ViewNavigation.test.ts +54 -34
  511. package/src/views/__tests__/useDialog.closeDestroy.test.tsx +159 -0
  512. package/src/views/__tests__/viewEvents.resolveOpenerEngine.test.ts +28 -0
  513. package/src/views/createViewMeta.ts +402 -73
  514. package/src/views/index.tsx +1 -1
  515. package/src/views/useDialog.tsx +52 -31
  516. package/src/views/useDrawer.tsx +99 -55
  517. package/src/views/usePage.tsx +101 -33
  518. package/src/views/usePopover.tsx +4 -1
  519. package/src/views/viewEvents.ts +55 -0
  520. package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +0 -38
  521. package/lib/runjs-context/contexts/FlowRunJSContext.js +0 -217
  522. package/lib/runjs-context/contexts/LinkageRunJSContext.js +0 -62
  523. package/lib/runjs-context/index.d.ts +0 -19
  524. package/lib/runjs-context/index.js +0 -57
  525. package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +0 -16
  526. package/lib/runjs-context/snippets/global/api-request-get.snippet.js +0 -42
  527. package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +0 -16
  528. package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +0 -16
  529. package/lib/runjs-context/snippets/global/requireAsync.snippet.d.ts +0 -16
  530. package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +0 -16
  531. package/lib/runjs-context/snippets/global/sleep.snippet.js +0 -43
  532. package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +0 -16
  533. package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +0 -15
  534. package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +0 -15
  535. package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +0 -15
  536. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +0 -15
  537. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +0 -43
  538. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +0 -15
  539. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +0 -40
  540. package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +0 -15
  541. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +0 -15
  542. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +0 -42
  543. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +0 -15
  544. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js +0 -46
  545. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +0 -15
  546. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +0 -41
  547. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +0 -15
  548. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +0 -41
  549. package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +0 -15
  550. package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +0 -15
  551. package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +0 -15
  552. package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +0 -15
  553. package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +0 -15
  554. package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +0 -15
  555. package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +0 -15
  556. package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +0 -15
  557. package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +0 -15
  558. package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +0 -15
  559. package/src/runjs-context/contexts/FlowRunJSContext.ts +0 -190
  560. package/src/runjs-context/contexts/LinkageRunJSContext.ts +0 -35
  561. package/src/runjs-context/index.ts +0 -20
  562. package/src/runjs-context/snippets/global/api-request-get.snippet.ts +0 -20
  563. package/src/runjs-context/snippets/global/api-request-post.snippet.ts +0 -20
  564. package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +0 -19
  565. package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +0 -21
  566. package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +0 -21
  567. package/src/runjs-context/snippets/global/log-json-record.snippet.ts +0 -21
  568. package/src/runjs-context/snippets/global/requireAsync.snippet.ts +0 -24
  569. package/src/runjs-context/snippets/global/sleep.snippet.ts +0 -21
  570. package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +0 -22
  571. package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +0 -23
  572. package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +0 -24
  573. package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +0 -21
  574. package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +0 -18
  575. package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +0 -20
  576. package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +0 -24
  577. package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +0 -19
  578. package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +0 -24
  579. package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +0 -24
  580. package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +0 -30
  581. package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +0 -34
  582. package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +0 -20
  583. package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +0 -19
  584. package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +0 -18
  585. /package/lib/runjs-context/snippets/global/{copy-record-json.snippet.d.ts → api-request.snippet.d.ts} +0 -0
  586. /package/lib/runjs-context/snippets/global/{copy-to-clipboard.snippet.d.ts → clipboard-copy-text.snippet.d.ts} +0 -0
  587. /package/lib/runjs-context/snippets/global/{log-json-record.snippet.d.ts → import-esm.snippet.d.ts} +0 -0
  588. /package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.d.ts → query-selector.snippet.d.ts} +0 -0
  589. /package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.d.ts → block/echarts-init.snippet.d.ts} +0 -0
@@ -8,7 +8,6 @@
8
8
  */
9
9
 
10
10
  import { batch, define, observable, observe } from '@formily/reactive';
11
- import { observer } from '@formily/reactive-react';
12
11
  import _ from 'lodash';
13
12
  import React from 'react';
14
13
  import { uid } from 'uid/secure';
@@ -31,17 +30,11 @@ import type {
31
30
  ParamObject,
32
31
  ParentFlowModel,
33
32
  PersistOptions,
34
- StepDefinition,
33
+ ResolveUseResult,
35
34
  StepParams,
36
35
  } from '../types';
37
36
  import { IModelComponentProps, ReadonlyModelProps } from '../types';
38
- import {
39
- FlowExitException,
40
- isInheritedFrom,
41
- resolveDefaultParams,
42
- resolveExpressions,
43
- setupRuntimeContextSteps,
44
- } from '../utils';
37
+ import { isInheritedFrom, setupRuntimeContextSteps } from '../utils';
45
38
  // import { FlowExitAllException } from '../utils/exceptions';
46
39
  import { Typography } from 'antd/lib';
47
40
  import { ModelActionRegistry } from '../action-registry/ModelActionRegistry';
@@ -50,8 +43,11 @@ import { ModelEventRegistry } from '../event-registry/ModelEventRegistry';
50
43
  import { GlobalFlowRegistry } from '../flow-registry/GlobalFlowRegistry';
51
44
  import { FlowDefinition } from '../FlowDefinition';
52
45
  import { FlowSettingsOpenOptions } from '../flowSettings';
53
- import type { EventDefinition } from '../types';
46
+ import type { ScheduleOptions } from '../scheduler/ModelOperationScheduler';
47
+ import type { DispatchEventOptions, EventDefinition } from '../types';
54
48
  import { ForkFlowModel } from './forkFlowModel';
49
+ import type { MenuProps } from 'antd';
50
+ import { observer } from '..';
55
51
 
56
52
  // 使用 WeakMap 为每个类缓存一个 ModelActionRegistry 实例
57
53
  const classActionRegistries = new WeakMap<typeof FlowModel, ModelActionRegistry>();
@@ -65,6 +61,33 @@ const modelMetas = new WeakMap<typeof FlowModel, FlowModelMeta>();
65
61
  // 使用WeakMap存储每个类的 GlobalFlowRegistry
66
62
  const modelGlobalRegistries = new WeakMap<typeof FlowModel, GlobalFlowRegistry>();
67
63
 
64
+ type BaseMenuItem = NonNullable<MenuProps['items']>[number];
65
+ type MenuLeafItem = Exclude<BaseMenuItem, { children: MenuProps['items'] }>;
66
+
67
+ export type FlowModelExtraMenuItem = Omit<MenuLeafItem, 'key'> & {
68
+ key: React.Key;
69
+ group?: string;
70
+ sort?: number;
71
+ onClick?: () => void;
72
+ };
73
+
74
+ type FlowModelExtraMenuItemInput = Omit<FlowModelExtraMenuItem, 'key'> & { key?: React.Key };
75
+
76
+ type ExtraMenuItemEntry = {
77
+ group?: string;
78
+ sort?: number;
79
+ matcher?: (model: FlowModel) => boolean;
80
+ keyPrefix?: string;
81
+ items:
82
+ | FlowModelExtraMenuItemInput[]
83
+ | ((
84
+ model: FlowModel,
85
+ t: (k: string, opt?: any) => string,
86
+ ) => FlowModelExtraMenuItemInput[] | Promise<FlowModelExtraMenuItemInput[]>);
87
+ };
88
+
89
+ const classMenuExtensions = new WeakMap<typeof FlowModel, Set<ExtraMenuItemEntry>>();
90
+
68
91
  export enum ModelRenderMode {
69
92
  ReactElement = 'reactElement',
70
93
  RenderFunction = 'renderFunction',
@@ -72,7 +95,7 @@ export enum ModelRenderMode {
72
95
 
73
96
  export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
74
97
  /**
75
- * 当 flowSettings.enabled 且 model.hidden 为 true 时用于渲染设置态组件(实例方法,子类可覆盖)。
98
+ * 当 flowSettingsEnabled 且 model.hidden 为 true 时用于渲染设置态组件(实例方法,子类可覆盖)。
76
99
  * 基类默认仅返回一个透明度降低的占位元素
77
100
  */
78
101
  protected renderHiddenInConfig(): React.ReactNode | undefined {
@@ -88,7 +111,10 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
88
111
  public subModels: Structure['subModels'];
89
112
  private _options: FlowModelOptions<Structure>;
90
113
  protected _title: string;
114
+ protected _extraTitle: string;
91
115
  public isNew = false; // 标记是否为新建状态
116
+ public skeleton = null;
117
+ public forbidden = null;
92
118
 
93
119
  /**
94
120
  * 所有 fork 实例的引用集合。
@@ -103,9 +129,9 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
103
129
  private forkCache: Map<string, ForkFlowModel<any>> = new Map();
104
130
 
105
131
  /**
106
- * 上一次 applyAutoFlows 的执行参数
132
+ * 上一次 beforeRender 的执行参数
107
133
  */
108
- private _lastAutoRunParams: any[] | null = null;
134
+ private _lastAutoRunParams: [Record<string, any> | undefined, boolean?] | null = null;
109
135
  protected observerDispose: () => void;
110
136
  #flowContext: FlowModelContext;
111
137
 
@@ -114,6 +140,10 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
114
140
  */
115
141
  private _originalRender: (() => any) | null = null;
116
142
 
143
+ protected renderOriginal(): React.ReactNode {
144
+ return this._originalRender();
145
+ }
146
+
117
147
  /**
118
148
  * 缓存的响应式包装器组件(每个实例一个)
119
149
  */
@@ -150,12 +180,16 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
150
180
  this.subModels = {};
151
181
  this.sortIndex = options.sortIndex || 0;
152
182
  this._options = options;
183
+ this._title = '';
184
+ this._extraTitle = '';
153
185
 
154
- define(this, {
186
+ define(this as any, {
155
187
  hidden: observable,
156
188
  props: observable,
157
189
  subModels: observable.shallow,
158
190
  stepParams: observable,
191
+ _title: observable,
192
+ _extraTitle: observable,
159
193
  // setProps: action,
160
194
  setProps: batch,
161
195
  // setStepParams: action,
@@ -176,7 +210,7 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
176
210
  }
177
211
 
178
212
  if (this.flowEngine) {
179
- this.invalidateAutoFlowCache();
213
+ this.invalidateFlowCache('beforeRender');
180
214
  }
181
215
  this._rerunLastAutoRun();
182
216
  this.forks.forEach((fork) => {
@@ -256,6 +290,14 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
256
290
  return this._options.parentId;
257
291
  }
258
292
 
293
+ public scheduleModelOperation(
294
+ toUid: string,
295
+ fn: (model: FlowModel) => Promise<void> | void,
296
+ options?: ScheduleOptions,
297
+ ) {
298
+ return this.flowEngine?.scheduleModelOperation(this, toUid, fn, options);
299
+ }
300
+
259
301
  static get meta() {
260
302
  return modelMetas.get(this);
261
303
  }
@@ -308,6 +350,12 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
308
350
  return registry;
309
351
  }
310
352
 
353
+ /**
354
+ * 动态解析实际要实例化的模型类;可在子类中覆盖。
355
+ * 返回注册名或构造器,支持在 FlowEngine 中继续沿链解析。
356
+ */
357
+ static resolveUse?(options: CreateModelOptions, engine: FlowEngine, parent?: FlowModel): ResolveUseResult | void;
358
+
311
359
  /**
312
360
  * 注册仅当前 FlowModel 类及其子类可用的 Action。
313
361
  * 该注册是类级别的,不会影响全局(FlowEngine)的 Action 注册。
@@ -342,8 +390,8 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
342
390
  this.eventRegistry.registerEvents(events);
343
391
  }
344
392
 
345
- static buildChildrenFromModels(ctx, Models: Array<any>) {
346
- return Models.map((M) => buildSubModelItem(M, ctx, true));
393
+ static async buildChildrenFromModels(ctx, Models: Array<any>) {
394
+ return Promise.all(Models.map((M) => buildSubModelItem(M, ctx, true)));
347
395
  }
348
396
 
349
397
  get title() {
@@ -351,10 +399,18 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
351
399
  return this.translate(this._title) || this.translate(this.constructor['meta']?.label);
352
400
  }
353
401
 
402
+ get extraTitle() {
403
+ return this._extraTitle ? this.translate(this._extraTitle) : '';
404
+ }
405
+
354
406
  setTitle(value: string) {
355
407
  this._title = value;
356
408
  }
357
409
 
410
+ setExtraTitle(value: string) {
411
+ this._extraTitle = value || '';
412
+ }
413
+
358
414
  setHidden(value: boolean) {
359
415
  this.hidden = !!value;
360
416
  }
@@ -368,7 +424,19 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
368
424
  const meta = Cls.meta as any;
369
425
  const metaCreate = meta?.createModelOptions;
370
426
  if (metaCreate && typeof metaCreate === 'object' && metaCreate.subModels) {
371
- mergedSubModels = _.merge({}, _.cloneDeep(metaCreate.subModels || {}), _.cloneDeep(subModels || {}));
427
+ const replaceArrays = (objValue: unknown, srcValue: unknown) => {
428
+ if (Array.isArray(objValue) && Array.isArray(srcValue)) {
429
+ // Arrays should be replaced, not merged by index.
430
+ return srcValue;
431
+ }
432
+ return undefined;
433
+ };
434
+ mergedSubModels = _.mergeWith(
435
+ {},
436
+ _.cloneDeep(metaCreate.subModels || {}),
437
+ _.cloneDeep(subModels || {}),
438
+ replaceArrays,
439
+ );
372
440
  }
373
441
  } catch (e) {
374
442
  // Fallback silently if meta defaults resolution fails
@@ -387,13 +455,63 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
387
455
  });
388
456
  }
389
457
 
390
- public invalidateAutoFlowCache(deep = false) {
458
+ /**
459
+ * 失效指定事件的流程缓存;未指定 eventName 时,失效当前模型全部事件缓存。
460
+ * - 默认 beforeRender 与其它事件共享同一缓存体系:prefix=`event:${scope}`,flowKey=`eventName`,uid=`model.uid`
461
+ */
462
+ public invalidateFlowCache(eventName?: string, deep = false) {
391
463
  if (this.flowEngine) {
392
- const cacheKey = FlowEngine.generateApplyFlowCacheKey('autoFlow', 'all', this.uid);
393
- this.flowEngine.applyFlowCache.delete(cacheKey);
464
+ const scope = `event:${this.getFlowCacheScope(eventName || 'beforeRender')}`;
465
+ const cache = this.flowEngine.applyFlowCache;
466
+
467
+ if (eventName) {
468
+ // 删除该事件名下所有缓存(忽略不同 inputArgs 的散列差异)
469
+ const altScope = scope.replace(/:/g, '-');
470
+ const uidSuffixes = [`:${this.uid}`, `-${this.uid}`];
471
+ const eventSegments = [`:${eventName}:`, `-${eventName}-`];
472
+ for (const key of cache.keys()) {
473
+ const startMatches = key.startsWith(scope) || key.startsWith(altScope);
474
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
475
+ const eventMatches = eventSegments.some((seg) => key.includes(seg));
476
+ if (startMatches && endMatches && eventMatches) {
477
+ cache.delete(key);
478
+ }
479
+ }
480
+ } else {
481
+ // 粗粒度:扫描并删除当前模型 uid 相关的事件缓存(任意事件)
482
+ const altScope = `${scope}:`.replace(/:/g, '-');
483
+ const prefixes = [`${scope}:`, altScope];
484
+ const uidSuffixes = [`:${this.uid}`, `-${this.uid}`];
485
+ for (const key of cache.keys()) {
486
+ const startMatches = prefixes.some((p) => key.startsWith(p));
487
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
488
+ if (startMatches && endMatches) cache.delete(key);
489
+ }
490
+ }
491
+
492
+ // 同步失效所有 fork 的缓存
394
493
  this.forks.forEach((fork) => {
395
- const forkCacheKey = FlowEngine.generateApplyFlowCacheKey(`${fork['forkId']}`, 'all', this.uid);
396
- this.flowEngine.applyFlowCache.delete(forkCacheKey);
494
+ const forkScope = `event:${
495
+ (fork as any).getFlowCacheScope?.(eventName || 'beforeRender') ?? String((fork as any)['forkId'])
496
+ }`;
497
+ const altForkScope = forkScope.replace(/:/g, '-');
498
+ const uidSuffixes = [`:${this.uid}`, `-${this.uid}`];
499
+ if (eventName) {
500
+ const eventSegments = [`:${eventName}:`, `-${eventName}-`];
501
+ for (const key of this.flowEngine.applyFlowCache.keys()) {
502
+ const startMatches = key.startsWith(forkScope) || key.startsWith(altForkScope);
503
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
504
+ const eventMatches = eventSegments.some((seg) => key.includes(seg));
505
+ if (startMatches && endMatches && eventMatches) this.flowEngine.applyFlowCache.delete(key);
506
+ }
507
+ } else {
508
+ const prefixes = [`${forkScope}:`, `${altForkScope}-`];
509
+ for (const key of this.flowEngine.applyFlowCache.keys()) {
510
+ const startMatches = prefixes.some((p) => key.startsWith(p));
511
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
512
+ if (startMatches && endMatches) this.flowEngine.applyFlowCache.delete(key);
513
+ }
514
+ }
397
515
  });
398
516
  }
399
517
  if (deep) {
@@ -402,10 +520,10 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
402
520
  const subModelValue = this.subModels[subModelKey];
403
521
  if (Array.isArray(subModelValue)) {
404
522
  for (const subModel of subModelValue) {
405
- subModel.invalidateAutoFlowCache(deep);
523
+ subModel.invalidateFlowCache(eventName, deep);
406
524
  }
407
525
  } else if (subModelValue instanceof FlowModel) {
408
- subModelValue.invalidateAutoFlowCache(deep);
526
+ subModelValue.invalidateFlowCache(eventName, deep);
409
527
  }
410
528
  }
411
529
  }
@@ -551,17 +669,22 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
551
669
  const instanceKeys = new Set(instanceFlows.keys());
552
670
  const staticEntries = Array.from(staticFlows.entries()).filter(([key]) => !instanceKeys.has(key));
553
671
 
554
- // 实例流保持原始注册顺序,统一一次排序(稳定排序):
672
+ // 组内排序:
673
+ // - 静态流:GlobalFlowRegistry 已按 sort 和继承深度排序,直接使用
674
+ // - 实例流:按 sort 升序;相同 sort 保持注册顺序
555
675
  const instanceEntries = Array.from(instanceFlows.entries());
556
- const allEntries = [...staticEntries, ...instanceEntries];
557
- allEntries.sort(([, a], [, b]) => {
558
- const sa = a.sort ?? 0;
559
- const sb = b.sort ?? 0;
676
+ const instanceEntriesWithIndex = instanceEntries.map((e, i) => ({ e, i }));
677
+ instanceEntriesWithIndex.sort((a, b) => {
678
+ const sa = a.e[1].sort ?? 0;
679
+ const sb = b.e[1].sort ?? 0;
560
680
  if (sa !== sb) return sa - sb;
561
- return 0; // 其它情况保持稳定顺序(静态内部:父类优先;实例内部:注册顺序)
681
+ return a.i - b.i; // 稳定顺序
562
682
  });
563
683
 
564
- return new Map<string, FlowDefinition>(allEntries);
684
+ // 分组合并:动态流(实例)优先于静态流
685
+ const merged: [string, FlowDefinition][] = [...instanceEntriesWithIndex.map(({ e }) => e), ...staticEntries];
686
+
687
+ return new Map<string, FlowDefinition>(merged);
565
688
  }
566
689
 
567
690
  setProps(props: IModelComponentProps): void;
@@ -606,6 +729,8 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
606
729
  }
607
730
  }
608
731
  }
732
+ // 发起配置修改事件
733
+ this.emitter.emit('onStepParamsChanged');
609
734
  }
610
735
 
611
736
  getStepParams(flowKey: string, stepKey: string): any | undefined;
@@ -637,7 +762,11 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
637
762
  return currentFlowEngine.executor.runFlow(target, flowKey, inputArgs, runId);
638
763
  }
639
764
 
640
- private async _dispatchEvent(eventName: string, inputArgs?: Record<string, any>): Promise<void> {
765
+ private async _dispatchEvent(
766
+ eventName: string,
767
+ inputArgs?: Record<string, any>,
768
+ options?: DispatchEventOptions,
769
+ ): Promise<any[]> {
641
770
  const currentFlowEngine = this.flowEngine;
642
771
  if (!currentFlowEngine) {
643
772
  console.warn('FlowEngine not available on this model for dispatchEvent. Please set flowEngine on the model.');
@@ -650,64 +779,79 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
650
779
  this.cleanRun
651
780
  }, targetIsFork=${(target as any)?.isFork === true}`,
652
781
  );
653
- await currentFlowEngine.executor.dispatchEvent(target, eventName, inputArgs);
782
+ return await currentFlowEngine.executor.dispatchEvent(target, eventName, inputArgs, options);
654
783
  }
655
784
 
656
- private _dispatchEventWithDebounce = _.debounce(async (eventName: string, inputArgs?: Record<string, any>) => {
657
- return this._dispatchEvent(eventName, inputArgs);
658
- }, 100);
785
+ private _dispatchEventWithDebounce = _.debounce(
786
+ async function (
787
+ this: FlowModel,
788
+ eventName: string,
789
+ inputArgs?: Record<string, any>,
790
+ options?: DispatchEventOptions,
791
+ ) {
792
+ return this._dispatchEvent(eventName, inputArgs, options);
793
+ },
794
+ 500,
795
+ { leading: true },
796
+ );
659
797
 
660
798
  async dispatchEvent(
661
799
  eventName: string,
662
800
  inputArgs?: Record<string, any>,
663
801
  options?: {
664
- /**
665
- * 是否要开启防抖功能
666
- */
667
- debounce: boolean;
668
- },
669
- ): Promise<void> {
670
- if (options?.debounce) {
671
- return this._dispatchEventWithDebounce(eventName, inputArgs);
802
+ /** 是否要开启防抖功能 */
803
+ debounce?: boolean;
804
+ } & DispatchEventOptions,
805
+ ): Promise<any[]> {
806
+ const isBeforeRender = eventName === 'beforeRender';
807
+ // 缺省值由模型层提供:beforeRender 默认顺序执行 + 使用缓存;其它事件默认顺序执行(不默认使用缓存)
808
+ const defaults = isBeforeRender ? { sequential: true, useCache: true } : { sequential: true };
809
+ const execOptions = {
810
+ sequential: options?.sequential ?? (defaults as any).sequential,
811
+ useCache: options?.useCache ?? (defaults as any).useCache,
812
+ } as DispatchEventOptions;
813
+
814
+ // 记录最近一次 beforeRender 的入参与选项,便于 stepParams 变化时触发重跑
815
+ if (isBeforeRender) {
816
+ this._lastAutoRunParams = [inputArgs, execOptions.useCache];
672
817
  }
673
818
 
674
- return this._dispatchEvent(eventName, inputArgs);
819
+ if (options?.debounce) {
820
+ return this._dispatchEventWithDebounce(eventName, inputArgs, execOptions);
821
+ }
822
+ return this._dispatchEvent(eventName, inputArgs, execOptions);
675
823
  }
676
824
 
677
825
  /**
678
- * 获取所有自动应用流程定义(保持 getFlows 的顺序,即按 sort 排序)
679
- * @returns {FlowDefinition[]} 自动应用流程定义数组(已按 sort 排序)
826
+ * 按事件名获取对应的流程集合(保持 getFlows 的顺序,即按 sort 排序)。
827
+ * - beforeRender 兼容:除显式 on: 'beforeRender' 外,包含未声明 on 且 manual !== true 的流程。
680
828
  */
681
- public getAutoFlows(): FlowDefinition[] {
829
+ public getEventFlows(eventName: string): FlowDefinition[] {
682
830
  const allFlows = this.getFlows();
683
-
684
- // 过滤出自动流程(保持 Map 的原有顺序)
685
- // 没有 on 属性且没有 manual: true 的流程默认自动执行
686
- const autoFlows = Array.from(allFlows.values()).filter((flow) => {
687
- // 如果有 on 属性,说明是事件触发流程,不自动执行
688
- if (flow.on) {
689
- return false;
831
+ const beforeRender = eventName === 'beforeRender';
832
+ const isMatch = (flow: FlowDefinition) => {
833
+ if (beforeRender) {
834
+ if (flow.manual === true) return false;
835
+ if (!flow.on) return true;
836
+ return typeof flow.on === 'string' ? flow.on === 'beforeRender' : flow.on?.eventName === 'beforeRender';
690
837
  }
691
- // 如果明确设置了 manual: true,不自动执行
692
- if (flow.manual === true) {
693
- return false;
694
- }
695
- // 其他情况默认自动执行
696
- return true;
697
- });
698
-
699
- return autoFlows;
838
+ const on = flow.on;
839
+ if (!on) return false;
840
+ return typeof on === 'string' ? on === eventName : on?.eventName === eventName;
841
+ };
842
+ return Array.from(allFlows.values()).filter(isMatch);
700
843
  }
701
844
 
702
845
  /**
703
- * 重新执行上一次的 applyAutoFlows,保持参数一致
846
+ * 重新执行上一次的 beforeRender,保持参数一致
704
847
  * 如果之前没有执行过,则直接跳过
705
848
  * 使用 lodash debounce 避免频繁调用
706
849
  */
707
850
  private _rerunLastAutoRun = _.debounce(async () => {
708
851
  if (this._lastAutoRunParams) {
709
852
  try {
710
- await this.applyAutoFlows(...this._lastAutoRunParams);
853
+ const [inputArgs] = this._lastAutoRunParams as any[];
854
+ await this.dispatchEvent('beforeRender', inputArgs);
711
855
  } catch (error) {
712
856
  console.error('FlowModel._rerunLastAutoRun: Error during rerun:', error);
713
857
  }
@@ -715,86 +859,39 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
715
859
  }, 100);
716
860
 
717
861
  /**
718
- * 自动流程执行前钩子。
719
- * 子类可覆盖;可抛出 FlowExitException 提前终止。
862
+ * 通用事件分发钩子:开始
863
+ * 子类可覆盖;beforeRender 事件可通过抛出 FlowExitException 提前终止。
720
864
  */
721
- public async onBeforeAutoFlows(inputArgs?: Record<string, any>): Promise<void> {}
865
+ public async onDispatchEventStart(
866
+ eventName: string,
867
+ options?: DispatchEventOptions,
868
+ inputArgs?: Record<string, any>,
869
+ ): Promise<void> {}
722
870
 
723
871
  /**
724
- * 自动流程执行后钩子。
872
+ * 通用事件分发钩子:结束
725
873
  * 子类可覆盖。
726
874
  */
727
- public async onAfterAutoFlows(results: any[], inputArgs?: Record<string, any>): Promise<void> {}
875
+ public async onDispatchEventEnd(
876
+ eventName: string,
877
+ options?: DispatchEventOptions,
878
+ inputArgs?: Record<string, any>,
879
+ results?: any[],
880
+ ): Promise<void> {}
728
881
 
729
882
  /**
730
- * 自动流程错误钩子。
883
+ * 通用事件分发钩子:错误
731
884
  * 子类可覆盖。
732
885
  */
733
- public async onAutoFlowsError(error: Error, inputArgs?: Record<string, any>): Promise<void> {}
886
+ public async onDispatchEventError(
887
+ eventName: string,
888
+ options?: DispatchEventOptions,
889
+ inputArgs?: Record<string, any>,
890
+ error?: Error,
891
+ ): Promise<void> {}
734
892
 
735
893
  useHooksBeforeRender() {}
736
894
 
737
- /**
738
- * 执行所有自动应用流程
739
- * @param {Record<string, any>} [inputArgs] 可选的运行时参数
740
- * @param {boolean} [useCache=true] 是否使用缓存机制,默认为 true
741
- * @returns {Promise<any[]>} 所有自动应用流程的执行结果数组
742
- */
743
- async applyAutoFlows(inputArgs?: Record<string, any>, useCache?: boolean): Promise<any[]>;
744
- async applyAutoFlows(...args: any[]): Promise<any[]> {
745
- const [inputArgs, useCache = true] = args;
746
- const cacheKey = useCache
747
- ? FlowEngine.generateApplyFlowCacheKey(this['forkId'] ?? 'autoFlow', 'all', this.uid)
748
- : null;
749
- if (!_.isEqual(inputArgs, this._lastAutoRunParams?.[0]) && cacheKey) {
750
- this.flowEngine.applyFlowCache.delete(cacheKey);
751
- }
752
- this._lastAutoRunParams = args;
753
-
754
- // 在执行自动流程前触发(无论是否命中缓存都应触发)
755
- try {
756
- await this.onBeforeAutoFlows(inputArgs);
757
- } catch (error) {
758
- if (error instanceof FlowExitException) {
759
- this.context.logger?.debug(`[FlowModel.applyAutoFlows] ${error.message}`);
760
- return [];
761
- }
762
- try {
763
- await this.onAutoFlowsError(error as Error, inputArgs);
764
- } catch (_) {
765
- // swallow secondary hook error to avoid masking the original
766
- }
767
- throw error;
768
- }
769
-
770
- // 执行自动流程(内部可能命中缓存)
771
- let results: any[] = [];
772
- try {
773
- results = await this.flowEngine.executor.runAutoFlows(this, inputArgs, useCache);
774
- } catch (error) {
775
- try {
776
- await this.onAutoFlowsError(error as Error, inputArgs);
777
- } catch (_) {
778
- // ignore secondary error from error hook
779
- }
780
- throw error;
781
- }
782
-
783
- // 执行后钩子
784
- try {
785
- await this.onAfterAutoFlows(results, inputArgs);
786
- } catch (error) {
787
- try {
788
- await this.onAutoFlowsError(error as Error, inputArgs);
789
- } catch (_) {
790
- // ignore
791
- }
792
- throw error;
793
- }
794
-
795
- return results;
796
- }
797
-
798
895
  /**
799
896
  * 智能检测是否应该跳过响应式包装
800
897
  * 说明:
@@ -838,7 +935,7 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
838
935
  // 如果需要跳过响应式包装(例如返回渲染函数),也需要包一层以处理 hidden/config 逻辑
839
936
  if (this.shouldSkipReactiveWrapping()) {
840
937
  const wrappedNonReactive = function (this: any) {
841
- const isConfigMode = !!this?.flowEngine?.flowSettings?.enabled;
938
+ const isConfigMode = !!this?.context?.flowSettingsEnabled;
842
939
  if (this.hidden) {
843
940
  if (!isConfigMode) return null;
844
941
  const rendered = this.renderHiddenInConfig?.();
@@ -874,15 +971,25 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
874
971
  if (typeof renderTarget.onMount === 'function') {
875
972
  renderTarget.onMount();
876
973
  }
974
+ // 发射 mounted 生命周期事件(严格模式:不吞错,若有错误将以未处理拒绝暴露)
975
+ void renderTarget.flowEngine?.emitter?.emitAsync('model:mounted', {
976
+ uid: renderTarget.uid,
977
+ model: renderTarget,
978
+ });
877
979
  return () => {
878
980
  if (typeof renderTarget.onUnmount === 'function') {
879
981
  renderTarget.onUnmount();
880
982
  }
983
+ // 发射 unmounted 生命周期事件(严格模式:不吞错)
984
+ void renderTarget.flowEngine?.emitter?.emitAsync('model:unmounted', {
985
+ uid: renderTarget.uid,
986
+ model: renderTarget,
987
+ });
881
988
  };
882
989
  }, [renderTarget]);
883
990
 
884
991
  // 处理 hidden 渲染逻辑:
885
- const isConfigMode = !!modelInstance?.flowEngine?.flowSettings?.enabled;
992
+ const isConfigMode = !!modelInstance?.context?.flowSettingsEnabled;
886
993
  if (modelInstance.hidden) {
887
994
  if (!isConfigMode) {
888
995
  return null;
@@ -891,6 +998,10 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
891
998
  return modelInstance.renderHiddenInConfig?.();
892
999
  }
893
1000
 
1001
+ // 订阅 stepParams 变化,以便当步骤参数(如 JS 代码等)更新时触发一次 React 渲染,
1002
+ // 从而让 useHooksBeforeRender 中的副作用得以感知并执行(如 applyFlow('jsSettings'))。
1003
+ modelInstance.stepParams;
1004
+
894
1005
  // 调用原始渲染方法
895
1006
  return originalRender.call(renderTarget);
896
1007
  });
@@ -962,14 +1073,14 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
962
1073
  }
963
1074
 
964
1075
  async rerender() {
965
- await this.applyAutoFlows(this._lastAutoRunParams?.[0], false);
1076
+ await this.dispatchEvent('beforeRender', this._lastAutoRunParams?.[0], { useCache: false });
966
1077
  }
967
1078
 
968
1079
  /**
969
- * 自动流程缓存的作用域标识;fork 实例可覆盖以区分缓存。
1080
+ * 事件缓存的作用域标识;可按事件区分(默认与事件无关的 scope 返回 'default')。
970
1081
  */
971
- public getAutoFlowCacheScope(): string {
972
- return 'autoFlow';
1082
+ public getFlowCacheScope(eventName: string): string {
1083
+ return String(eventName);
973
1084
  }
974
1085
 
975
1086
  setParent(parent: FlowModel): void {
@@ -1024,6 +1135,13 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1024
1135
  model.sortIndex = maxSortIndex + 1;
1025
1136
  subModels[subKey].push(model);
1026
1137
  actualParent.emitter.emit('onSubModelAdded', model);
1138
+ // 同步发射到引擎级事件总线,便于外部统一监听模型树变更
1139
+ actualParent.flowEngine?.emitter?.emit('model:subModel:added', {
1140
+ parentUid: actualParent.uid,
1141
+ parent: actualParent,
1142
+ subKey,
1143
+ model,
1144
+ });
1027
1145
  return model;
1028
1146
  }
1029
1147
 
@@ -1050,6 +1168,12 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1050
1168
  model.setParent(actualParent);
1051
1169
  (actualParent.subModels as any)[subKey] = model;
1052
1170
  actualParent.emitter.emit('onSubModelAdded', model);
1171
+ actualParent.flowEngine?.emitter?.emit('model:subModel:added', {
1172
+ parentUid: actualParent.uid,
1173
+ parent: actualParent,
1174
+ subKey,
1175
+ model,
1176
+ });
1053
1177
  return model;
1054
1178
  }
1055
1179
 
@@ -1128,14 +1252,17 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1128
1252
  return this.flowEngine.createModel(options);
1129
1253
  }
1130
1254
 
1131
- async applySubModelsAutoFlows<K extends keyof Structure['subModels']>(
1255
+ /**
1256
+ * 对指定子模型派发 beforeRender 事件(顺序执行并使用缓存)。
1257
+ */
1258
+ async applySubModelsBeforeRenderFlows<K extends keyof Structure['subModels']>(
1132
1259
  subKey: K,
1133
1260
  inputArgs?: Record<string, any>,
1134
1261
  shared?: Record<string, any>,
1135
1262
  ) {
1136
1263
  await Promise.all(
1137
1264
  this.mapSubModels(subKey, async (sub) => {
1138
- await sub.applyAutoFlows(inputArgs);
1265
+ await sub.dispatchEvent('beforeRender', inputArgs);
1139
1266
  }),
1140
1267
  );
1141
1268
  }
@@ -1162,7 +1289,7 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1162
1289
  }
1163
1290
 
1164
1291
  // 创建新的 fork 实例
1165
- const forkId = this.forks.size; // 当前集合大小作为索引
1292
+ const forkId = uid(); // 当前集合大小作为索引
1166
1293
  const fork = new ForkFlowModel<this>(this as any, localProps, forkId);
1167
1294
  if (options?.register !== false) {
1168
1295
  this.forks.add(fork as any);
@@ -1209,7 +1336,7 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1209
1336
  throw new Error('FlowEngine is not set on this model. Please set flowEngine before saving.');
1210
1337
  }
1211
1338
  this.observerDispose();
1212
- this.invalidateAutoFlowCache(true);
1339
+ this.invalidateFlowCache('beforeRender', true);
1213
1340
  return this.flowEngine.removeModel(this.uid);
1214
1341
  }
1215
1342
 
@@ -1229,7 +1356,7 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1229
1356
  throw new Error('FlowEngine is not set on this model. Please set flowEngine before deleting.');
1230
1357
  }
1231
1358
  this.observerDispose();
1232
- this.invalidateAutoFlowCache(true);
1359
+ this.invalidateFlowCache('beforeRender', true);
1233
1360
  // 从 FlowEngine 中销毁模型
1234
1361
  return this.flowEngine.destroyModel(this.uid);
1235
1362
  }
@@ -1307,6 +1434,7 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1307
1434
  ..._.omit(this._options, ['flowEngine']),
1308
1435
  stepParams: this.stepParams,
1309
1436
  sortIndex: this.sortIndex,
1437
+ flowRegistry: {},
1310
1438
  };
1311
1439
  const subModels = this.subModels as {
1312
1440
  [key: string]: FlowModel | FlowModel[];
@@ -1323,12 +1451,92 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1323
1451
  }
1324
1452
  }
1325
1453
  for (const [key, flow] of this.flowRegistry.getFlows()) {
1326
- data['flowRegistry'] = data['flowRegistry'] || {};
1327
- data['flowRegistry'][key] = flow.toData();
1454
+ data.flowRegistry[key] = flow.toData();
1328
1455
  }
1329
1456
  return data;
1330
1457
  }
1331
1458
 
1459
+ /**
1460
+ * 复制当前模型实例为一个新的实例。
1461
+ * 新实例及其所有子模型都会有新的 uid,且不保留 root model 的 parent 关系。
1462
+ * 内部所有引用旧 uid 的地方(如 parentId, parentUid 等)都会被替换为对应的新 uid。
1463
+ * @returns {FlowModel} 复制后的新模型实例
1464
+ */
1465
+ clone<T extends FlowModel = this>(): T {
1466
+ if (!this.flowEngine) {
1467
+ throw new Error('FlowEngine is not set on this model. Please set flowEngine before cloning.');
1468
+ }
1469
+
1470
+ // 序列化当前实例
1471
+ const serialized = this.serialize();
1472
+
1473
+ // 第一步:收集所有 uid 并建立 oldUid -> newUid 的映射
1474
+ const uidMap = new Map<string, string>();
1475
+
1476
+ const collectUids = (data: Record<string, any>): void => {
1477
+ if (data.uid && typeof data.uid === 'string') {
1478
+ uidMap.set(data.uid, uid());
1479
+ }
1480
+
1481
+ // 递归处理 subModels
1482
+ if (data.subModels) {
1483
+ for (const key in data.subModels) {
1484
+ const subModel = data.subModels[key];
1485
+ if (Array.isArray(subModel)) {
1486
+ subModel.forEach((item) => collectUids(item));
1487
+ } else if (subModel && typeof subModel === 'object') {
1488
+ collectUids(subModel);
1489
+ }
1490
+ }
1491
+ }
1492
+ };
1493
+
1494
+ collectUids(serialized);
1495
+
1496
+ // 第二步:深度遍历并替换所有 uid 引用
1497
+ const replaceUidReferences = (data: any, isRoot = false): any => {
1498
+ if (data === null || data === undefined) {
1499
+ return data;
1500
+ }
1501
+
1502
+ // 如果是字符串,检查是否是需要替换的 uid
1503
+ if (typeof data === 'string') {
1504
+ return uidMap.get(data) ?? data;
1505
+ }
1506
+
1507
+ // 如果是数组,递归处理每个元素
1508
+ if (Array.isArray(data)) {
1509
+ return data.map((item) => replaceUidReferences(item, false));
1510
+ }
1511
+
1512
+ // 如果是对象,递归处理每个属性
1513
+ if (typeof data === 'object') {
1514
+ const result: Record<string, any> = {};
1515
+
1516
+ for (const key in data) {
1517
+ if (!Object.prototype.hasOwnProperty.call(data, key)) continue;
1518
+
1519
+ // 只删除 root model 的 parentId
1520
+ if (isRoot && key === 'parentId') {
1521
+ continue;
1522
+ }
1523
+
1524
+ result[key] = replaceUidReferences(data[key], false);
1525
+ }
1526
+
1527
+ return result;
1528
+ }
1529
+
1530
+ // 其他类型(number, boolean 等)直接返回
1531
+ return data;
1532
+ };
1533
+
1534
+ const clonedData = replaceUidReferences(serialized, true);
1535
+
1536
+ // 使用 flowEngine 创建新实例
1537
+ return this.flowEngine.createModel<T>(clonedData as any);
1538
+ }
1539
+
1332
1540
  /**
1333
1541
  * Opens the flow settings dialog for this flow model.
1334
1542
  * @param options - Configuration options for opening flow settings, excluding the model property
@@ -1341,6 +1549,76 @@ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
1341
1549
  });
1342
1550
  }
1343
1551
 
1552
+ /** 注册设置菜单的额外项(静态,按类缓存,可继承合并) */
1553
+ static registerExtraMenuItems(
1554
+ opts:
1555
+ | ExtraMenuItemEntry
1556
+ | ((
1557
+ model: FlowModel,
1558
+ t: (k: string, opt?: any) => string,
1559
+ ) => FlowModelExtraMenuItemInput[] | Promise<FlowModelExtraMenuItemInput[]>),
1560
+ ): () => void {
1561
+ const ModelClass = this as typeof FlowModel;
1562
+ const registry = classMenuExtensions.get(ModelClass) || new Set<ExtraMenuItemEntry>();
1563
+ let entry: ExtraMenuItemEntry;
1564
+ if (typeof opts === 'function') {
1565
+ entry = { items: opts };
1566
+ } else {
1567
+ entry = opts;
1568
+ }
1569
+ registry.add(entry);
1570
+ classMenuExtensions.set(ModelClass, registry);
1571
+ return () => {
1572
+ const reg = classMenuExtensions.get(ModelClass);
1573
+ reg?.delete(entry);
1574
+ };
1575
+ }
1576
+
1577
+ static async getExtraMenuItems(
1578
+ model: FlowModel,
1579
+ t: (k: string, opt?: any) => string,
1580
+ ): Promise<FlowModelExtraMenuItem[]> {
1581
+ const ModelClass = this as typeof FlowModel;
1582
+ const collected: FlowModelExtraMenuItem[] = [];
1583
+ const seen = new Set<typeof FlowModel>();
1584
+ const walk = async (Cls: typeof FlowModel) => {
1585
+ if (!Cls || seen.has(Cls)) return;
1586
+ seen.add(Cls);
1587
+ const reg = classMenuExtensions.get(Cls);
1588
+ if (reg) {
1589
+ for (const entry of reg) {
1590
+ if (entry.matcher && !entry.matcher(model)) continue;
1591
+ const items =
1592
+ typeof entry.items === 'function' ? await entry.items(model, t) : await Promise.resolve(entry.items || []);
1593
+ const group = entry.group || 'common-actions';
1594
+ const sort = entry.sort ?? 0;
1595
+ const prefix = entry.keyPrefix || Cls.name || 'extra';
1596
+ (items || []).forEach((it, idx: number) => {
1597
+ if (!it) return;
1598
+ const key = it.key ?? `${prefix}-${group}-${idx}-${Math.random().toString(36).slice(2, 6)}`;
1599
+ collected.push({
1600
+ ...it,
1601
+ key,
1602
+ group: it.group || group,
1603
+ sort: typeof it.sort === 'number' ? it.sort : sort,
1604
+ });
1605
+ });
1606
+ }
1607
+ }
1608
+ const ParentClass = Object.getPrototypeOf(Cls) as typeof FlowModel;
1609
+ const isFlowModelCtor = ParentClass === FlowModel || ParentClass?.prototype instanceof FlowModel;
1610
+ if (isFlowModelCtor) {
1611
+ await walk(ParentClass);
1612
+ }
1613
+ };
1614
+ await walk(ModelClass);
1615
+ return collected;
1616
+ }
1617
+
1618
+ refresh() {
1619
+ return this.rerender();
1620
+ }
1621
+
1344
1622
  // =============================
1345
1623
  // Dynamic flows (disabled)
1346
1624
  // The following APIs are kept as comments to preserve context