@nocobase/flow-engine 2.0.0-alpha.10

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 (638) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +30 -0
  3. package/lib/ContextPathProxy.d.ts +17 -0
  4. package/lib/ContextPathProxy.js +65 -0
  5. package/lib/ElementProxy.d.ts +17 -0
  6. package/lib/ElementProxy.js +93 -0
  7. package/lib/FlowContextProvider.d.ts +24 -0
  8. package/lib/FlowContextProvider.js +82 -0
  9. package/lib/FlowDefinition.d.ts +423 -0
  10. package/lib/FlowDefinition.js +257 -0
  11. package/lib/JSRunner.d.ts +32 -0
  12. package/lib/JSRunner.js +95 -0
  13. package/lib/ReactView.d.ts +20 -0
  14. package/lib/ReactView.js +120 -0
  15. package/lib/ViewScopedFlowEngine.d.ts +23 -0
  16. package/lib/ViewScopedFlowEngine.js +81 -0
  17. package/lib/acl/Acl.d.ts +31 -0
  18. package/lib/acl/Acl.js +115 -0
  19. package/lib/action-registry/BaseActionRegistry.d.ts +23 -0
  20. package/lib/action-registry/BaseActionRegistry.js +57 -0
  21. package/lib/action-registry/EngineActionRegistry.d.ts +20 -0
  22. package/lib/action-registry/EngineActionRegistry.js +47 -0
  23. package/lib/action-registry/ModelActionRegistry.d.ts +34 -0
  24. package/lib/action-registry/ModelActionRegistry.js +79 -0
  25. package/lib/components/DynamicFlowsEditor.d.ts +17 -0
  26. package/lib/components/DynamicFlowsEditor.js +49 -0
  27. package/lib/components/FieldModelRenderer.d.ts +10 -0
  28. package/lib/components/FieldModelRenderer.js +100 -0
  29. package/lib/components/FlowContextSelector.d.ts +11 -0
  30. package/lib/components/FlowContextSelector.js +221 -0
  31. package/lib/components/FlowErrorFallback.d.ts +25 -0
  32. package/lib/components/FlowErrorFallback.js +264 -0
  33. package/lib/components/FlowModelRenderer.d.ts +61 -0
  34. package/lib/components/FlowModelRenderer.js +214 -0
  35. package/lib/components/FormItem.d.ts +18 -0
  36. package/lib/components/FormItem.js +151 -0
  37. package/lib/components/common/FlowSettingsButton.d.ts +11 -0
  38. package/lib/components/common/FlowSettingsButton.js +66 -0
  39. package/lib/components/common/index.d.ts +9 -0
  40. package/lib/components/common/index.js +30 -0
  41. package/lib/components/common/withFlowDesignMode.d.ts +26 -0
  42. package/lib/components/common/withFlowDesignMode.js +61 -0
  43. package/lib/components/dnd/findModelUidPosition.d.ts +13 -0
  44. package/lib/components/dnd/findModelUidPosition.js +50 -0
  45. package/lib/components/dnd/gridDragPlanner.d.ts +130 -0
  46. package/lib/components/dnd/gridDragPlanner.js +497 -0
  47. package/lib/components/dnd/index.d.ts +24 -0
  48. package/lib/components/dnd/index.js +164 -0
  49. package/lib/components/index.d.ts +18 -0
  50. package/lib/components/index.js +48 -0
  51. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.d.ts +46 -0
  52. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +225 -0
  53. package/lib/components/settings/independents/dropdown/index.d.ts +9 -0
  54. package/lib/components/settings/independents/dropdown/index.js +30 -0
  55. package/lib/components/settings/independents/index.d.ts +1 -0
  56. package/lib/components/settings/independents/index.js +30 -0
  57. package/lib/components/settings/index.d.ts +10 -0
  58. package/lib/components/settings/index.js +32 -0
  59. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +24 -0
  60. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +501 -0
  61. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.d.ts +45 -0
  62. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +231 -0
  63. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +111 -0
  64. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +484 -0
  65. package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.d.ts +26 -0
  66. package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.js +342 -0
  67. package/lib/components/settings/wrappers/contextual/StepSettings.d.ts +23 -0
  68. package/lib/components/settings/wrappers/contextual/StepSettings.js +110 -0
  69. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.d.ts +20 -0
  70. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +212 -0
  71. package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.d.ts +20 -0
  72. package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.js +47 -0
  73. package/lib/components/settings/wrappers/contextual/index.d.ts +14 -0
  74. package/lib/components/settings/wrappers/contextual/index.js +40 -0
  75. package/lib/components/settings/wrappers/embedded/FlowSettings.d.ts +33 -0
  76. package/lib/components/settings/wrappers/embedded/FlowSettings.js +207 -0
  77. package/lib/components/settings/wrappers/embedded/FlowsSettings.d.ts +41 -0
  78. package/lib/components/settings/wrappers/embedded/FlowsSettings.js +84 -0
  79. package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.d.ts +16 -0
  80. package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.js +88 -0
  81. package/lib/components/settings/wrappers/embedded/index.d.ts +10 -0
  82. package/lib/components/settings/wrappers/embedded/index.js +32 -0
  83. package/lib/components/settings/wrappers/index.d.ts +2 -0
  84. package/lib/components/settings/wrappers/index.js +32 -0
  85. package/lib/components/subModel/AddSubModelButton.d.ts +62 -0
  86. package/lib/components/subModel/AddSubModelButton.js +415 -0
  87. package/lib/components/subModel/LazyDropdown.d.ts +55 -0
  88. package/lib/components/subModel/LazyDropdown.js +524 -0
  89. package/lib/components/subModel/index.d.ts +10 -0
  90. package/lib/components/subModel/index.js +32 -0
  91. package/lib/components/subModel/utils.d.ts +34 -0
  92. package/lib/components/subModel/utils.js +287 -0
  93. package/lib/components/variables/InlineVariableTag.d.ts +21 -0
  94. package/lib/components/variables/InlineVariableTag.js +123 -0
  95. package/lib/components/variables/SlateVariableEditor.d.ts +46 -0
  96. package/lib/components/variables/SlateVariableEditor.js +302 -0
  97. package/lib/components/variables/VariableInput.d.ts +11 -0
  98. package/lib/components/variables/VariableInput.js +334 -0
  99. package/lib/components/variables/VariableTag.d.ts +11 -0
  100. package/lib/components/variables/VariableTag.js +189 -0
  101. package/lib/components/variables/VariableTrigger.d.ts +20 -0
  102. package/lib/components/variables/VariableTrigger.js +136 -0
  103. package/lib/components/variables/index.d.ts +15 -0
  104. package/lib/components/variables/index.js +53 -0
  105. package/lib/components/variables/types.d.ts +93 -0
  106. package/lib/components/variables/types.js +24 -0
  107. package/lib/components/variables/useResolvedMetaTree.d.ts +19 -0
  108. package/lib/components/variables/useResolvedMetaTree.js +91 -0
  109. package/lib/components/variables/utils.d.ts +22 -0
  110. package/lib/components/variables/utils.js +177 -0
  111. package/lib/data-source/index.d.ts +180 -0
  112. package/lib/data-source/index.js +737 -0
  113. package/lib/data-source/jioToJoiSchema.d.ts +19 -0
  114. package/lib/data-source/jioToJoiSchema.js +114 -0
  115. package/lib/data-source/sortCollectionsByInherits.d.ts +10 -0
  116. package/lib/data-source/sortCollectionsByInherits.js +71 -0
  117. package/lib/decorators/index.d.ts +9 -0
  118. package/lib/decorators/index.js +36 -0
  119. package/lib/decorators/largeField.d.ts +9 -0
  120. package/lib/decorators/largeField.js +42 -0
  121. package/lib/emitter.d.ts +16 -0
  122. package/lib/emitter.js +58 -0
  123. package/lib/event-registry/BaseEventRegistry.d.ts +22 -0
  124. package/lib/event-registry/BaseEventRegistry.js +57 -0
  125. package/lib/event-registry/EngineEventRegistry.d.ts +19 -0
  126. package/lib/event-registry/EngineEventRegistry.js +47 -0
  127. package/lib/event-registry/ModelEventRegistry.d.ts +33 -0
  128. package/lib/event-registry/ModelEventRegistry.js +79 -0
  129. package/lib/executor/FlowExecutor.d.ts +25 -0
  130. package/lib/executor/FlowExecutor.js +290 -0
  131. package/lib/flow-registry/BaseFlowRegistry.d.ts +46 -0
  132. package/lib/flow-registry/BaseFlowRegistry.js +86 -0
  133. package/lib/flow-registry/GlobalFlowRegistry.d.ts +22 -0
  134. package/lib/flow-registry/GlobalFlowRegistry.js +95 -0
  135. package/lib/flow-registry/InstanceFlowRegistry.d.ts +21 -0
  136. package/lib/flow-registry/InstanceFlowRegistry.js +59 -0
  137. package/lib/flow-registry/index.d.ts +11 -0
  138. package/lib/flow-registry/index.js +34 -0
  139. package/lib/flowContext.d.ts +243 -0
  140. package/lib/flowContext.js +1337 -0
  141. package/lib/flowEngine.d.ts +340 -0
  142. package/lib/flowEngine.js +781 -0
  143. package/lib/flowI18n.d.ts +46 -0
  144. package/lib/flowI18n.js +117 -0
  145. package/lib/flowSettings.d.ts +266 -0
  146. package/lib/flowSettings.js +850 -0
  147. package/lib/hooks/index.d.ts +14 -0
  148. package/lib/hooks/index.js +40 -0
  149. package/lib/hooks/useApplyAutoFlows.d.ts +21 -0
  150. package/lib/hooks/useApplyAutoFlows.js +63 -0
  151. package/lib/hooks/useFlowModel.d.ts +29 -0
  152. package/lib/hooks/useFlowModel.js +72 -0
  153. package/lib/hooks/useFlowModelById.d.ts +11 -0
  154. package/lib/hooks/useFlowModelById.js +61 -0
  155. package/lib/hooks/useFlowSettingsContext.d.ts +20 -0
  156. package/lib/hooks/useFlowSettingsContext.js +61 -0
  157. package/lib/hooks/useFlowStep.d.ts +17 -0
  158. package/lib/hooks/useFlowStep.js +56 -0
  159. package/lib/hooks/useNiceDropdownMaxHeight.d.ts +13 -0
  160. package/lib/hooks/useNiceDropdownMaxHeight.js +52 -0
  161. package/lib/index.d.ts +30 -0
  162. package/lib/index.js +93 -0
  163. package/lib/locale/en-US.json +61 -0
  164. package/lib/locale/index.d.ts +141 -0
  165. package/lib/locale/index.js +70 -0
  166. package/lib/locale/zh-CN.json +61 -0
  167. package/lib/models/CollectionFieldModel.d.ts +52 -0
  168. package/lib/models/CollectionFieldModel.js +280 -0
  169. package/lib/models/DisplayItemModel.d.ts +12 -0
  170. package/lib/models/DisplayItemModel.js +41 -0
  171. package/lib/models/EditableItemModel.d.ts +12 -0
  172. package/lib/models/EditableItemModel.js +41 -0
  173. package/lib/models/FilterableItemModel.d.ts +12 -0
  174. package/lib/models/FilterableItemModel.js +41 -0
  175. package/lib/models/flowModel.d.ts +342 -0
  176. package/lib/models/flowModel.js +1154 -0
  177. package/lib/models/forkFlowModel.d.ts +83 -0
  178. package/lib/models/forkFlowModel.js +280 -0
  179. package/lib/models/index.d.ts +14 -0
  180. package/lib/models/index.js +40 -0
  181. package/lib/provider.d.ts +22 -0
  182. package/lib/provider.js +115 -0
  183. package/lib/resources/apiResource.d.ts +34 -0
  184. package/lib/resources/apiResource.js +153 -0
  185. package/lib/resources/baseRecordResource.d.ts +61 -0
  186. package/lib/resources/baseRecordResource.js +264 -0
  187. package/lib/resources/filterItem.d.ts +33 -0
  188. package/lib/resources/filterItem.js +93 -0
  189. package/lib/resources/flowResource.d.ts +45 -0
  190. package/lib/resources/flowResource.js +146 -0
  191. package/lib/resources/index.d.ts +15 -0
  192. package/lib/resources/index.js +42 -0
  193. package/lib/resources/multiRecordResource.d.ts +53 -0
  194. package/lib/resources/multiRecordResource.js +230 -0
  195. package/lib/resources/singleRecordResource.d.ts +23 -0
  196. package/lib/resources/singleRecordResource.js +111 -0
  197. package/lib/resources/sqlResource.d.ts +73 -0
  198. package/lib/resources/sqlResource.js +294 -0
  199. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +11 -0
  200. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +73 -0
  201. package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +11 -0
  202. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +91 -0
  203. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +11 -0
  204. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +58 -0
  205. package/lib/runjs-context/contexts/JSColumnRunJSContext.d.ts +15 -0
  206. package/lib/runjs-context/contexts/JSColumnRunJSContext.js +78 -0
  207. package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +11 -0
  208. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +74 -0
  209. package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +11 -0
  210. package/lib/runjs-context/contexts/JSItemRunJSContext.js +70 -0
  211. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +11 -0
  212. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +60 -0
  213. package/lib/runjs-context/contexts/base.d.ts +9 -0
  214. package/lib/runjs-context/contexts/base.js +169 -0
  215. package/lib/runjs-context/helpers.d.ts +20 -0
  216. package/lib/runjs-context/helpers.js +88 -0
  217. package/lib/runjs-context/registry.d.ts +20 -0
  218. package/lib/runjs-context/registry.js +61 -0
  219. package/lib/runjs-context/setup.d.ts +9 -0
  220. package/lib/runjs-context/setup.js +82 -0
  221. package/lib/runjs-context/snippets/global/api-request.snippet.d.ts +11 -0
  222. package/lib/runjs-context/snippets/global/api-request.snippet.js +57 -0
  223. package/lib/runjs-context/snippets/global/import-esm.snippet.d.ts +11 -0
  224. package/lib/runjs-context/snippets/global/import-esm.snippet.js +58 -0
  225. package/lib/runjs-context/snippets/global/message-error.snippet.d.ts +11 -0
  226. package/lib/runjs-context/snippets/global/message-error.snippet.js +47 -0
  227. package/lib/runjs-context/snippets/global/message-success.snippet.d.ts +11 -0
  228. package/lib/runjs-context/snippets/global/message-success.snippet.js +47 -0
  229. package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +11 -0
  230. package/lib/runjs-context/snippets/global/notification-open.snippet.js +50 -0
  231. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.d.ts +11 -0
  232. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +54 -0
  233. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.d.ts +11 -0
  234. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +54 -0
  235. package/lib/runjs-context/snippets/global/query-selector.snippet.d.ts +11 -0
  236. package/lib/runjs-context/snippets/global/query-selector.snippet.js +53 -0
  237. package/lib/runjs-context/snippets/global/require-amd.snippet.d.ts +11 -0
  238. package/lib/runjs-context/snippets/global/require-amd.snippet.js +49 -0
  239. package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +11 -0
  240. package/lib/runjs-context/snippets/global/window-open.snippet.js +48 -0
  241. package/lib/runjs-context/snippets/index.d.ts +22 -0
  242. package/lib/runjs-context/snippets/index.js +213 -0
  243. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.d.ts +11 -0
  244. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.js +55 -0
  245. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.d.ts +11 -0
  246. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +64 -0
  247. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.d.ts +11 -0
  248. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +99 -0
  249. package/lib/runjs-context/snippets/scene/block/echarts-init.snippet.d.ts +11 -0
  250. package/lib/runjs-context/snippets/scene/block/echarts-init.snippet.js +63 -0
  251. package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.d.ts +11 -0
  252. package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.js +52 -0
  253. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.d.ts +11 -0
  254. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +57 -0
  255. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.d.ts +11 -0
  256. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.js +72 -0
  257. package/lib/runjs-context/snippets/scene/block/render-react.snippet.d.ts +11 -0
  258. package/lib/runjs-context/snippets/scene/block/render-react.snippet.js +57 -0
  259. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.d.ts +11 -0
  260. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +100 -0
  261. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.d.ts +11 -0
  262. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +85 -0
  263. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.d.ts +11 -0
  264. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +60 -0
  265. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.d.ts +11 -0
  266. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +283 -0
  267. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.d.ts +11 -0
  268. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +124 -0
  269. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.d.ts +11 -0
  270. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.js +52 -0
  271. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.d.ts +11 -0
  272. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.js +64 -0
  273. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.d.ts +11 -0
  274. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.js +51 -0
  275. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.d.ts +11 -0
  276. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.js +50 -0
  277. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.d.ts +11 -0
  278. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +82 -0
  279. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.d.ts +11 -0
  280. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +80 -0
  281. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.d.ts +11 -0
  282. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +74 -0
  283. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.d.ts +11 -0
  284. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.js +63 -0
  285. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.d.ts +11 -0
  286. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +81 -0
  287. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.d.ts +11 -0
  288. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.js +64 -0
  289. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.d.ts +11 -0
  290. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.js +74 -0
  291. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.d.ts +11 -0
  292. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.js +53 -0
  293. package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.d.ts +11 -0
  294. package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.js +69 -0
  295. package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.d.ts +11 -0
  296. package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.js +68 -0
  297. package/lib/runjs-context/snippets/scene/form/set-required.snippet.d.ts +11 -0
  298. package/lib/runjs-context/snippets/scene/form/set-required.snippet.js +69 -0
  299. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.d.ts +11 -0
  300. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.js +67 -0
  301. package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.d.ts +11 -0
  302. package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.js +69 -0
  303. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.d.ts +11 -0
  304. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +64 -0
  305. package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.d.ts +11 -0
  306. package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.js +53 -0
  307. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.d.ts +11 -0
  308. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +79 -0
  309. package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.d.ts +11 -0
  310. package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.js +55 -0
  311. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.d.ts +11 -0
  312. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.js +64 -0
  313. package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.d.ts +11 -0
  314. package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.js +52 -0
  315. package/lib/runjs-context/snippets/types.d.ts +24 -0
  316. package/lib/runjs-context/snippets/types.js +24 -0
  317. package/lib/types.d.ts +407 -0
  318. package/lib/types.js +43 -0
  319. package/lib/utils/autoFlowError.d.ts +16 -0
  320. package/lib/utils/autoFlowError.js +53 -0
  321. package/lib/utils/constants.d.ts +29 -0
  322. package/lib/utils/constants.js +77 -0
  323. package/lib/utils/context.d.ts +40 -0
  324. package/lib/utils/context.js +63 -0
  325. package/lib/utils/createCollectionContextMeta.d.ts +11 -0
  326. package/lib/utils/createCollectionContextMeta.js +117 -0
  327. package/lib/utils/exceptions.d.ts +22 -0
  328. package/lib/utils/exceptions.js +62 -0
  329. package/lib/utils/flow-definitions.d.ts +11 -0
  330. package/lib/utils/flow-definitions.js +40 -0
  331. package/lib/utils/index.d.ts +22 -0
  332. package/lib/utils/index.js +115 -0
  333. package/lib/utils/inheritance.d.ts +16 -0
  334. package/lib/utils/inheritance.js +53 -0
  335. package/lib/utils/params-resolvers.d.ts +51 -0
  336. package/lib/utils/params-resolvers.js +309 -0
  337. package/lib/utils/parsePathnameToViewParams.d.ts +34 -0
  338. package/lib/utils/parsePathnameToViewParams.js +84 -0
  339. package/lib/utils/safeGlobals.d.ts +16 -0
  340. package/lib/utils/safeGlobals.js +179 -0
  341. package/lib/utils/schema-utils.d.ts +40 -0
  342. package/lib/utils/schema-utils.js +161 -0
  343. package/lib/utils/serverContextParams.d.ts +29 -0
  344. package/lib/utils/serverContextParams.js +106 -0
  345. package/lib/utils/setupRuntimeContextSteps.d.ts +19 -0
  346. package/lib/utils/setupRuntimeContextSteps.js +88 -0
  347. package/lib/utils/translation.d.ts +18 -0
  348. package/lib/utils/translation.js +58 -0
  349. package/lib/utils/variablesParams.d.ts +52 -0
  350. package/lib/utils/variablesParams.js +161 -0
  351. package/lib/views/DialogComponent.d.ts +22 -0
  352. package/lib/views/DialogComponent.js +98 -0
  353. package/lib/views/DrawerComponent.d.ts +11 -0
  354. package/lib/views/DrawerComponent.js +101 -0
  355. package/lib/views/FlowView.d.ts +76 -0
  356. package/lib/views/FlowView.js +81 -0
  357. package/lib/views/PageComponent.d.ts +10 -0
  358. package/lib/views/PageComponent.js +168 -0
  359. package/lib/views/ViewNavigation.d.ts +45 -0
  360. package/lib/views/ViewNavigation.js +97 -0
  361. package/lib/views/createViewMeta.d.ts +44 -0
  362. package/lib/views/createViewMeta.js +377 -0
  363. package/lib/views/index.d.ts +14 -0
  364. package/lib/views/index.js +51 -0
  365. package/lib/views/useDialog.d.ts +32 -0
  366. package/lib/views/useDialog.js +200 -0
  367. package/lib/views/useDrawer.d.ts +33 -0
  368. package/lib/views/useDrawer.js +220 -0
  369. package/lib/views/usePage.d.ts +32 -0
  370. package/lib/views/usePage.js +194 -0
  371. package/lib/views/usePatchElement.d.ts +10 -0
  372. package/lib/views/usePatchElement.js +54 -0
  373. package/lib/views/usePopover.d.ts +17 -0
  374. package/lib/views/usePopover.js +159 -0
  375. package/package.json +37 -0
  376. package/src/ContextPathProxy.ts +45 -0
  377. package/src/ElementProxy.ts +69 -0
  378. package/src/FlowContextProvider.tsx +42 -0
  379. package/src/FlowDefinition.ts +275 -0
  380. package/src/JSRunner.ts +84 -0
  381. package/src/ReactView.tsx +104 -0
  382. package/src/ViewScopedFlowEngine.ts +75 -0
  383. package/src/__tests__/ElementProxy.test.ts +51 -0
  384. package/src/__tests__/JSRunner.test.ts +92 -0
  385. package/src/__tests__/ReactView.test.tsx +63 -0
  386. package/src/__tests__/context-path-proxy.test.ts +35 -0
  387. package/src/__tests__/flow-engine.test.ts +189 -0
  388. package/src/__tests__/flowContext.test.ts +2012 -0
  389. package/src/__tests__/flowContextCreateJSRunner.test.ts +163 -0
  390. package/src/__tests__/flowEngine.saveModel.test.ts +171 -0
  391. package/src/__tests__/flowI18n.test.ts +28 -0
  392. package/src/__tests__/flowModel.getFlows.test.ts +61 -0
  393. package/src/__tests__/flowModel.openView.navigation.test.ts +78 -0
  394. package/src/__tests__/flowRunJSContextDefine.test.ts +508 -0
  395. package/src/__tests__/flowRuntimeContext.test.ts +187 -0
  396. package/src/__tests__/flowSettings.open.test.tsx +1920 -0
  397. package/src/__tests__/flowSettings.test.ts +566 -0
  398. package/src/__tests__/globalFlowRegistry.test.ts +77 -0
  399. package/src/__tests__/isFieldInterfaceMatch.test.ts +51 -0
  400. package/src/__tests__/metaTreeNodeCache.test.ts +234 -0
  401. package/src/__tests__/path-aggregation.test.ts +85 -0
  402. package/src/__tests__/provider.test.tsx +28 -0
  403. package/src/__tests__/renderHiddenInConfig.test.tsx +91 -0
  404. package/src/__tests__/runjsContext.test.ts +241 -0
  405. package/src/__tests__/runjsContextImplementations.test.ts +217 -0
  406. package/src/__tests__/runjsContextRuntime.test.ts +269 -0
  407. package/src/__tests__/runjsEdgeCases.test.ts +281 -0
  408. package/src/__tests__/runjsLocales.test.ts +36 -0
  409. package/src/__tests__/runjsRuntimeFeatures.test.ts +449 -0
  410. package/src/__tests__/runjsSnippets.test.ts +140 -0
  411. package/src/__tests__/viewScopedFlowEngine.test.ts +212 -0
  412. package/src/acl/Acl.tsx +109 -0
  413. package/src/acl/__tests__/Acl.test.tsx +72 -0
  414. package/src/action-registry/BaseActionRegistry.ts +46 -0
  415. package/src/action-registry/EngineActionRegistry.ts +32 -0
  416. package/src/action-registry/ModelActionRegistry.ts +75 -0
  417. package/src/action-registry/__tests__/engineActionRegistry.test.ts +43 -0
  418. package/src/action-registry/__tests__/modelActionRegistry.test.ts +107 -0
  419. package/src/components/DynamicFlowsEditor.tsx +318 -0
  420. package/src/components/FieldModelRenderer.tsx +68 -0
  421. package/src/components/FlowContextSelector.tsx +255 -0
  422. package/src/components/FlowErrorFallback.tsx +316 -0
  423. package/src/components/FlowModelRenderer.tsx +362 -0
  424. package/src/components/FormItem.tsx +136 -0
  425. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +226 -0
  426. package/src/components/__tests__/gridDragPlanner.test.ts +494 -0
  427. package/src/components/common/FlowSettingsButton.tsx +30 -0
  428. package/src/components/common/index.ts +10 -0
  429. package/src/components/common/withFlowDesignMode.tsx +49 -0
  430. package/src/components/dnd/README.md +149 -0
  431. package/src/components/dnd/findModelUidPosition.ts +26 -0
  432. package/src/components/dnd/gridDragPlanner.ts +659 -0
  433. package/src/components/dnd/index.tsx +128 -0
  434. package/src/components/index.ts +20 -0
  435. package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +279 -0
  436. package/src/components/settings/independents/dropdown/index.ts +10 -0
  437. package/src/components/settings/independents/index.ts +2 -0
  438. package/src/components/settings/index.ts +11 -0
  439. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +617 -0
  440. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +292 -0
  441. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +655 -0
  442. package/src/components/settings/wrappers/contextual/StepRequiredSettingsDialog.tsx +446 -0
  443. package/src/components/settings/wrappers/contextual/StepSettings.tsx +109 -0
  444. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +223 -0
  445. package/src/components/settings/wrappers/contextual/StepSettingsDrawer.tsx +32 -0
  446. package/src/components/settings/wrappers/contextual/index.ts +15 -0
  447. package/src/components/settings/wrappers/embedded/FlowSettings.tsx +258 -0
  448. package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +111 -0
  449. package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +96 -0
  450. package/src/components/settings/wrappers/embedded/index.ts +11 -0
  451. package/src/components/settings/wrappers/index.ts +5 -0
  452. package/src/components/subModel/AddSubModelButton.tsx +575 -0
  453. package/src/components/subModel/LazyDropdown.tsx +714 -0
  454. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +1185 -0
  455. package/src/components/subModel/__tests__/buildWrapperFieldChildren.test.ts +192 -0
  456. package/src/components/subModel/__tests__/utils.test.ts +425 -0
  457. package/src/components/subModel/index.ts +12 -0
  458. package/src/components/subModel/utils.ts +278 -0
  459. package/src/components/variables/InlineVariableTag.tsx +97 -0
  460. package/src/components/variables/SlateVariableEditor.tsx +384 -0
  461. package/src/components/variables/VariableInput.tsx +360 -0
  462. package/src/components/variables/VariableTag.tsx +175 -0
  463. package/src/components/variables/VariableTrigger.tsx +116 -0
  464. package/src/components/variables/__tests__/FlowContextSelector.test.tsx +553 -0
  465. package/src/components/variables/__tests__/VariableInput.test.tsx +550 -0
  466. package/src/components/variables/__tests__/VariableTag.test.tsx +347 -0
  467. package/src/components/variables/__tests__/test-utils.tsx +62 -0
  468. package/src/components/variables/__tests__/utils.test.ts +310 -0
  469. package/src/components/variables/index.ts +16 -0
  470. package/src/components/variables/types.ts +100 -0
  471. package/src/components/variables/useResolvedMetaTree.ts +76 -0
  472. package/src/components/variables/utils.ts +192 -0
  473. package/src/data-source/__tests__/collection.test.ts +58 -0
  474. package/src/data-source/__tests__/index.test.ts +82 -0
  475. package/src/data-source/__tests__/jioToJoiSchema.test.ts +56 -0
  476. package/src/data-source/__tests__/sortCollectionsByInherits.test.ts +125 -0
  477. package/src/data-source/index.ts +816 -0
  478. package/src/data-source/jioToJoiSchema.ts +103 -0
  479. package/src/data-source/sortCollectionsByInherits.ts +61 -0
  480. package/src/decorators/index.ts +10 -0
  481. package/src/decorators/largeField.ts +14 -0
  482. package/src/emitter.ts +33 -0
  483. package/src/event-registry/BaseEventRegistry.ts +40 -0
  484. package/src/event-registry/EngineEventRegistry.ts +26 -0
  485. package/src/event-registry/ModelEventRegistry.ts +69 -0
  486. package/src/event-registry/__tests__/engineEventRegistry.test.ts +48 -0
  487. package/src/executor/FlowExecutor.ts +302 -0
  488. package/src/executor/__tests__/eventStep.test.ts +157 -0
  489. package/src/executor/__tests__/flowExecutor.test.ts +309 -0
  490. package/src/flow-registry/BaseFlowRegistry.ts +91 -0
  491. package/src/flow-registry/GlobalFlowRegistry.ts +82 -0
  492. package/src/flow-registry/InstanceFlowRegistry.ts +39 -0
  493. package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +141 -0
  494. package/src/flow-registry/__tests__/instance-and-global-registry.test.ts +67 -0
  495. package/src/flow-registry/__tests__/instanceFlowRegistry.test.ts +83 -0
  496. package/src/flow-registry/index.ts +12 -0
  497. package/src/flowContext.ts +1742 -0
  498. package/src/flowEngine.ts +905 -0
  499. package/src/flowI18n.ts +96 -0
  500. package/src/flowSettings.ts +1045 -0
  501. package/src/hooks/index.ts +15 -0
  502. package/src/hooks/useApplyAutoFlows.ts +53 -0
  503. package/src/hooks/useFlowModel.tsx +59 -0
  504. package/src/hooks/useFlowModelById.ts +37 -0
  505. package/src/hooks/useFlowSettingsContext.tsx +37 -0
  506. package/src/hooks/useFlowStep.tsx +19 -0
  507. package/src/hooks/useNiceDropdownMaxHeight.ts +34 -0
  508. package/src/index.ts +46 -0
  509. package/src/locale/en-US.json +61 -0
  510. package/src/locale/index.ts +38 -0
  511. package/src/locale/zh-CN.json +61 -0
  512. package/src/models/CollectionFieldModel.tsx +306 -0
  513. package/src/models/DisplayItemModel.tsx +13 -0
  514. package/src/models/EditableItemModel.tsx +13 -0
  515. package/src/models/FilterableItemModel.tsx +13 -0
  516. package/src/models/__tests__/CollectionFieldModel.test.ts +122 -0
  517. package/src/models/__tests__/defaultParams-on-create.test.ts +83 -0
  518. package/src/models/__tests__/flow-model-oninit.test.ts +44 -0
  519. package/src/models/__tests__/flowModel.actions.integration.test.ts +100 -0
  520. package/src/models/__tests__/flowModel.getFlows.sort.test.ts +100 -0
  521. package/src/models/__tests__/flowModel.test.ts +2869 -0
  522. package/src/models/__tests__/flowRegistry.test.ts +512 -0
  523. package/src/models/__tests__/forkFlowModel.test.ts +1047 -0
  524. package/src/models/__tests__/model-actions.test.ts +70 -0
  525. package/src/models/__tests__/model-events.test.ts +69 -0
  526. package/src/models/flowModel.tsx +1421 -0
  527. package/src/models/forkFlowModel.ts +319 -0
  528. package/src/models/index.ts +17 -0
  529. package/src/provider.tsx +103 -0
  530. package/src/resources/__tests__/apiResource.test.ts +201 -0
  531. package/src/resources/__tests__/baseRecordResource.test.ts +262 -0
  532. package/src/resources/__tests__/filterItem.test.ts +260 -0
  533. package/src/resources/__tests__/flowResource.test.ts +127 -0
  534. package/src/resources/apiResource.ts +148 -0
  535. package/src/resources/baseRecordResource.ts +279 -0
  536. package/src/resources/filterItem.ts +74 -0
  537. package/src/resources/flowResource.ts +143 -0
  538. package/src/resources/index.ts +17 -0
  539. package/src/resources/multiRecordResource.ts +219 -0
  540. package/src/resources/singleRecordResource.ts +83 -0
  541. package/src/resources/sqlResource.ts +299 -0
  542. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +46 -0
  543. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +64 -0
  544. package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +31 -0
  545. package/src/runjs-context/contexts/JSColumnRunJSContext.ts +58 -0
  546. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +48 -0
  547. package/src/runjs-context/contexts/JSItemRunJSContext.ts +43 -0
  548. package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +33 -0
  549. package/src/runjs-context/contexts/base.ts +155 -0
  550. package/src/runjs-context/helpers.ts +58 -0
  551. package/src/runjs-context/registry.ts +34 -0
  552. package/src/runjs-context/setup.ts +51 -0
  553. package/src/runjs-context/snippets/global/api-request.snippet.ts +38 -0
  554. package/src/runjs-context/snippets/global/import-esm.snippet.ts +39 -0
  555. package/src/runjs-context/snippets/global/message-error.snippet.ts +26 -0
  556. package/src/runjs-context/snippets/global/message-success.snippet.ts +26 -0
  557. package/src/runjs-context/snippets/global/notification-open.snippet.ts +31 -0
  558. package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +33 -0
  559. package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +33 -0
  560. package/src/runjs-context/snippets/global/query-selector.snippet.ts +34 -0
  561. package/src/runjs-context/snippets/global/require-amd.snippet.ts +30 -0
  562. package/src/runjs-context/snippets/global/window-open.snippet.ts +29 -0
  563. package/src/runjs-context/snippets/index.ts +195 -0
  564. package/src/runjs-context/snippets/scene/block/add-event-listener.snippet.ts +41 -0
  565. package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +45 -0
  566. package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +80 -0
  567. package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +44 -0
  568. package/src/runjs-context/snippets/scene/block/render-button-handler.snippet.ts +33 -0
  569. package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +38 -0
  570. package/src/runjs-context/snippets/scene/block/render-info-card.snippet.ts +53 -0
  571. package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +38 -0
  572. package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +81 -0
  573. package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +66 -0
  574. package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +46 -0
  575. package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +264 -0
  576. package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +105 -0
  577. package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +33 -0
  578. package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +45 -0
  579. package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +32 -0
  580. package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +31 -0
  581. package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +63 -0
  582. package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +61 -0
  583. package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +55 -0
  584. package/src/runjs-context/snippets/scene/form/calculate-total.snippet.ts +44 -0
  585. package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +62 -0
  586. package/src/runjs-context/snippets/scene/form/conditional-required.snippet.ts +45 -0
  587. package/src/runjs-context/snippets/scene/form/copy-field-values.snippet.ts +55 -0
  588. package/src/runjs-context/snippets/scene/form/render-basic.snippet.ts +39 -0
  589. package/src/runjs-context/snippets/scene/form/set-disabled.snippet.ts +50 -0
  590. package/src/runjs-context/snippets/scene/form/set-field-value.snippet.ts +49 -0
  591. package/src/runjs-context/snippets/scene/form/set-required.snippet.ts +50 -0
  592. package/src/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.ts +48 -0
  593. package/src/runjs-context/snippets/scene/form/toggle-visible.snippet.ts +50 -0
  594. package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +45 -0
  595. package/src/runjs-context/snippets/scene/table/collection-selected-count.snippet.ts +34 -0
  596. package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +60 -0
  597. package/src/runjs-context/snippets/scene/table/destroy-selected.snippet.ts +36 -0
  598. package/src/runjs-context/snippets/scene/table/export-selected-json.snippet.ts +45 -0
  599. package/src/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.ts +33 -0
  600. package/src/runjs-context/snippets/types.ts +21 -0
  601. package/src/types.ts +484 -0
  602. package/src/utils/__tests__/context.test.ts +93 -0
  603. package/src/utils/__tests__/params-resolvers.test.ts +652 -0
  604. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +104 -0
  605. package/src/utils/__tests__/safeGlobals.test.ts +29 -0
  606. package/src/utils/__tests__/utils.test.ts +1021 -0
  607. package/src/utils/__tests__/variablesParams.test.ts +52 -0
  608. package/src/utils/autoFlowError.ts +29 -0
  609. package/src/utils/constants.ts +60 -0
  610. package/src/utils/context.ts +70 -0
  611. package/src/utils/createCollectionContextMeta.ts +122 -0
  612. package/src/utils/exceptions.ts +36 -0
  613. package/src/utils/flow-definitions.ts +16 -0
  614. package/src/utils/index.ts +62 -0
  615. package/src/utils/inheritance.ts +39 -0
  616. package/src/utils/params-resolvers.ts +482 -0
  617. package/src/utils/parsePathnameToViewParams.ts +103 -0
  618. package/src/utils/safeGlobals.ts +188 -0
  619. package/src/utils/schema-utils.ts +201 -0
  620. package/src/utils/serverContextParams.ts +112 -0
  621. package/src/utils/setupRuntimeContextSteps.ts +89 -0
  622. package/src/utils/translation.ts +37 -0
  623. package/src/utils/variablesParams.ts +184 -0
  624. package/src/views/DialogComponent.tsx +79 -0
  625. package/src/views/DrawerComponent.tsx +72 -0
  626. package/src/views/FlowView.tsx +103 -0
  627. package/src/views/PageComponent.tsx +150 -0
  628. package/src/views/ViewNavigation.ts +122 -0
  629. package/src/views/__tests__/FlowView.test.ts +31 -0
  630. package/src/views/__tests__/ViewNavigation.test.ts +191 -0
  631. package/src/views/__tests__/usePatchElement.test.tsx +28 -0
  632. package/src/views/createViewMeta.ts +402 -0
  633. package/src/views/index.tsx +15 -0
  634. package/src/views/useDialog.tsx +194 -0
  635. package/src/views/useDrawer.tsx +229 -0
  636. package/src/views/usePage.tsx +185 -0
  637. package/src/views/usePatchElement.tsx +27 -0
  638. package/src/views/usePopover.tsx +131 -0
@@ -0,0 +1,1421 @@
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 { batch, define, observable, observe } from '@formily/reactive';
11
+ import { observer } from '@formily/reactive-react';
12
+ import _ from 'lodash';
13
+ import React from 'react';
14
+ import { uid } from 'uid/secure';
15
+ import { openRequiredParamsStepFormDialog as openRequiredParamsStepFormDialogFn } from '../components/settings/wrappers/contextual/StepRequiredSettingsDialog';
16
+ import { openStepSettingsDialog as openStepSettingsDialogFn } from '../components/settings/wrappers/contextual/StepSettingsDialog';
17
+ import { Emitter } from '../emitter';
18
+ import { InstanceFlowRegistry } from '../flow-registry/InstanceFlowRegistry';
19
+ import { FlowContext, FlowModelContext, FlowRuntimeContext } from '../flowContext';
20
+ import { FlowEngine } from '../flowEngine';
21
+ import type {
22
+ ActionDefinition,
23
+ ArrayElementType,
24
+ CreateModelOptions,
25
+ CreateSubModelOptions,
26
+ DefaultStructure,
27
+ FlowDefinitionOptions,
28
+ FlowModelMeta,
29
+ FlowModelOptions,
30
+ ModelConstructor,
31
+ ParamObject,
32
+ ParentFlowModel,
33
+ PersistOptions,
34
+ StepDefinition,
35
+ StepParams,
36
+ } from '../types';
37
+ import { IModelComponentProps, ReadonlyModelProps } from '../types';
38
+ import {
39
+ FlowExitException,
40
+ isInheritedFrom,
41
+ resolveDefaultParams,
42
+ resolveExpressions,
43
+ setupRuntimeContextSteps,
44
+ } from '../utils';
45
+ // import { FlowExitAllException } from '../utils/exceptions';
46
+ import { Typography } from 'antd/lib';
47
+ import { ModelActionRegistry } from '../action-registry/ModelActionRegistry';
48
+ import { buildSubModelItem } from '../components/subModel/utils';
49
+ import { ModelEventRegistry } from '../event-registry/ModelEventRegistry';
50
+ import { GlobalFlowRegistry } from '../flow-registry/GlobalFlowRegistry';
51
+ import { FlowDefinition } from '../FlowDefinition';
52
+ import { FlowSettingsOpenOptions } from '../flowSettings';
53
+ import type { EventDefinition, FlowEvent, DispatchEventOptions } from '../types';
54
+ import { ForkFlowModel } from './forkFlowModel';
55
+
56
+ // 使用 WeakMap 为每个类缓存一个 ModelActionRegistry 实例
57
+ const classActionRegistries = new WeakMap<typeof FlowModel, ModelActionRegistry>();
58
+
59
+ // 使用 WeakMap 为每个类缓存一个 ModelEventRegistry 实例
60
+ const classEventRegistries = new WeakMap<typeof FlowModel, ModelEventRegistry>();
61
+
62
+ // 使用WeakMap存储每个类的meta
63
+ const modelMetas = new WeakMap<typeof FlowModel, FlowModelMeta>();
64
+
65
+ // 使用WeakMap存储每个类的 GlobalFlowRegistry
66
+ const modelGlobalRegistries = new WeakMap<typeof FlowModel, GlobalFlowRegistry>();
67
+
68
+ export enum ModelRenderMode {
69
+ ReactElement = 'reactElement',
70
+ RenderFunction = 'renderFunction',
71
+ }
72
+
73
+ export class FlowModel<Structure extends DefaultStructure = DefaultStructure> {
74
+ /**
75
+ * 当 flowSettings.enabled 且 model.hidden 为 true 时用于渲染设置态组件(实例方法,子类可覆盖)。
76
+ * 基类默认仅返回一个透明度降低的占位元素
77
+ */
78
+ protected renderHiddenInConfig(): React.ReactNode | undefined {
79
+ return <span style={{ opacity: 0.5 }}>{this.translate?.('Hidden') || 'Hidden'}</span>;
80
+ }
81
+ public readonly uid: string;
82
+ public sortIndex: number;
83
+ public hidden = false;
84
+ public props: IModelComponentProps = {};
85
+ public stepParams: StepParams = {};
86
+ public flowEngine: FlowEngine;
87
+ public parent: ParentFlowModel<Structure>;
88
+ public subModels: Structure['subModels'];
89
+ private _options: FlowModelOptions<Structure>;
90
+ protected _title: string;
91
+ public isNew = false; // 标记是否为新建状态
92
+
93
+ /**
94
+ * 所有 fork 实例的引用集合。
95
+ * 使用 Set 便于在销毁时主动遍历并调用 dispose,避免悬挂引用。
96
+ */
97
+ public forks: Set<ForkFlowModel<any>> = new Set();
98
+ public emitter: Emitter = new Emitter();
99
+
100
+ /**
101
+ * 基于 key 的 fork 实例缓存,用于复用 fork 实例
102
+ */
103
+ private forkCache: Map<string, ForkFlowModel<any>> = new Map();
104
+
105
+ /**
106
+ * 上一次 beforeRender 的执行参数
107
+ */
108
+ private _lastAutoRunParams: [Record<string, any> | undefined, boolean?] | null = null;
109
+ protected observerDispose: () => void;
110
+ #flowContext: FlowModelContext;
111
+
112
+ /**
113
+ * 原始 render 方法的引用
114
+ */
115
+ private _originalRender: (() => any) | null = null;
116
+
117
+ /**
118
+ * 缓存的响应式包装器组件(每个实例一个)
119
+ */
120
+ private _reactiveWrapperCache?: React.ComponentType;
121
+
122
+ flowRegistry: InstanceFlowRegistry;
123
+ private _cleanRun?: boolean;
124
+ /**
125
+ * 声明渲染模式:
126
+ * - 'renderElement': render 返回 React 节点,框架会用 observer 包装以获得响应式;
127
+ * - 'renderFunction': render 返回渲染函数(例如表格单元格渲染器),不做包装也不预调用;
128
+ */
129
+ static renderMode: ModelRenderMode = ModelRenderMode.ReactElement;
130
+
131
+ constructor(options: FlowModelOptions<Structure>) {
132
+ if (!options.flowEngine) {
133
+ throw new Error('FlowModel must be initialized with a FlowEngine instance.');
134
+ }
135
+ this.flowEngine = options.flowEngine;
136
+ if (this.flowEngine.getModel(options.uid)) {
137
+ // 此时 new FlowModel 并不创建新实例,而是返回已存在的实例,避免重复创建同一个model实例
138
+ return this.flowEngine.getModel(options.uid);
139
+ }
140
+
141
+ if (!options.uid) {
142
+ options.uid = uid();
143
+ }
144
+
145
+ this.uid = options.uid;
146
+ this.props = {
147
+ ...options.props,
148
+ };
149
+ this.stepParams = options.stepParams || {};
150
+ this.subModels = {};
151
+ this.sortIndex = options.sortIndex || 0;
152
+ this._options = options;
153
+
154
+ define(this, {
155
+ hidden: observable,
156
+ props: observable,
157
+ subModels: observable.shallow,
158
+ stepParams: observable,
159
+ // setProps: action,
160
+ setProps: batch,
161
+ // setStepParams: action,
162
+ setStepParams: batch,
163
+ });
164
+ // 保证onInit在所有属性都定义完成后调用
165
+ // queueMicrotask(() => {
166
+ // this.onInit(options);
167
+ // });
168
+
169
+ this.flowRegistry = new InstanceFlowRegistry(this);
170
+ this.flowRegistry.addFlows(options.flowRegistry);
171
+
172
+ this.observerDispose = observe(this.stepParams, (changed) => {
173
+ // if doesn't change, skip
174
+ if (changed.type === 'set' && _.isEqual(changed.value, changed.oldValue)) {
175
+ return;
176
+ }
177
+
178
+ if (this.flowEngine) {
179
+ this.invalidateFlowCache('beforeRender');
180
+ }
181
+ this._rerunLastAutoRun();
182
+ this.forks.forEach((fork) => {
183
+ fork.rerender();
184
+ });
185
+ });
186
+
187
+ // 设置 render 方法的响应式包装
188
+ try {
189
+ this.setupReactiveRender();
190
+ } catch (error) {
191
+ console.error(`Failed to setup reactive render for ${this.constructor.name}:`, error);
192
+ // 如果包装失败,确保 render 方法仍然可用
193
+ if (typeof this.render !== 'function') {
194
+ this.render = () => React.createElement('div', null, 'Render method not available');
195
+ }
196
+ }
197
+
198
+ this._cleanRun = !!options['cleanRun'];
199
+ }
200
+
201
+ /**
202
+ * 对外暴露的上下文:
203
+ */
204
+ get context() {
205
+ if (!this.#flowContext) {
206
+ this.#flowContext = new FlowModelContext(this);
207
+ }
208
+ return this.#flowContext;
209
+ }
210
+
211
+ on(eventName: string, listener: (...args: any[]) => void) {
212
+ this.emitter.on(eventName, listener);
213
+ }
214
+
215
+ onInit(options) {
216
+ // Dynamic flows loading is disabled. Previous logic preserved for reference:
217
+ /*
218
+ this.loadDynamicFlows()
219
+ .then((flows) => {
220
+ if (!_.isEmpty(flows)) {
221
+ this.setDynamicFlows(flows);
222
+ }
223
+ })
224
+ .catch((error) => {
225
+ console.error(`Failed to load dynamic flows for ${this.constructor.name}:`, error);
226
+ });
227
+ */
228
+ }
229
+
230
+ /**
231
+ * 通过 AddSubModelButton 添加为子模型后调用(子类可覆盖)
232
+ */
233
+ async afterAddAsSubModel() {}
234
+
235
+ get async() {
236
+ return this._options.async || false;
237
+ }
238
+
239
+ get use() {
240
+ return this._options.use;
241
+ }
242
+
243
+ get subKey() {
244
+ return this._options.subKey;
245
+ }
246
+
247
+ get subType() {
248
+ return this._options.subType;
249
+ }
250
+
251
+ get reactView() {
252
+ return this.flowEngine.reactView;
253
+ }
254
+
255
+ get parentId() {
256
+ return this._options.parentId;
257
+ }
258
+
259
+ static get meta() {
260
+ return modelMetas.get(this);
261
+ }
262
+
263
+ static get globalFlowRegistry(): GlobalFlowRegistry {
264
+ const Cls = this as unknown as typeof FlowModel;
265
+ let reg = modelGlobalRegistries.get(Cls);
266
+ if (!reg) {
267
+ reg = new GlobalFlowRegistry(Cls);
268
+ modelGlobalRegistries.set(Cls, reg);
269
+ }
270
+ return reg;
271
+ }
272
+
273
+ // 获取当前类的动作注册表(含父子链注入),按类缓存
274
+ protected static get actionRegistry(): ModelActionRegistry {
275
+ const ModelClass = this;
276
+ let registry = classActionRegistries.get(ModelClass);
277
+ if (!registry) {
278
+ let parentRegistry: ModelActionRegistry | null = null;
279
+ const ParentClass = Object.getPrototypeOf(ModelClass);
280
+ if (ParentClass && ParentClass !== Function.prototype && ParentClass !== Object.prototype) {
281
+ const isSubclassOfFlowModel = ParentClass === FlowModel || isInheritedFrom(ParentClass, FlowModel);
282
+ if (isSubclassOfFlowModel) {
283
+ parentRegistry = (ParentClass as typeof FlowModel).actionRegistry as ModelActionRegistry;
284
+ }
285
+ }
286
+ registry = new ModelActionRegistry(ModelClass, parentRegistry);
287
+ classActionRegistries.set(ModelClass, registry);
288
+ }
289
+ return registry;
290
+ }
291
+
292
+ // 获取当前类的事件注册表(含父子链注入),按类缓存
293
+ protected static get eventRegistry(): ModelEventRegistry {
294
+ const ModelClass = this;
295
+ let registry = classEventRegistries.get(ModelClass);
296
+ if (!registry) {
297
+ let parentRegistry: ModelEventRegistry | null = null;
298
+ const ParentClass = Object.getPrototypeOf(ModelClass);
299
+ if (ParentClass && ParentClass !== Function.prototype && ParentClass !== Object.prototype) {
300
+ const isSubclassOfFlowModel = ParentClass === FlowModel || isInheritedFrom(ParentClass, FlowModel);
301
+ if (isSubclassOfFlowModel) {
302
+ parentRegistry = (ParentClass as typeof FlowModel).eventRegistry as ModelEventRegistry;
303
+ }
304
+ }
305
+ registry = new ModelEventRegistry(ModelClass, parentRegistry);
306
+ classEventRegistries.set(ModelClass, registry);
307
+ }
308
+ return registry;
309
+ }
310
+
311
+ /**
312
+ * 注册仅当前 FlowModel 类及其子类可用的 Action。
313
+ * 该注册是类级别的,不会影响全局(FlowEngine)的 Action 注册。
314
+ */
315
+ public static registerAction<TModel extends FlowModel = FlowModel>(definition: ActionDefinition<TModel>): void {
316
+ this.actionRegistry.registerAction(definition);
317
+ }
318
+
319
+ /**
320
+ * 批量注册仅当前 FlowModel 类及其子类可用的 Actions。
321
+ */
322
+ public static registerActions<TModel extends FlowModel = FlowModel>(
323
+ actions: Record<string, ActionDefinition<TModel>>,
324
+ ): void {
325
+ this.actionRegistry.registerActions(actions);
326
+ }
327
+
328
+ /**
329
+ * 注册仅当前 FlowModel 类及其子类可用的 Event。
330
+ * 该注册是类级别的,不会影响全局(FlowEngine)的 Event 注册。
331
+ */
332
+ public static registerEvent<TModel extends FlowModel = FlowModel>(definition: EventDefinition<TModel>): void {
333
+ this.eventRegistry.registerEvent(definition);
334
+ }
335
+
336
+ /**
337
+ * 批量注册仅当前 FlowModel 类及其子类可用的 Events。
338
+ */
339
+ public static registerEvents<TModel extends FlowModel = FlowModel>(
340
+ events: Record<string, EventDefinition<TModel>>,
341
+ ): void {
342
+ this.eventRegistry.registerEvents(events);
343
+ }
344
+
345
+ static buildChildrenFromModels(ctx, Models: Array<any>) {
346
+ return Models.map((M) => buildSubModelItem(M, ctx, true));
347
+ }
348
+
349
+ get title() {
350
+ // model 可以通过 setTitle 来自定义title, 具有更高的优先级
351
+ return this.translate(this._title) || this.translate(this.constructor['meta']?.label);
352
+ }
353
+
354
+ setTitle(value: string) {
355
+ this._title = value;
356
+ }
357
+
358
+ setHidden(value: boolean) {
359
+ this.hidden = !!value;
360
+ }
361
+
362
+ _createSubModels(subModels: Record<string, CreateSubModelOptions | CreateSubModelOptions[]>) {
363
+ // Merge default subModels declared in meta.createModelOptions (object form) with provided subModels.
364
+ // Provided subModels take precedence over defaults.
365
+ let mergedSubModels: Record<string, CreateSubModelOptions | CreateSubModelOptions[]> = subModels || {};
366
+ try {
367
+ const Cls = this.constructor as typeof FlowModel;
368
+ const meta = Cls.meta as any;
369
+ const metaCreate = meta?.createModelOptions;
370
+ if (metaCreate && typeof metaCreate === 'object' && metaCreate.subModels) {
371
+ mergedSubModels = _.merge({}, _.cloneDeep(metaCreate.subModels || {}), _.cloneDeep(subModels || {}));
372
+ }
373
+ } catch (e) {
374
+ // Fallback silently if meta defaults resolution fails
375
+ }
376
+
377
+ Object.entries(mergedSubModels || {}).forEach(([key, value]) => {
378
+ if (Array.isArray(value)) {
379
+ value
380
+ .sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0))
381
+ .forEach((item) => {
382
+ this.addSubModel(key, item);
383
+ });
384
+ } else {
385
+ this.setSubModel(key, value);
386
+ }
387
+ });
388
+ }
389
+
390
+ /**
391
+ * 失效指定事件的流程缓存;未指定 eventName 时,失效当前模型全部事件缓存。
392
+ * - 默认 beforeRender 与其它事件共享同一缓存体系:prefix=`event:${scope}`,flowKey=`eventName`,uid=`model.uid`
393
+ */
394
+ public invalidateFlowCache(eventName?: string, deep = false) {
395
+ if (this.flowEngine) {
396
+ const scope = `event:${this.getFlowCacheScope(eventName || 'beforeRender')}`;
397
+ const cache = this.flowEngine.applyFlowCache;
398
+
399
+ if (eventName) {
400
+ // 删除该事件名下所有缓存(忽略不同 inputArgs 的散列差异)
401
+ const altScope = scope.replace(/:/g, '-');
402
+ const uidSuffixes = [`:${this.uid}`, `-${this.uid}`];
403
+ const eventSegments = [`:${eventName}:`, `-${eventName}-`];
404
+ for (const key of cache.keys()) {
405
+ const startMatches = key.startsWith(scope) || key.startsWith(altScope);
406
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
407
+ const eventMatches = eventSegments.some((seg) => key.includes(seg));
408
+ if (startMatches && endMatches && eventMatches) {
409
+ cache.delete(key);
410
+ }
411
+ }
412
+ } else {
413
+ // 粗粒度:扫描并删除当前模型 uid 相关的事件缓存(任意事件)
414
+ const altScope = `${scope}:`.replace(/:/g, '-');
415
+ const prefixes = [`${scope}:`, altScope];
416
+ const uidSuffixes = [`:${this.uid}`, `-${this.uid}`];
417
+ for (const key of cache.keys()) {
418
+ const startMatches = prefixes.some((p) => key.startsWith(p));
419
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
420
+ if (startMatches && endMatches) cache.delete(key);
421
+ }
422
+ }
423
+
424
+ // 同步失效所有 fork 的缓存
425
+ this.forks.forEach((fork) => {
426
+ const forkScope = `event:${
427
+ (fork as any).getFlowCacheScope?.(eventName || 'beforeRender') ?? String((fork as any)['forkId'])
428
+ }`;
429
+ const altForkScope = forkScope.replace(/:/g, '-');
430
+ const uidSuffixes = [`:${this.uid}`, `-${this.uid}`];
431
+ if (eventName) {
432
+ const eventSegments = [`:${eventName}:`, `-${eventName}-`];
433
+ for (const key of this.flowEngine.applyFlowCache.keys()) {
434
+ const startMatches = key.startsWith(forkScope) || key.startsWith(altForkScope);
435
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
436
+ const eventMatches = eventSegments.some((seg) => key.includes(seg));
437
+ if (startMatches && endMatches && eventMatches) this.flowEngine.applyFlowCache.delete(key);
438
+ }
439
+ } else {
440
+ const prefixes = [`${forkScope}:`, `${altForkScope}-`];
441
+ for (const key of this.flowEngine.applyFlowCache.keys()) {
442
+ const startMatches = prefixes.some((p) => key.startsWith(p));
443
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
444
+ if (startMatches && endMatches) this.flowEngine.applyFlowCache.delete(key);
445
+ }
446
+ }
447
+ });
448
+ }
449
+ if (deep) {
450
+ const subModelKeys = Object.keys(this.subModels);
451
+ for (const subModelKey of subModelKeys) {
452
+ const subModelValue = this.subModels[subModelKey];
453
+ if (Array.isArray(subModelValue)) {
454
+ for (const subModel of subModelValue) {
455
+ subModel.invalidateFlowCache(eventName, deep);
456
+ }
457
+ } else if (subModelValue instanceof FlowModel) {
458
+ subModelValue.invalidateFlowCache(eventName, deep);
459
+ }
460
+ }
461
+ }
462
+ }
463
+
464
+ /**
465
+ * 设置FlowEngine实例
466
+ * @param {FlowEngine} flowEngine FlowEngine实例
467
+ */
468
+ setFlowEngine(flowEngine: FlowEngine): void {
469
+ // this.flowEngine = flowEngine;
470
+ }
471
+
472
+ static define(meta: FlowModelMeta) {
473
+ modelMetas.set(this, meta);
474
+ }
475
+
476
+ /**
477
+ * 注册一个 Flow。
478
+ * @template TModel 具体的FlowModel子类类型
479
+ * @param {string | FlowDefinitionOptions<TModel>} keyOrDefinition 流程的 Key 或 FlowDefinitionOptions 对象。
480
+ * 如果为字符串,则为流程 Key,需要配合 flowDefinition 参数。
481
+ * 如果为对象,则为包含 key 属性的完整 FlowDefinitionOptions。
482
+ * @param {FlowDefinitionOptions<TModel>} [flowDefinition] 当第一个参数为流程 Key 时,此参数为流程的定义。
483
+ * @returns {void}
484
+ */
485
+ public static registerFlow<
486
+ TClass extends ModelConstructor,
487
+ TModel extends InstanceType<TClass> = InstanceType<TClass>,
488
+ >(
489
+ this: TClass,
490
+ keyOrDefinition: string | FlowDefinitionOptions<TModel>,
491
+ flowDefinition?: Omit<FlowDefinitionOptions<TModel>, 'key'> & { key?: string },
492
+ ): void {
493
+ const Cls = this as unknown as typeof FlowModel;
494
+ if (typeof keyOrDefinition === 'string') {
495
+ Cls.globalFlowRegistry.addFlow(keyOrDefinition, flowDefinition);
496
+ } else {
497
+ Cls.globalFlowRegistry.addFlow(keyOrDefinition.key, keyOrDefinition);
498
+ }
499
+ }
500
+
501
+ // /**
502
+ // * 清空所有注册的流程定义。在测试中用来清理已注册的流,防止对其它测试产生影响。
503
+ // */
504
+ // public static clearFlows(): void {
505
+ // modelFlows = new WeakMap<typeof FlowModel, Map<string, FlowDefinition>>();
506
+ // }
507
+
508
+ /**
509
+ * 获取已注册的流程定义。
510
+ * 如果当前类不存在对应的flow,会继续往父类查找。
511
+ * @param {string} key 流程 Key。
512
+ * @returns {FlowDefinition | undefined} 流程定义,如果未找到则返回 undefined。
513
+ */
514
+ public getFlow(key: string): FlowDefinition | undefined {
515
+ if (this.flowRegistry.hasFlow(key)) {
516
+ return this.flowRegistry.getFlow(key);
517
+ }
518
+ const Cls = this.constructor as typeof FlowModel;
519
+ return Cls.globalFlowRegistry.getFlow(key);
520
+ }
521
+
522
+ /**
523
+ * 注册一个实例级别的流程定义。
524
+ * @template TModel 具体的FlowModel子类类型
525
+ * @param {string | FlowDefinitionOptions<TModel>} keyOrDefinition 流程的 Key 或 FlowDefinitionOptions 对象。
526
+ * @param {FlowDefinitionOptions<TModel>} [flowDefinition] 当第一个参数为流程 Key 时,此参数为流程的定义。
527
+ * @returns {FlowDefinition} 注册的流程定义实例
528
+ */
529
+ public registerFlow<TModel extends FlowModel = this>(
530
+ keyOrDefinition: string | FlowDefinitionOptions<TModel>,
531
+ flowDefinition?: Omit<FlowDefinitionOptions<TModel>, 'key'> & { key?: string },
532
+ ): FlowDefinition {
533
+ if (typeof keyOrDefinition === 'string') {
534
+ return this.flowRegistry.addFlow(keyOrDefinition, flowDefinition);
535
+ } else {
536
+ return this.flowRegistry.addFlow(keyOrDefinition.key, keyOrDefinition);
537
+ }
538
+ }
539
+
540
+ /**
541
+ * 获取当前模型可用的所有 Actions:
542
+ * - 包含全局(FlowEngine)注册的 Actions;
543
+ * - 合并类级(FlowModel.registerAction(s))注册的 Actions,并考虑继承(子类覆盖父类同名 Action)。
544
+ */
545
+ public getActions<TModel extends FlowModel = this, TCtx extends FlowContext = FlowRuntimeContext<TModel>>(): Map<
546
+ string,
547
+ ActionDefinition<TModel, TCtx>
548
+ > {
549
+ const ModelClass = this.constructor as typeof FlowModel;
550
+ const merged = ModelClass.actionRegistry.getActions<TModel, TCtx>();
551
+ const actions = new Map<string, ActionDefinition<TModel, TCtx>>();
552
+ const globalActions = this.flowEngine?.getActions<TModel, TCtx>();
553
+ if (globalActions) for (const [k, v] of globalActions) actions.set(k, v);
554
+ for (const [k, v] of merged) actions.set(k, v);
555
+ return actions;
556
+ }
557
+
558
+ /**
559
+ * 获取当前模型可用的所有 Events:
560
+ * - 包含全局(FlowEngine)注册的 Events;
561
+ * - 合并类级(FlowModel.registerEvent(s))注册的 Events,并考虑继承(子类覆盖父类同名 Event)。
562
+ */
563
+ public getEvents<TModel extends FlowModel = this>(): Map<string, EventDefinition<TModel>> {
564
+ const ModelClass = this.constructor as typeof FlowModel;
565
+ const merged = ModelClass.eventRegistry.getEvents();
566
+ const events = new Map<string, EventDefinition<TModel>>();
567
+ const globalEvents = this.flowEngine?.getEvents<TModel>();
568
+ if (globalEvents) for (const [k, v] of globalEvents) events.set(k, v);
569
+ for (const [k, v] of merged) events.set(k, v);
570
+ return events;
571
+ }
572
+
573
+ /**
574
+ * 获取指定名称的 Event(优先返回类级注册的,未找到则回退到全局)。
575
+ */
576
+ public getEvent<TModel extends FlowModel = this>(name: string): EventDefinition<TModel> | undefined {
577
+ const ModelClass = this.constructor as typeof FlowModel;
578
+ const own = ModelClass.eventRegistry.getEvent(name) as EventDefinition<TModel> | undefined;
579
+ if (own) return own;
580
+ return this.flowEngine?.getEvent<TModel>(name);
581
+ }
582
+
583
+ /**
584
+ * 获取指定名称的 Action(优先返回类级注册的,未找到则回退到全局)。
585
+ */
586
+ public getAction<TModel extends FlowModel = this, TCtx extends FlowContext = FlowRuntimeContext<TModel>>(
587
+ name: string,
588
+ ): ActionDefinition<TModel, TCtx> | undefined {
589
+ const ModelClass = this.constructor as typeof FlowModel;
590
+ const own = ModelClass.actionRegistry.getAction<TModel, TCtx>(name);
591
+ if (own) return own;
592
+ return this.flowEngine?.getAction<TModel, TCtx>(name);
593
+ }
594
+
595
+ getFlows() {
596
+ // 分离获取:实例流(未排序)与静态流(在 GlobalFlowRegistry 中已排序)
597
+ const instanceFlows = this.flowRegistry.getFlows();
598
+ const staticFlows = (this.constructor as typeof FlowModel).globalFlowRegistry.getFlows();
599
+
600
+ // 跳过同名静态流(实例覆盖静态)
601
+ const instanceKeys = new Set(instanceFlows.keys());
602
+ const staticEntries = Array.from(staticFlows.entries()).filter(([key]) => !instanceKeys.has(key));
603
+
604
+ // 实例流保持原始注册顺序,统一一次排序(稳定排序):
605
+ const instanceEntries = Array.from(instanceFlows.entries());
606
+ const allEntries = [...staticEntries, ...instanceEntries];
607
+ allEntries.sort(([, a], [, b]) => {
608
+ const sa = a.sort ?? 0;
609
+ const sb = b.sort ?? 0;
610
+ if (sa !== sb) return sa - sb;
611
+ return 0; // 其它情况保持稳定顺序(静态内部:父类优先;实例内部:注册顺序)
612
+ });
613
+
614
+ return new Map<string, FlowDefinition>(allEntries);
615
+ }
616
+
617
+ setProps(props: IModelComponentProps): void;
618
+ setProps(key: string, value: any): void;
619
+ setProps(props: IModelComponentProps | string, value?: any): void {
620
+ if (typeof props === 'string') {
621
+ this.props[props] = value;
622
+ } else {
623
+ this.props = { ...this.props, ...props };
624
+ }
625
+ }
626
+
627
+ getProps(): ReadonlyModelProps {
628
+ return this.props as ReadonlyModelProps;
629
+ }
630
+
631
+ setStepParams(flowKey: string, stepKey: string, params: ParamObject): void;
632
+ setStepParams(flowKey: string, stepParams: Record<string, ParamObject>): void;
633
+ setStepParams(allParams: StepParams): void;
634
+ setStepParams(
635
+ flowKeyOrAllParams: string | StepParams,
636
+ stepKeyOrStepsParams?: string | Record<string, ParamObject>,
637
+ params?: ParamObject,
638
+ ): void {
639
+ if (typeof flowKeyOrAllParams === 'string') {
640
+ const flowKey = flowKeyOrAllParams;
641
+ if (typeof stepKeyOrStepsParams === 'string' && params !== undefined) {
642
+ if (!this.stepParams[flowKey]) {
643
+ this.stepParams[flowKey] = {};
644
+ }
645
+ this.stepParams[flowKey][stepKeyOrStepsParams] = {
646
+ ...this.stepParams[flowKey][stepKeyOrStepsParams],
647
+ ...params,
648
+ };
649
+ } else if (typeof stepKeyOrStepsParams === 'object' && stepKeyOrStepsParams !== null) {
650
+ this.stepParams[flowKey] = { ...(this.stepParams[flowKey] || {}), ...stepKeyOrStepsParams };
651
+ }
652
+ } else if (typeof flowKeyOrAllParams === 'object' && flowKeyOrAllParams !== null) {
653
+ for (const fk in flowKeyOrAllParams) {
654
+ if (Object.prototype.hasOwnProperty.call(flowKeyOrAllParams, fk)) {
655
+ this.stepParams[fk] = { ...(this.stepParams[fk] || {}), ...flowKeyOrAllParams[fk] };
656
+ }
657
+ }
658
+ }
659
+ }
660
+
661
+ getStepParams(flowKey: string, stepKey: string): any | undefined;
662
+ getStepParams(flowKey: string): Record<string, any> | undefined;
663
+ getStepParams(): StepParams;
664
+ getStepParams(flowKey?: string, stepKey?: string): any {
665
+ if (flowKey && stepKey) {
666
+ return this.stepParams[flowKey]?.[stepKey];
667
+ }
668
+ if (flowKey) {
669
+ return this.stepParams[flowKey];
670
+ }
671
+ return this.stepParams;
672
+ }
673
+
674
+ async applyFlow(flowKey: string, inputArgs?: Record<string, any>, runId?: string): Promise<any> {
675
+ const currentFlowEngine = this.flowEngine;
676
+ if (!currentFlowEngine) {
677
+ console.warn('FlowEngine not available on this model for applyFlow. Check and model.flowEngine setup.');
678
+ return Promise.reject(new Error('FlowEngine not available for applyFlow. Please set flowEngine on the model.'));
679
+ }
680
+ const isFork = (this as any).isFork === true;
681
+ const target = this;
682
+ console.log(
683
+ `[FlowModel] applyFlow: uid=${this.uid}, flowKey=${flowKey}, isFork=${isFork}, cleanRun=${
684
+ this.cleanRun
685
+ }, targetIsFork=${(target as any)?.isFork === true}`,
686
+ );
687
+ return currentFlowEngine.executor.runFlow(target, flowKey, inputArgs, runId);
688
+ }
689
+
690
+ private async _dispatchEvent(
691
+ eventName: string,
692
+ inputArgs?: Record<string, any>,
693
+ options?: DispatchEventOptions,
694
+ ): Promise<any[]> {
695
+ const currentFlowEngine = this.flowEngine;
696
+ if (!currentFlowEngine) {
697
+ console.warn('FlowEngine not available on this model for dispatchEvent. Please set flowEngine on the model.');
698
+ return;
699
+ }
700
+ const isFork = (this as any).isFork === true;
701
+ const target = this;
702
+ console.log(
703
+ `[FlowModel] dispatchEvent: uid=${this.uid}, event=${eventName}, isFork=${isFork}, cleanRun=${
704
+ this.cleanRun
705
+ }, targetIsFork=${(target as any)?.isFork === true}`,
706
+ );
707
+ return await currentFlowEngine.executor.dispatchEvent(target, eventName, inputArgs, options);
708
+ }
709
+
710
+ private _dispatchEventWithDebounce = _.debounce(
711
+ async (eventName: string, inputArgs?: Record<string, any>, options?: DispatchEventOptions) => {
712
+ return this._dispatchEvent(eventName, inputArgs, options);
713
+ },
714
+ 100,
715
+ );
716
+
717
+ async dispatchEvent(
718
+ eventName: string,
719
+ inputArgs?: Record<string, any>,
720
+ options?: {
721
+ /** 是否要开启防抖功能 */
722
+ debounce?: boolean;
723
+ } & DispatchEventOptions,
724
+ ): Promise<any[]> {
725
+ const isBeforeRender = eventName === 'beforeRender';
726
+ // 缺省值由模型层提供:beforeRender 默认顺序执行 + 使用缓存;可被 options 覆盖
727
+ const defaults = isBeforeRender ? { sequential: true, useCache: true } : {};
728
+ const execOptions = {
729
+ sequential: options?.sequential ?? (defaults as any).sequential,
730
+ useCache: options?.useCache ?? (defaults as any).useCache,
731
+ } as DispatchEventOptions;
732
+
733
+ // 记录最近一次 beforeRender 的入参与选项,便于 stepParams 变化时触发重跑
734
+ if (isBeforeRender) {
735
+ this._lastAutoRunParams = [inputArgs, execOptions.useCache];
736
+ }
737
+
738
+ if (options?.debounce) {
739
+ return this._dispatchEventWithDebounce(eventName, inputArgs, execOptions);
740
+ }
741
+ return this._dispatchEvent(eventName, inputArgs, execOptions);
742
+ }
743
+
744
+ /**
745
+ * 按事件名获取对应的流程集合(保持 getFlows 的顺序,即按 sort 排序)。
746
+ * - beforeRender 兼容:除显式 on: 'beforeRender' 外,包含未声明 on 且 manual !== true 的流程。
747
+ */
748
+ public getEventFlows(eventName: string): FlowDefinition[] {
749
+ const allFlows = this.getFlows();
750
+ const beforeRender = eventName === 'beforeRender';
751
+ const isMatch = (flow: FlowDefinition) => {
752
+ if (beforeRender) {
753
+ if (flow.manual === true) return false;
754
+ if (!flow.on) return true;
755
+ return typeof flow.on === 'string' ? flow.on === 'beforeRender' : flow.on?.eventName === 'beforeRender';
756
+ }
757
+ const on = flow.on;
758
+ if (!on) return false;
759
+ return typeof on === 'string' ? on === eventName : on?.eventName === eventName;
760
+ };
761
+ return Array.from(allFlows.values()).filter(isMatch);
762
+ }
763
+
764
+ /**
765
+ * 重新执行上一次的 beforeRender,保持参数一致
766
+ * 如果之前没有执行过,则直接跳过
767
+ * 使用 lodash debounce 避免频繁调用
768
+ */
769
+ private _rerunLastAutoRun = _.debounce(async () => {
770
+ if (this._lastAutoRunParams) {
771
+ try {
772
+ const [inputArgs] = this._lastAutoRunParams as any[];
773
+ await this.dispatchEvent('beforeRender', inputArgs);
774
+ } catch (error) {
775
+ console.error('FlowModel._rerunLastAutoRun: Error during rerun:', error);
776
+ }
777
+ }
778
+ }, 100);
779
+
780
+ /**
781
+ * 通用事件分发钩子:开始
782
+ * 子类可覆盖;beforeRender 事件可通过抛出 FlowExitException 提前终止。
783
+ */
784
+ public async onDispatchEventStart(
785
+ eventName: string,
786
+ options?: DispatchEventOptions,
787
+ inputArgs?: Record<string, any>,
788
+ ): Promise<void> {}
789
+
790
+ /**
791
+ * 通用事件分发钩子:结束
792
+ * 子类可覆盖。
793
+ */
794
+ public async onDispatchEventEnd(
795
+ eventName: string,
796
+ options?: DispatchEventOptions,
797
+ inputArgs?: Record<string, any>,
798
+ results?: any[],
799
+ ): Promise<void> {}
800
+
801
+ /**
802
+ * 通用事件分发钩子:错误
803
+ * 子类可覆盖。
804
+ */
805
+ public async onDispatchEventError(
806
+ eventName: string,
807
+ options?: DispatchEventOptions,
808
+ inputArgs?: Record<string, any>,
809
+ error?: Error,
810
+ ): Promise<void> {}
811
+
812
+ useHooksBeforeRender() {}
813
+
814
+ /**
815
+ * 智能检测是否应该跳过响应式包装
816
+ * 说明:
817
+ * - 仅基于标记判断,不会执行 render,避免出现“预调用 render”带来的副作用和双调用问题。
818
+ * - 当子类需要返回函数(如表格列的单元格渲染器),应在子类上设置静态属性 `renderReturnsFunction = true`。
819
+ */
820
+ private shouldSkipReactiveWrapping(): boolean {
821
+ // 已经包裹过则跳过
822
+ if ((this.render as any).__isReactiveWrapped) {
823
+ return true;
824
+ }
825
+ // 子类显式声明渲染模式为 renderFunction,则跳过包裹
826
+ const Cls = this.constructor as typeof FlowModel;
827
+ if (Cls.renderMode === ModelRenderMode.RenderFunction) {
828
+ return true;
829
+ }
830
+ return false;
831
+ }
832
+
833
+ /**
834
+ * 设置 render 方法的响应式包装
835
+ * @private
836
+ */
837
+ private setupReactiveRender(): void {
838
+ // 确保 render 方法存在且是函数
839
+ if (typeof this.render !== 'function') {
840
+ return;
841
+ }
842
+
843
+ try {
844
+ // 保存原始 render 方法的引用
845
+ const originalRender = this.render;
846
+ this._originalRender = originalRender;
847
+
848
+ // 验证原始方法是函数
849
+ if (typeof originalRender !== 'function') {
850
+ console.error(`FlowModel ${this.constructor.name}: original render method is not a function`, originalRender);
851
+ return;
852
+ }
853
+
854
+ // 如果需要跳过响应式包装(例如返回渲染函数),也需要包一层以处理 hidden/config 逻辑
855
+ if (this.shouldSkipReactiveWrapping()) {
856
+ const wrappedNonReactive = function (this: any) {
857
+ const isConfigMode = !!this?.flowEngine?.flowSettings?.enabled;
858
+ if (this.hidden) {
859
+ if (!isConfigMode) return null;
860
+ const rendered = this.renderHiddenInConfig?.();
861
+ const Cls = this.constructor as typeof FlowModel;
862
+ const returnsFunction = Cls.renderMode === ModelRenderMode.RenderFunction;
863
+ return returnsFunction ? (typeof rendered === 'function' ? rendered : () => rendered) : rendered;
864
+ }
865
+ return originalRender.call(this);
866
+ };
867
+ (wrappedNonReactive as any).__originalRender = originalRender;
868
+ this.render = wrappedNonReactive;
869
+ return;
870
+ }
871
+
872
+ // 创建缓存的响应式包装器组件工厂(只创建一次)
873
+ const createReactiveWrapper = (modelInstance: any) => {
874
+ const ReactiveWrapper = observer(() => {
875
+ // 触发响应式更新的关键属性访问(读取 run/渲染目标的 props)
876
+ const renderTarget = modelInstance;
877
+ if (renderTarget !== modelInstance && (renderTarget as any)?.localProps !== undefined) {
878
+ // 订阅 fork 的本地 props 变更
879
+ (renderTarget as any).localProps;
880
+ // 同时订阅原实例(master/UI fork)的 props 变更,
881
+ // 以捕获诸如 FormItem→FieldModelRenderer 通过 model.setProps 写到 master.props 的更新
882
+ modelInstance.props;
883
+ } else {
884
+ // 订阅当前实例的 props 变更
885
+ modelInstance.props;
886
+ }
887
+
888
+ // 添加生命周期钩子:当渲染目标变化时,解绑旧目标并绑定新目标
889
+ React.useEffect(() => {
890
+ if (typeof renderTarget.onMount === 'function') {
891
+ renderTarget.onMount();
892
+ }
893
+ return () => {
894
+ if (typeof renderTarget.onUnmount === 'function') {
895
+ renderTarget.onUnmount();
896
+ }
897
+ };
898
+ }, [renderTarget]);
899
+
900
+ // 处理 hidden 渲染逻辑:
901
+ const isConfigMode = !!modelInstance?.flowEngine?.flowSettings?.enabled;
902
+ if (modelInstance.hidden) {
903
+ if (!isConfigMode) {
904
+ return null;
905
+ }
906
+ // 设置态隐藏时的渲染:由实例方法 renderHiddenInConfig 决定;若为渲染函数模式,则包装为函数
907
+ return modelInstance.renderHiddenInConfig?.();
908
+ }
909
+
910
+ // 订阅 stepParams 变化,以便当步骤参数(如 JS 代码等)更新时触发一次 React 渲染,
911
+ // 从而让 useHooksBeforeRender 中的副作用得以感知并执行(如 applyFlow('jsSettings'))。
912
+ modelInstance.stepParams;
913
+
914
+ // 调用原始渲染方法
915
+ return originalRender.call(renderTarget);
916
+ });
917
+
918
+ // 设置显示名称便于调试
919
+ ReactiveWrapper.displayName = `ReactiveWrapper(${modelInstance.constructor.name})`;
920
+
921
+ return ReactiveWrapper;
922
+ };
923
+
924
+ const wrappedRender = function (this: any) {
925
+ // 当前实例创建或获取缓存的 ReactiveWrapper
926
+ if (!this._reactiveWrapperCache) {
927
+ this._reactiveWrapperCache = createReactiveWrapper(this);
928
+ }
929
+
930
+ // 返回响应式组件
931
+ return React.createElement(this._reactiveWrapperCache);
932
+ };
933
+
934
+ // 标记已被包装
935
+ (wrappedRender as any).__isReactiveWrapped = true;
936
+ (wrappedRender as any).__originalRender = originalRender;
937
+
938
+ // 替换 render 方法
939
+ this.render = wrappedRender;
940
+ } catch (error) {
941
+ console.error(`FlowModel ${this.constructor.name}: Error during render method wrapping:`, error);
942
+ }
943
+ }
944
+
945
+ get cleanRun() {
946
+ return true; // 故意的设置 cleanRun 为true
947
+ // return !!this._cleanRun;
948
+ }
949
+
950
+ setCleanRun(value: boolean) {
951
+ const prev = this._cleanRun;
952
+ this._cleanRun = !!value;
953
+ }
954
+
955
+ /**
956
+ * 组件挂载时的生命周期钩子
957
+ * 子类可以重写此方法来添加挂载时的逻辑
958
+ * @protected
959
+ */
960
+ // eslint-disable-next-line no-empty
961
+ protected onMount(): void {
962
+ // 默认为空实现,子类可以重写
963
+ }
964
+
965
+ /**
966
+ * 组件卸载时的生命周期钩子
967
+ * 子类可以重写此方法来添加卸载时的逻辑
968
+ * @protected
969
+ */
970
+ protected onUnmount(): void {
971
+ // 默认为空实现,子类可以重写
972
+ }
973
+
974
+ /**
975
+ * 有权限时的渲染逻辑。
976
+ * 这是一个抽象方法,所有子类都必须实现,用于返回自己的正常 UI。
977
+ *
978
+ * @returns {React.ReactNode} 有权限时的渲染结果
979
+ */
980
+ public render(): any {
981
+ return <div {...this.props}></div>;
982
+ }
983
+
984
+ async rerender() {
985
+ await this.dispatchEvent('beforeRender', this._lastAutoRunParams?.[0], { useCache: false });
986
+ }
987
+
988
+ /**
989
+ * 事件缓存的作用域标识;可按事件区分(默认与事件无关的 scope 返回 'default')。
990
+ */
991
+ public getFlowCacheScope(eventName: string): string {
992
+ return String(eventName);
993
+ }
994
+
995
+ setParent(parent: FlowModel): void {
996
+ // forkflowModel instanceof FlowModel is false, but fork can be used as parent
997
+ const isValidParent =
998
+ parent && (parent.constructor === FlowModel || isInheritedFrom(parent.constructor as any, FlowModel));
999
+ if (!isValidParent) {
1000
+ throw new Error('Parent must be an instance of FlowModel.');
1001
+ }
1002
+ this.parent = parent as ParentFlowModel<Structure>;
1003
+ this._options.parentId = parent.uid;
1004
+ if (this._options.delegateToParent !== false) {
1005
+ this.context.addDelegate(this.parent.context);
1006
+ }
1007
+ }
1008
+
1009
+ removeParentDelegate() {
1010
+ if (!this.parent) {
1011
+ return;
1012
+ }
1013
+ this.context.removeDelegate(this.parent.context);
1014
+ }
1015
+
1016
+ addSubModel<T extends FlowModel>(subKey: string, options: CreateModelOptions | T) {
1017
+ const actualParent: FlowModel = (this['master'] as FlowModel) || this;
1018
+
1019
+ let model: T;
1020
+ if (options instanceof FlowModel) {
1021
+ // Compare by uid to tolerate fork wrappers and contextThis bindings
1022
+ const hasParent = !!options.parent;
1023
+ const parentUid = options.parent?.uid;
1024
+ if (hasParent && parentUid && parentUid !== actualParent.uid) {
1025
+ throw new Error('Sub model already has a parent.');
1026
+ }
1027
+ model = options;
1028
+ } else {
1029
+ model = actualParent.flowEngine.createModel<T>({
1030
+ ...options,
1031
+ parentId: actualParent.uid,
1032
+ subKey,
1033
+ subType: 'array',
1034
+ });
1035
+ }
1036
+ model.setParent(actualParent);
1037
+ const subModels = actualParent.subModels as {
1038
+ [subKey: string]: FlowModel[];
1039
+ };
1040
+ if (!Array.isArray(subModels[subKey])) {
1041
+ subModels[subKey] = observable.shallow([]);
1042
+ }
1043
+ const maxSortIndex = Math.max(...(subModels[subKey] as FlowModel[]).map((item) => item.sortIndex || 0), 0);
1044
+ model.sortIndex = maxSortIndex + 1;
1045
+ subModels[subKey].push(model);
1046
+ actualParent.emitter.emit('onSubModelAdded', model);
1047
+ return model;
1048
+ }
1049
+
1050
+ setSubModel(subKey: string, options: CreateModelOptions | FlowModel) {
1051
+ const actualParent: FlowModel = (this['master'] as FlowModel) || this;
1052
+
1053
+ let model: FlowModel;
1054
+ if (options instanceof FlowModel) {
1055
+ // Compare by uid to tolerate fork wrappers and contextThis bindings
1056
+ const hasParent = !!options.parent;
1057
+ const parentUid = options.parent?.uid;
1058
+ if (hasParent && parentUid && parentUid !== actualParent.uid) {
1059
+ throw new Error('Sub model already has a parent.');
1060
+ }
1061
+ model = options;
1062
+ } else {
1063
+ model = actualParent.flowEngine.createModel({
1064
+ ...options,
1065
+ parentId: actualParent.uid,
1066
+ subKey,
1067
+ subType: 'object',
1068
+ });
1069
+ }
1070
+ model.setParent(actualParent);
1071
+ (actualParent.subModels as any)[subKey] = model;
1072
+ actualParent.emitter.emit('onSubModelAdded', model);
1073
+ return model;
1074
+ }
1075
+
1076
+ filterSubModels<K extends keyof Structure['subModels'], R>(
1077
+ subKey: K,
1078
+ callback: (model: ArrayElementType<Structure['subModels'][K]>, index: number) => boolean,
1079
+ ): ArrayElementType<Structure['subModels'][K]>[] {
1080
+ const model = (this.subModels as any)[subKey as string];
1081
+
1082
+ if (!model) {
1083
+ return [];
1084
+ }
1085
+
1086
+ const results: ArrayElementType<Structure['subModels'][K]>[] = [];
1087
+
1088
+ _.castArray(model)
1089
+ .sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0))
1090
+ .forEach((item, index) => {
1091
+ const result = (callback as (model: any, index: number) => boolean)(item, index);
1092
+ if (result) {
1093
+ results.push(item);
1094
+ }
1095
+ });
1096
+
1097
+ return results;
1098
+ }
1099
+
1100
+ mapSubModels<K extends keyof Structure['subModels'], R>(
1101
+ subKey: K,
1102
+ callback: (model: ArrayElementType<Structure['subModels'][K]>, index: number) => R,
1103
+ ): R[] {
1104
+ const model = (this.subModels as any)[subKey as string];
1105
+
1106
+ if (!model) {
1107
+ return [];
1108
+ }
1109
+
1110
+ const results: R[] = [];
1111
+
1112
+ _.castArray(model)
1113
+ .sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0))
1114
+ .forEach((item, index) => {
1115
+ const result = (callback as (model: any, index: number) => R)(item, index);
1116
+ results.push(result);
1117
+ });
1118
+
1119
+ return results;
1120
+ }
1121
+
1122
+ hasSubModel<K extends keyof Structure['subModels']>(subKey: K) {
1123
+ const subModel = (this.subModels as any)[subKey as string];
1124
+ if (!subModel) {
1125
+ return false;
1126
+ }
1127
+ return _.castArray(subModel).length > 0;
1128
+ }
1129
+
1130
+ findSubModel<K extends keyof Structure['subModels'], R>(
1131
+ subKey: K,
1132
+ callback: (model: ArrayElementType<Structure['subModels'][K]>) => R,
1133
+ ): ArrayElementType<Structure['subModels'][K]> | null {
1134
+ const model = (this.subModels as any)[subKey as string];
1135
+
1136
+ if (!model) {
1137
+ return null;
1138
+ }
1139
+
1140
+ return (
1141
+ (_.castArray(model).find((item) => {
1142
+ return (callback as (model: any) => R)(item);
1143
+ }) as ArrayElementType<Structure['subModels'][K]> | undefined) || null
1144
+ );
1145
+ }
1146
+
1147
+ createRootModel(options) {
1148
+ return this.flowEngine.createModel(options);
1149
+ }
1150
+
1151
+ /**
1152
+ * 对指定子模型派发 beforeRender 事件(顺序执行并使用缓存)。
1153
+ */
1154
+ async applySubModelsBeforeRenderFlows<K extends keyof Structure['subModels']>(
1155
+ subKey: K,
1156
+ inputArgs?: Record<string, any>,
1157
+ shared?: Record<string, any>,
1158
+ ) {
1159
+ await Promise.all(
1160
+ this.mapSubModels(subKey, async (sub) => {
1161
+ await sub.dispatchEvent('beforeRender', inputArgs);
1162
+ }),
1163
+ );
1164
+ }
1165
+
1166
+ /**
1167
+ * 创建一个 fork 实例,实现"一份数据(master)多视图(fork)"的能力。
1168
+ * @param {IModelComponentProps} [localProps={}] fork 专属的局部 props,优先级高于 master.props
1169
+ * @param {string} [key] 可选的 key,用于复用 fork 实例。如果提供了 key,会尝试复用已存在的 fork
1170
+ * @returns {ForkFlowModel<this>} 创建的 fork 实例
1171
+ */
1172
+ createFork(
1173
+ localProps?: IModelComponentProps,
1174
+ key?: string,
1175
+ options?: { sharedProperties?: string[]; register?: boolean },
1176
+ ): ForkFlowModel<this> {
1177
+ // 如果提供了 key,尝试从缓存中获取
1178
+ if (key) {
1179
+ const cachedFork = this.forkCache.get(key);
1180
+ if (cachedFork && !(cachedFork as any).disposed) {
1181
+ // 更新 localProps
1182
+ cachedFork.setProps(localProps || {});
1183
+ return cachedFork as ForkFlowModel<this>;
1184
+ }
1185
+ }
1186
+
1187
+ // 创建新的 fork 实例
1188
+ const forkId = this.forks.size; // 当前集合大小作为索引
1189
+ const fork = new ForkFlowModel<this>(this as any, localProps, forkId);
1190
+ if (options?.register !== false) {
1191
+ this.forks.add(fork as any);
1192
+ }
1193
+
1194
+ // 如果提供了 key,将 fork 缓存起来
1195
+ if (key && options?.register !== false) {
1196
+ this.forkCache.set(key, fork as any);
1197
+ }
1198
+
1199
+ return fork as ForkFlowModel<this>;
1200
+ }
1201
+
1202
+ clearForks() {
1203
+ console.log(`FlowModel ${this.uid} clearing all forks.`);
1204
+ // 主动使所有 fork 失效
1205
+ if (this.forks?.size) {
1206
+ this.forks.forEach((fork) => fork.dispose());
1207
+ this.forks.clear();
1208
+ }
1209
+ // 清理 fork 缓存
1210
+ this.forkCache.clear();
1211
+ }
1212
+
1213
+ getFork(key: string) {
1214
+ return this.forkCache.get(key);
1215
+ }
1216
+
1217
+ /**
1218
+ * 移动当前模型到目标模型的位置
1219
+ * @param {FlowModel} targetModel 目标模型
1220
+ * @param {PersistOptions} [options] 可选的持久化选项
1221
+ * @returns {boolean} 是否成功移动
1222
+ */
1223
+ moveTo(targetModel: FlowModel, options?: PersistOptions) {
1224
+ if (!this.flowEngine) {
1225
+ throw new Error('FlowEngine is not set on this model. Please set flowEngine before saving.');
1226
+ }
1227
+ return this.flowEngine.moveModel(this.uid, targetModel.uid, options);
1228
+ }
1229
+
1230
+ remove() {
1231
+ if (!this.flowEngine) {
1232
+ throw new Error('FlowEngine is not set on this model. Please set flowEngine before saving.');
1233
+ }
1234
+ this.observerDispose();
1235
+ this.invalidateFlowCache('beforeRender', true);
1236
+ return this.flowEngine.removeModel(this.uid);
1237
+ }
1238
+
1239
+ async save() {
1240
+ if (!this.flowEngine) {
1241
+ throw new Error('FlowEngine is not set on this model. Please set flowEngine before saving.');
1242
+ }
1243
+ return this.flowEngine.saveModel(this);
1244
+ }
1245
+
1246
+ async saveStepParams() {
1247
+ return this.flowEngine.saveModel(this, { onlyStepParams: true });
1248
+ }
1249
+
1250
+ async destroy() {
1251
+ if (!this.flowEngine) {
1252
+ throw new Error('FlowEngine is not set on this model. Please set flowEngine before deleting.');
1253
+ }
1254
+ this.observerDispose();
1255
+ this.invalidateFlowCache('beforeRender', true);
1256
+ // 从 FlowEngine 中销毁模型
1257
+ return this.flowEngine.destroyModel(this.uid);
1258
+ }
1259
+
1260
+ /**
1261
+ * @deprecated
1262
+ * 打开步骤设置对话框
1263
+ * 用于配置流程中特定步骤的参数和设置
1264
+ * @param {string} flowKey 流程的唯一标识符
1265
+ * @param {string} stepKey 步骤的唯一标识符
1266
+ * @returns {void}
1267
+ */
1268
+ openStepSettingsDialog(flowKey: string, stepKey: string) {
1269
+ // 创建流程运行时上下文
1270
+ const flow = this.getFlow(flowKey);
1271
+ const step = flow?.steps?.[stepKey];
1272
+
1273
+ if (!flow || !step) {
1274
+ console.error(`Flow ${flowKey} or step ${stepKey} not found`);
1275
+ return;
1276
+ }
1277
+
1278
+ const ctx = new FlowRuntimeContext(this, flowKey, 'settings');
1279
+ setupRuntimeContextSteps(ctx, flow.steps, this, flowKey);
1280
+ ctx.defineProperty('currentStep', { value: step });
1281
+
1282
+ return openStepSettingsDialogFn({
1283
+ model: this,
1284
+ flowKey,
1285
+ stepKey,
1286
+ ctx,
1287
+ });
1288
+ }
1289
+
1290
+ /**
1291
+ * 配置必填步骤参数
1292
+ * 用于在一个分步表单中配置所有需要参数的步骤
1293
+ * @param {number | string} [dialogWidth=800] 对话框宽度,默认为800
1294
+ * @param {string} [dialogTitle='步骤参数配置'] 对话框标题,默认为'步骤参数配置'
1295
+ * @returns {Promise<any>} 返回表单提交的值
1296
+ */
1297
+ async configureRequiredSteps(dialogWidth?: number | string, dialogTitle?: string) {
1298
+ return openRequiredParamsStepFormDialogFn({
1299
+ model: this,
1300
+ dialogWidth,
1301
+ dialogTitle,
1302
+ });
1303
+ }
1304
+
1305
+ /**
1306
+ * @deprecated
1307
+ * @param dialogWidth
1308
+ * @param dialogTitle
1309
+ * @returns
1310
+ */
1311
+ async openPresetStepSettingsDialog(dialogWidth?: number | string, dialogTitle?: string) {
1312
+ return this.configureRequiredSteps(dialogWidth, dialogTitle);
1313
+ }
1314
+
1315
+ async openFlowStepSettingsDialog(options: {
1316
+ flowKey?: string;
1317
+ stepKey?: string;
1318
+ preset?: boolean;
1319
+ uiMode?: 'drawer' | 'dialog';
1320
+ }) {}
1321
+
1322
+ get translate() {
1323
+ return this.flowEngine.translate.bind(this.flowEngine);
1324
+ }
1325
+
1326
+ // TODO: 不完整,需要考虑 sub-model 的情况
1327
+ serialize(): Record<string, any> {
1328
+ const data = {
1329
+ uid: this.uid,
1330
+ ..._.omit(this._options, ['flowEngine']),
1331
+ stepParams: this.stepParams,
1332
+ sortIndex: this.sortIndex,
1333
+ };
1334
+ const subModels = this.subModels as {
1335
+ [key: string]: FlowModel | FlowModel[];
1336
+ };
1337
+ for (const subModelKey in subModels) {
1338
+ data.subModels = data.subModels || {};
1339
+ if (Array.isArray(subModels[subModelKey])) {
1340
+ (data.subModels as any)[subModelKey] = (subModels[subModelKey] as FlowModel[]).map((model, index) => ({
1341
+ ...model.serialize(),
1342
+ sortIndex: index,
1343
+ }));
1344
+ } else if (subModels[subModelKey] instanceof FlowModel) {
1345
+ (data.subModels as any)[subModelKey] = (subModels[subModelKey] as FlowModel).serialize();
1346
+ }
1347
+ }
1348
+ for (const [key, flow] of this.flowRegistry.getFlows()) {
1349
+ data['flowRegistry'] = data['flowRegistry'] || {};
1350
+ data['flowRegistry'][key] = flow.toData();
1351
+ }
1352
+ return data;
1353
+ }
1354
+
1355
+ /**
1356
+ * Opens the flow settings dialog for this flow model.
1357
+ * @param options - Configuration options for opening flow settings, excluding the model property
1358
+ * @returns A promise that resolves when the flow settings dialog is opened
1359
+ */
1360
+ async openFlowSettings(options?: Omit<FlowSettingsOpenOptions, 'model'>) {
1361
+ return this.flowEngine.flowSettings.open({
1362
+ model: this,
1363
+ ...options,
1364
+ });
1365
+ }
1366
+
1367
+ // =============================
1368
+ // Dynamic flows (disabled)
1369
+ // The following APIs are kept as comments to preserve context
1370
+ // =============================
1371
+ /*
1372
+ async openDynamicFlowsEditor(
1373
+ options?: Omit<FlowSettingsOpenOptions, 'model' | 'flowKey' | 'flowKeys' | 'stepKey' | 'preset'>,
1374
+ ) {
1375
+ return this.flowEngine.flowSettings.openDynamicFlowsEditor({
1376
+ model: this,
1377
+ ...options,
1378
+ });
1379
+ }
1380
+
1381
+ #dynamicFlows: FlowDefinition[] = [];
1382
+
1383
+ async loadDynamicFlows(): Promise<FlowDefinition[]> {
1384
+ return JSON.parse(localStorage.getItem('DYNAMIC_FLOWS') || '[]');
1385
+ }
1386
+
1387
+ async saveDynamicFlows(): Promise<void> {
1388
+ localStorage.setItem('DYNAMIC_FLOWS', JSON.stringify(this.#dynamicFlows));
1389
+ }
1390
+
1391
+ setDynamicFlows(flows: FlowDefinition[]): void {
1392
+ this.#dynamicFlows = flows;
1393
+ flows.forEach((flow) => {
1394
+ // @ts-ignore
1395
+ this.constructor.registerFlow(flow);
1396
+ });
1397
+ }
1398
+
1399
+ getDynamicFlows(): FlowDefinitionOptions[] {
1400
+ return this.#dynamicFlows;
1401
+ }
1402
+ */
1403
+ }
1404
+
1405
+ export class ErrorFlowModel extends FlowModel {
1406
+ public errorMessage: string;
1407
+
1408
+ setErrorMessage(msg: string) {
1409
+ this.errorMessage = msg;
1410
+ }
1411
+
1412
+ public render() {
1413
+ return <Typography.Text type="danger">{this.errorMessage}</Typography.Text>;
1414
+ }
1415
+ }
1416
+
1417
+ export function defineFlow<TModel extends FlowModel = FlowModel>(
1418
+ definition: FlowDefinitionOptions,
1419
+ ): FlowDefinitionOptions<TModel> {
1420
+ return definition as FlowDefinitionOptions<TModel>;
1421
+ }