@nocobase/flow-engine 2.0.0-alpha.2

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 (597) 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 +94 -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 +64 -0
  34. package/lib/components/FlowModelRenderer.js +254 -0
  35. package/lib/components/FormItem.d.ts +18 -0
  36. package/lib/components/FormItem.js +147 -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/getMousePositionOnElement.d.ts +50 -0
  44. package/lib/components/dnd/getMousePositionOnElement.js +95 -0
  45. package/lib/components/dnd/index.d.ts +24 -0
  46. package/lib/components/dnd/index.js +164 -0
  47. package/lib/components/dnd/moveBlock.d.ts +33 -0
  48. package/lib/components/dnd/moveBlock.js +302 -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 +206 -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 +322 -0
  99. package/lib/components/variables/VariableTag.d.ts +11 -0
  100. package/lib/components/variables/VariableTag.js +148 -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 +733 -0
  113. package/lib/data-source/jioToJoiSchema.d.ts +19 -0
  114. package/lib/data-source/jioToJoiSchema.js +114 -0
  115. package/lib/decorators/index.d.ts +9 -0
  116. package/lib/decorators/index.js +36 -0
  117. package/lib/decorators/largeField.d.ts +9 -0
  118. package/lib/decorators/largeField.js +42 -0
  119. package/lib/emitter.d.ts +16 -0
  120. package/lib/emitter.js +58 -0
  121. package/lib/event-registry/BaseEventRegistry.d.ts +22 -0
  122. package/lib/event-registry/BaseEventRegistry.js +57 -0
  123. package/lib/event-registry/EngineEventRegistry.d.ts +19 -0
  124. package/lib/event-registry/EngineEventRegistry.js +47 -0
  125. package/lib/event-registry/ModelEventRegistry.d.ts +33 -0
  126. package/lib/event-registry/ModelEventRegistry.js +79 -0
  127. package/lib/executor/FlowExecutor.d.ts +26 -0
  128. package/lib/executor/FlowExecutor.js +262 -0
  129. package/lib/flow-registry/BaseFlowRegistry.d.ts +46 -0
  130. package/lib/flow-registry/BaseFlowRegistry.js +86 -0
  131. package/lib/flow-registry/GlobalFlowRegistry.d.ts +22 -0
  132. package/lib/flow-registry/GlobalFlowRegistry.js +95 -0
  133. package/lib/flow-registry/InstanceFlowRegistry.d.ts +21 -0
  134. package/lib/flow-registry/InstanceFlowRegistry.js +59 -0
  135. package/lib/flow-registry/index.d.ts +11 -0
  136. package/lib/flow-registry/index.js +34 -0
  137. package/lib/flowContext.d.ts +215 -0
  138. package/lib/flowContext.js +1266 -0
  139. package/lib/flowEngine.d.ts +340 -0
  140. package/lib/flowEngine.js +781 -0
  141. package/lib/flowI18n.d.ts +46 -0
  142. package/lib/flowI18n.js +117 -0
  143. package/lib/flowSettings.d.ts +266 -0
  144. package/lib/flowSettings.js +850 -0
  145. package/lib/hooks/index.d.ts +14 -0
  146. package/lib/hooks/index.js +40 -0
  147. package/lib/hooks/useApplyAutoFlows.d.ts +21 -0
  148. package/lib/hooks/useApplyAutoFlows.js +62 -0
  149. package/lib/hooks/useFlowModel.d.ts +29 -0
  150. package/lib/hooks/useFlowModel.js +72 -0
  151. package/lib/hooks/useFlowModelById.d.ts +11 -0
  152. package/lib/hooks/useFlowModelById.js +61 -0
  153. package/lib/hooks/useFlowSettingsContext.d.ts +20 -0
  154. package/lib/hooks/useFlowSettingsContext.js +61 -0
  155. package/lib/hooks/useFlowStep.d.ts +17 -0
  156. package/lib/hooks/useFlowStep.js +56 -0
  157. package/lib/hooks/useNiceDropdownMaxHeight.d.ts +13 -0
  158. package/lib/hooks/useNiceDropdownMaxHeight.js +52 -0
  159. package/lib/index.d.ts +27 -0
  160. package/lib/index.js +73 -0
  161. package/lib/locale/en-US.json +61 -0
  162. package/lib/locale/index.d.ts +141 -0
  163. package/lib/locale/index.js +70 -0
  164. package/lib/locale/zh-CN.json +61 -0
  165. package/lib/models/CollectionFieldModel.d.ts +50 -0
  166. package/lib/models/CollectionFieldModel.js +242 -0
  167. package/lib/models/DisplayItemModel.d.ts +12 -0
  168. package/lib/models/DisplayItemModel.js +41 -0
  169. package/lib/models/EditableItemModel.d.ts +12 -0
  170. package/lib/models/EditableItemModel.js +41 -0
  171. package/lib/models/FilterableItemModel.d.ts +12 -0
  172. package/lib/models/FilterableItemModel.js +41 -0
  173. package/lib/models/flowModel.d.ts +344 -0
  174. package/lib/models/flowModel.js +1133 -0
  175. package/lib/models/forkFlowModel.d.ts +83 -0
  176. package/lib/models/forkFlowModel.js +257 -0
  177. package/lib/models/index.d.ts +14 -0
  178. package/lib/models/index.js +40 -0
  179. package/lib/provider.d.ts +22 -0
  180. package/lib/provider.js +114 -0
  181. package/lib/resources/apiResource.d.ts +34 -0
  182. package/lib/resources/apiResource.js +153 -0
  183. package/lib/resources/baseRecordResource.d.ts +61 -0
  184. package/lib/resources/baseRecordResource.js +264 -0
  185. package/lib/resources/filterItem.d.ts +33 -0
  186. package/lib/resources/filterItem.js +93 -0
  187. package/lib/resources/flowResource.d.ts +45 -0
  188. package/lib/resources/flowResource.js +146 -0
  189. package/lib/resources/index.d.ts +15 -0
  190. package/lib/resources/index.js +42 -0
  191. package/lib/resources/multiRecordResource.d.ts +53 -0
  192. package/lib/resources/multiRecordResource.js +230 -0
  193. package/lib/resources/singleRecordResource.d.ts +23 -0
  194. package/lib/resources/singleRecordResource.js +111 -0
  195. package/lib/resources/sqlResource.d.ts +73 -0
  196. package/lib/resources/sqlResource.js +294 -0
  197. package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +38 -0
  198. package/lib/runjs-context/contexts/FlowRunJSContext.js +217 -0
  199. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +16 -0
  200. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +66 -0
  201. package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +16 -0
  202. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +78 -0
  203. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +12 -0
  204. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +59 -0
  205. package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +16 -0
  206. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +70 -0
  207. package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +16 -0
  208. package/lib/runjs-context/contexts/JSItemRunJSContext.js +66 -0
  209. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +12 -0
  210. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +61 -0
  211. package/lib/runjs-context/contexts/LinkageRunJSContext.d.ts +12 -0
  212. package/lib/runjs-context/contexts/LinkageRunJSContext.js +62 -0
  213. package/lib/runjs-context/helpers.d.ts +17 -0
  214. package/lib/runjs-context/helpers.js +79 -0
  215. package/lib/runjs-context/index.d.ts +19 -0
  216. package/lib/runjs-context/index.js +57 -0
  217. package/lib/runjs-context/registry.d.ts +17 -0
  218. package/lib/runjs-context/registry.js +93 -0
  219. package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +16 -0
  220. package/lib/runjs-context/snippets/global/api-request-get.snippet.js +42 -0
  221. package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +16 -0
  222. package/lib/runjs-context/snippets/global/api-request-post.snippet.js +42 -0
  223. package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +16 -0
  224. package/lib/runjs-context/snippets/global/console-log-ctx.snippet.js +41 -0
  225. package/lib/runjs-context/snippets/global/copy-record-json.snippet.d.ts +11 -0
  226. package/lib/runjs-context/snippets/global/copy-record-json.snippet.js +42 -0
  227. package/lib/runjs-context/snippets/global/copy-to-clipboard.snippet.d.ts +11 -0
  228. package/lib/runjs-context/snippets/global/copy-to-clipboard.snippet.js +42 -0
  229. package/lib/runjs-context/snippets/global/log-json-record.snippet.d.ts +11 -0
  230. package/lib/runjs-context/snippets/global/log-json-record.snippet.js +42 -0
  231. package/lib/runjs-context/snippets/global/message-error.snippet.d.ts +11 -0
  232. package/lib/runjs-context/snippets/global/message-error.snippet.js +41 -0
  233. package/lib/runjs-context/snippets/global/message-success.snippet.d.ts +11 -0
  234. package/lib/runjs-context/snippets/global/message-success.snippet.js +41 -0
  235. package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +16 -0
  236. package/lib/runjs-context/snippets/global/notification-open.snippet.js +43 -0
  237. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.d.ts +11 -0
  238. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +47 -0
  239. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.d.ts +11 -0
  240. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +47 -0
  241. package/lib/runjs-context/snippets/global/requireAsync.snippet.d.ts +16 -0
  242. package/lib/runjs-context/snippets/global/requireAsync.snippet.js +46 -0
  243. package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +16 -0
  244. package/lib/runjs-context/snippets/global/sleep.snippet.js +43 -0
  245. package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +16 -0
  246. package/lib/runjs-context/snippets/global/try-catch-async.snippet.js +44 -0
  247. package/lib/runjs-context/snippets/global/view-navigation-push.snippet.d.ts +11 -0
  248. package/lib/runjs-context/snippets/global/view-navigation-push.snippet.js +44 -0
  249. package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +16 -0
  250. package/lib/runjs-context/snippets/global/window-open.snippet.js +41 -0
  251. package/lib/runjs-context/snippets/index.d.ts +11 -0
  252. package/lib/runjs-context/snippets/index.js +94 -0
  253. package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +15 -0
  254. package/lib/runjs-context/snippets/libs/echarts-init.snippet.js +46 -0
  255. package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +15 -0
  256. package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.js +44 -0
  257. package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +15 -0
  258. package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.js +43 -0
  259. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +15 -0
  260. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +43 -0
  261. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +15 -0
  262. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +40 -0
  263. package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +15 -0
  264. package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.js +46 -0
  265. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +15 -0
  266. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +42 -0
  267. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +15 -0
  268. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js +46 -0
  269. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +15 -0
  270. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +41 -0
  271. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +15 -0
  272. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +41 -0
  273. package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +15 -0
  274. package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.js +46 -0
  275. package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.d.ts +11 -0
  276. package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.js +45 -0
  277. package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +15 -0
  278. package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.js +56 -0
  279. package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +15 -0
  280. package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.js +42 -0
  281. package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +15 -0
  282. package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.js +41 -0
  283. package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +15 -0
  284. package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.js +40 -0
  285. package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +15 -0
  286. package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.js +44 -0
  287. package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +15 -0
  288. package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.js +60 -0
  289. package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +15 -0
  290. package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.js +59 -0
  291. package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +15 -0
  292. package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.js +60 -0
  293. package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +15 -0
  294. package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.js +60 -0
  295. package/lib/runjs-context/snippets/types.d.ts +16 -0
  296. package/lib/runjs-context/snippets/types.js +24 -0
  297. package/lib/types.d.ts +398 -0
  298. package/lib/types.js +43 -0
  299. package/lib/utils/autoFlowError.d.ts +16 -0
  300. package/lib/utils/autoFlowError.js +53 -0
  301. package/lib/utils/constants.d.ts +29 -0
  302. package/lib/utils/constants.js +77 -0
  303. package/lib/utils/context.d.ts +40 -0
  304. package/lib/utils/context.js +63 -0
  305. package/lib/utils/createCollectionContextMeta.d.ts +11 -0
  306. package/lib/utils/createCollectionContextMeta.js +117 -0
  307. package/lib/utils/exceptions.d.ts +22 -0
  308. package/lib/utils/exceptions.js +62 -0
  309. package/lib/utils/flow-definitions.d.ts +11 -0
  310. package/lib/utils/flow-definitions.js +40 -0
  311. package/lib/utils/index.d.ts +22 -0
  312. package/lib/utils/index.js +117 -0
  313. package/lib/utils/inheritance.d.ts +16 -0
  314. package/lib/utils/inheritance.js +53 -0
  315. package/lib/utils/params-resolvers.d.ts +51 -0
  316. package/lib/utils/params-resolvers.js +309 -0
  317. package/lib/utils/parsePathnameToViewParams.d.ts +34 -0
  318. package/lib/utils/parsePathnameToViewParams.js +84 -0
  319. package/lib/utils/safeGlobals.d.ts +16 -0
  320. package/lib/utils/safeGlobals.js +179 -0
  321. package/lib/utils/schema-utils.d.ts +40 -0
  322. package/lib/utils/schema-utils.js +161 -0
  323. package/lib/utils/serverContextParams.d.ts +28 -0
  324. package/lib/utils/serverContextParams.js +106 -0
  325. package/lib/utils/setupRuntimeContextSteps.d.ts +19 -0
  326. package/lib/utils/setupRuntimeContextSteps.js +88 -0
  327. package/lib/utils/translation.d.ts +18 -0
  328. package/lib/utils/translation.js +58 -0
  329. package/lib/utils/variablesParams.d.ts +51 -0
  330. package/lib/utils/variablesParams.js +150 -0
  331. package/lib/views/DialogComponent.d.ts +22 -0
  332. package/lib/views/DialogComponent.js +98 -0
  333. package/lib/views/DrawerComponent.d.ts +11 -0
  334. package/lib/views/DrawerComponent.js +101 -0
  335. package/lib/views/FlowView.d.ts +76 -0
  336. package/lib/views/FlowView.js +81 -0
  337. package/lib/views/PageComponent.d.ts +10 -0
  338. package/lib/views/PageComponent.js +167 -0
  339. package/lib/views/ViewNavigation.d.ts +45 -0
  340. package/lib/views/ViewNavigation.js +97 -0
  341. package/lib/views/createViewMeta.d.ts +16 -0
  342. package/lib/views/createViewMeta.js +171 -0
  343. package/lib/views/index.d.ts +13 -0
  344. package/lib/views/index.js +48 -0
  345. package/lib/views/useDialog.d.ts +32 -0
  346. package/lib/views/useDialog.js +199 -0
  347. package/lib/views/useDrawer.d.ts +33 -0
  348. package/lib/views/useDrawer.js +206 -0
  349. package/lib/views/usePage.d.ts +32 -0
  350. package/lib/views/usePage.js +193 -0
  351. package/lib/views/usePatchElement.d.ts +10 -0
  352. package/lib/views/usePatchElement.js +54 -0
  353. package/lib/views/usePopover.d.ts +17 -0
  354. package/lib/views/usePopover.js +159 -0
  355. package/package.json +37 -0
  356. package/src/ContextPathProxy.ts +45 -0
  357. package/src/ElementProxy.ts +69 -0
  358. package/src/FlowContextProvider.tsx +40 -0
  359. package/src/FlowDefinition.ts +275 -0
  360. package/src/JSRunner.ts +84 -0
  361. package/src/ReactView.tsx +104 -0
  362. package/src/ViewScopedFlowEngine.ts +75 -0
  363. package/src/__tests__/ElementProxy.test.ts +51 -0
  364. package/src/__tests__/JSRunner.test.ts +92 -0
  365. package/src/__tests__/ReactView.test.tsx +63 -0
  366. package/src/__tests__/context-path-proxy.test.ts +35 -0
  367. package/src/__tests__/flow-engine.test.ts +189 -0
  368. package/src/__tests__/flowContext.test.ts +2012 -0
  369. package/src/__tests__/flowEngine.saveModel.test.ts +171 -0
  370. package/src/__tests__/flowI18n.test.ts +28 -0
  371. package/src/__tests__/flowModel.getFlows.test.ts +61 -0
  372. package/src/__tests__/flowModel.openView.navigation.test.ts +78 -0
  373. package/src/__tests__/flowRuntimeContext.test.ts +187 -0
  374. package/src/__tests__/flowSettings.open.test.tsx +1920 -0
  375. package/src/__tests__/flowSettings.test.ts +566 -0
  376. package/src/__tests__/globalFlowRegistry.test.ts +77 -0
  377. package/src/__tests__/isFieldInterfaceMatch.test.ts +51 -0
  378. package/src/__tests__/metaTreeNodeCache.test.ts +234 -0
  379. package/src/__tests__/path-aggregation.test.ts +85 -0
  380. package/src/__tests__/provider.test.tsx +28 -0
  381. package/src/__tests__/renderHiddenInConfig.test.tsx +91 -0
  382. package/src/__tests__/runjsContext.test.ts +60 -0
  383. package/src/__tests__/viewScopedFlowEngine.test.ts +212 -0
  384. package/src/acl/Acl.tsx +109 -0
  385. package/src/acl/__tests__/Acl.test.tsx +72 -0
  386. package/src/action-registry/BaseActionRegistry.ts +46 -0
  387. package/src/action-registry/EngineActionRegistry.ts +32 -0
  388. package/src/action-registry/ModelActionRegistry.ts +75 -0
  389. package/src/action-registry/__tests__/engineActionRegistry.test.ts +43 -0
  390. package/src/action-registry/__tests__/modelActionRegistry.test.ts +107 -0
  391. package/src/components/DynamicFlowsEditor.tsx +318 -0
  392. package/src/components/FieldModelRenderer.tsx +62 -0
  393. package/src/components/FlowContextSelector.tsx +255 -0
  394. package/src/components/FlowErrorFallback.tsx +316 -0
  395. package/src/components/FlowModelRenderer.tsx +428 -0
  396. package/src/components/FormItem.tsx +130 -0
  397. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +226 -0
  398. package/src/components/common/FlowSettingsButton.tsx +30 -0
  399. package/src/components/common/index.ts +10 -0
  400. package/src/components/common/withFlowDesignMode.tsx +49 -0
  401. package/src/components/dnd/getMousePositionOnElement.ts +115 -0
  402. package/src/components/dnd/index.tsx +128 -0
  403. package/src/components/dnd/moveBlock.ts +379 -0
  404. package/src/components/index.ts +20 -0
  405. package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +279 -0
  406. package/src/components/settings/independents/dropdown/index.ts +10 -0
  407. package/src/components/settings/independents/index.ts +2 -0
  408. package/src/components/settings/index.ts +11 -0
  409. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +617 -0
  410. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +292 -0
  411. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +655 -0
  412. package/src/components/settings/wrappers/contextual/StepRequiredSettingsDialog.tsx +446 -0
  413. package/src/components/settings/wrappers/contextual/StepSettings.tsx +109 -0
  414. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +217 -0
  415. package/src/components/settings/wrappers/contextual/StepSettingsDrawer.tsx +32 -0
  416. package/src/components/settings/wrappers/contextual/index.ts +15 -0
  417. package/src/components/settings/wrappers/embedded/FlowSettings.tsx +258 -0
  418. package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +111 -0
  419. package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +96 -0
  420. package/src/components/settings/wrappers/embedded/index.ts +11 -0
  421. package/src/components/settings/wrappers/index.ts +5 -0
  422. package/src/components/subModel/AddSubModelButton.tsx +575 -0
  423. package/src/components/subModel/LazyDropdown.tsx +714 -0
  424. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +1185 -0
  425. package/src/components/subModel/__tests__/buildWrapperFieldChildren.test.ts +192 -0
  426. package/src/components/subModel/__tests__/utils.test.ts +425 -0
  427. package/src/components/subModel/index.ts +12 -0
  428. package/src/components/subModel/utils.ts +278 -0
  429. package/src/components/variables/InlineVariableTag.tsx +97 -0
  430. package/src/components/variables/SlateVariableEditor.tsx +384 -0
  431. package/src/components/variables/VariableInput.tsx +342 -0
  432. package/src/components/variables/VariableTag.tsx +123 -0
  433. package/src/components/variables/VariableTrigger.tsx +116 -0
  434. package/src/components/variables/__tests__/FlowContextSelector.test.tsx +553 -0
  435. package/src/components/variables/__tests__/VariableInput.test.tsx +550 -0
  436. package/src/components/variables/__tests__/VariableTag.test.tsx +347 -0
  437. package/src/components/variables/__tests__/test-utils.tsx +62 -0
  438. package/src/components/variables/__tests__/utils.test.ts +310 -0
  439. package/src/components/variables/index.ts +16 -0
  440. package/src/components/variables/types.ts +100 -0
  441. package/src/components/variables/useResolvedMetaTree.ts +76 -0
  442. package/src/components/variables/utils.ts +192 -0
  443. package/src/data-source/__tests__/collection.test.ts +58 -0
  444. package/src/data-source/__tests__/index.test.ts +82 -0
  445. package/src/data-source/__tests__/jioToJoiSchema.test.ts +56 -0
  446. package/src/data-source/index.ts +812 -0
  447. package/src/data-source/jioToJoiSchema.ts +103 -0
  448. package/src/decorators/index.ts +10 -0
  449. package/src/decorators/largeField.ts +14 -0
  450. package/src/emitter.ts +33 -0
  451. package/src/event-registry/BaseEventRegistry.ts +40 -0
  452. package/src/event-registry/EngineEventRegistry.ts +26 -0
  453. package/src/event-registry/ModelEventRegistry.ts +69 -0
  454. package/src/event-registry/__tests__/engineEventRegistry.test.ts +48 -0
  455. package/src/executor/FlowExecutor.ts +256 -0
  456. package/src/executor/__tests__/eventStep.test.ts +157 -0
  457. package/src/executor/__tests__/flowExecutor.test.ts +163 -0
  458. package/src/flow-registry/BaseFlowRegistry.ts +91 -0
  459. package/src/flow-registry/GlobalFlowRegistry.ts +82 -0
  460. package/src/flow-registry/InstanceFlowRegistry.ts +39 -0
  461. package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +141 -0
  462. package/src/flow-registry/__tests__/instance-and-global-registry.test.ts +67 -0
  463. package/src/flow-registry/__tests__/instanceFlowRegistry.test.ts +83 -0
  464. package/src/flow-registry/index.ts +12 -0
  465. package/src/flowContext.ts +1639 -0
  466. package/src/flowEngine.ts +905 -0
  467. package/src/flowI18n.ts +96 -0
  468. package/src/flowSettings.ts +1045 -0
  469. package/src/hooks/index.ts +15 -0
  470. package/src/hooks/useApplyAutoFlows.ts +51 -0
  471. package/src/hooks/useFlowModel.tsx +59 -0
  472. package/src/hooks/useFlowModelById.ts +37 -0
  473. package/src/hooks/useFlowSettingsContext.tsx +37 -0
  474. package/src/hooks/useFlowStep.tsx +19 -0
  475. package/src/hooks/useNiceDropdownMaxHeight.ts +34 -0
  476. package/src/index.ts +38 -0
  477. package/src/locale/en-US.json +61 -0
  478. package/src/locale/index.ts +38 -0
  479. package/src/locale/zh-CN.json +61 -0
  480. package/src/models/CollectionFieldModel.tsx +269 -0
  481. package/src/models/DisplayItemModel.tsx +13 -0
  482. package/src/models/EditableItemModel.tsx +13 -0
  483. package/src/models/FilterableItemModel.tsx +13 -0
  484. package/src/models/__tests__/CollectionFieldModel.test.ts +122 -0
  485. package/src/models/__tests__/defaultParams-on-create.test.ts +83 -0
  486. package/src/models/__tests__/flow-model-oninit.test.ts +44 -0
  487. package/src/models/__tests__/flowModel.actions.integration.test.ts +100 -0
  488. package/src/models/__tests__/flowModel.getFlows.sort.test.ts +100 -0
  489. package/src/models/__tests__/flowModel.test.ts +2746 -0
  490. package/src/models/__tests__/flowRegistry.test.ts +512 -0
  491. package/src/models/__tests__/forkFlowModel.test.ts +1047 -0
  492. package/src/models/__tests__/model-actions.test.ts +70 -0
  493. package/src/models/__tests__/model-events.test.ts +69 -0
  494. package/src/models/flowModel.tsx +1398 -0
  495. package/src/models/forkFlowModel.ts +287 -0
  496. package/src/models/index.ts +17 -0
  497. package/src/provider.tsx +101 -0
  498. package/src/resources/__tests__/apiResource.test.ts +201 -0
  499. package/src/resources/__tests__/baseRecordResource.test.ts +262 -0
  500. package/src/resources/__tests__/filterItem.test.ts +260 -0
  501. package/src/resources/__tests__/flowResource.test.ts +127 -0
  502. package/src/resources/apiResource.ts +148 -0
  503. package/src/resources/baseRecordResource.ts +279 -0
  504. package/src/resources/filterItem.ts +74 -0
  505. package/src/resources/flowResource.ts +143 -0
  506. package/src/resources/index.ts +17 -0
  507. package/src/resources/multiRecordResource.ts +219 -0
  508. package/src/resources/singleRecordResource.ts +83 -0
  509. package/src/resources/sqlResource.ts +299 -0
  510. package/src/runjs-context/contexts/FlowRunJSContext.ts +190 -0
  511. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +39 -0
  512. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +52 -0
  513. package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +32 -0
  514. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +43 -0
  515. package/src/runjs-context/contexts/JSItemRunJSContext.ts +39 -0
  516. package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +34 -0
  517. package/src/runjs-context/contexts/LinkageRunJSContext.ts +35 -0
  518. package/src/runjs-context/helpers.ts +56 -0
  519. package/src/runjs-context/index.ts +20 -0
  520. package/src/runjs-context/registry.ts +65 -0
  521. package/src/runjs-context/snippets/global/api-request-get.snippet.ts +20 -0
  522. package/src/runjs-context/snippets/global/api-request-post.snippet.ts +20 -0
  523. package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +19 -0
  524. package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +21 -0
  525. package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +21 -0
  526. package/src/runjs-context/snippets/global/log-json-record.snippet.ts +21 -0
  527. package/src/runjs-context/snippets/global/message-error.snippet.ts +20 -0
  528. package/src/runjs-context/snippets/global/message-success.snippet.ts +20 -0
  529. package/src/runjs-context/snippets/global/notification-open.snippet.ts +21 -0
  530. package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +26 -0
  531. package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +26 -0
  532. package/src/runjs-context/snippets/global/requireAsync.snippet.ts +24 -0
  533. package/src/runjs-context/snippets/global/sleep.snippet.ts +21 -0
  534. package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +22 -0
  535. package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +23 -0
  536. package/src/runjs-context/snippets/global/window-open.snippet.ts +19 -0
  537. package/src/runjs-context/snippets/index.ts +59 -0
  538. package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +24 -0
  539. package/src/runjs-context/snippets/scene/actions/collection-selected-count.snippet.ts +22 -0
  540. package/src/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.ts +21 -0
  541. package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +21 -0
  542. package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +18 -0
  543. package/src/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.ts +29 -0
  544. package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +20 -0
  545. package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +24 -0
  546. package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +19 -0
  547. package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +24 -0
  548. package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +24 -0
  549. package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +30 -0
  550. package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +34 -0
  551. package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +20 -0
  552. package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +19 -0
  553. package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +18 -0
  554. package/src/runjs-context/snippets/scene/jsitem/render-basic.snippet.ts +27 -0
  555. package/src/runjs-context/snippets/scene/linkage/set-disabled.snippet.ts +38 -0
  556. package/src/runjs-context/snippets/scene/linkage/set-field-value.snippet.ts +37 -0
  557. package/src/runjs-context/snippets/scene/linkage/set-required.snippet.ts +38 -0
  558. package/src/runjs-context/snippets/scene/linkage/toggle-visible.snippet.ts +38 -0
  559. package/src/runjs-context/snippets/types.ts +17 -0
  560. package/src/types.ts +474 -0
  561. package/src/utils/__tests__/context.test.ts +93 -0
  562. package/src/utils/__tests__/params-resolvers.test.ts +652 -0
  563. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +104 -0
  564. package/src/utils/__tests__/safeGlobals.test.ts +29 -0
  565. package/src/utils/__tests__/utils.test.ts +1021 -0
  566. package/src/utils/__tests__/variablesParams.test.ts +52 -0
  567. package/src/utils/autoFlowError.ts +29 -0
  568. package/src/utils/constants.ts +60 -0
  569. package/src/utils/context.ts +70 -0
  570. package/src/utils/createCollectionContextMeta.ts +122 -0
  571. package/src/utils/exceptions.ts +36 -0
  572. package/src/utils/flow-definitions.ts +16 -0
  573. package/src/utils/index.ts +63 -0
  574. package/src/utils/inheritance.ts +39 -0
  575. package/src/utils/params-resolvers.ts +482 -0
  576. package/src/utils/parsePathnameToViewParams.ts +103 -0
  577. package/src/utils/safeGlobals.ts +188 -0
  578. package/src/utils/schema-utils.ts +201 -0
  579. package/src/utils/serverContextParams.ts +111 -0
  580. package/src/utils/setupRuntimeContextSteps.ts +89 -0
  581. package/src/utils/translation.ts +37 -0
  582. package/src/utils/variablesParams.ts +175 -0
  583. package/src/views/DialogComponent.tsx +79 -0
  584. package/src/views/DrawerComponent.tsx +72 -0
  585. package/src/views/FlowView.tsx +103 -0
  586. package/src/views/PageComponent.tsx +150 -0
  587. package/src/views/ViewNavigation.ts +122 -0
  588. package/src/views/__tests__/FlowView.test.ts +31 -0
  589. package/src/views/__tests__/ViewNavigation.test.ts +191 -0
  590. package/src/views/__tests__/usePatchElement.test.tsx +28 -0
  591. package/src/views/createViewMeta.ts +157 -0
  592. package/src/views/index.tsx +14 -0
  593. package/src/views/useDialog.tsx +192 -0
  594. package/src/views/useDrawer.tsx +205 -0
  595. package/src/views/usePage.tsx +182 -0
  596. package/src/views/usePatchElement.tsx +27 -0
  597. package/src/views/usePopover.tsx +131 -0
@@ -0,0 +1,905 @@
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
+ import { observable } from '@formily/reactive';
10
+ import _ from 'lodash';
11
+ import pino from 'pino';
12
+ import { EngineActionRegistry } from './action-registry/EngineActionRegistry';
13
+ import { EngineEventRegistry } from './event-registry/EngineEventRegistry';
14
+ import { FlowExecutor } from './executor/FlowExecutor';
15
+ import { FlowContext, FlowEngineContext, FlowRuntimeContext } from './flowContext';
16
+ import { FlowSettings } from './flowSettings';
17
+ import { ErrorFlowModel, FlowModel } from './models';
18
+ import { ReactView } from './ReactView';
19
+ import { APIResource, FlowResource, MultiRecordResource, SingleRecordResource, SQLResource } from './resources';
20
+ import type {
21
+ ActionDefinition,
22
+ ApplyFlowCacheEntry,
23
+ CreateModelOptions,
24
+ EventDefinition,
25
+ FlowModelOptions,
26
+ IFlowModelRepository,
27
+ ModelConstructor,
28
+ PersistOptions,
29
+ ResourceType,
30
+ } from './types';
31
+ import { isInheritedFrom } from './utils';
32
+
33
+ /**
34
+ * FlowEngine is the core class of the flow engine, responsible for managing flow models, actions, model repository, and more.
35
+ * It provides capabilities for registering, creating, finding, persisting, replacing, and moving models.
36
+ * Supports flow definitions, action definitions, model class inheritance and filtering.
37
+ * Integrates FlowEngineContext, FlowSettings, and ReactView for context, configuration, and view rendering.
38
+ *
39
+ * Main features:
40
+ * - Register, get, and find model classes and model instances
41
+ * - Register and get action definitions
42
+ * - Persist and query models via the model repository
43
+ * - Register flow definitions
44
+ * - Create, find, replace, move, and destroy model instances
45
+ * - Support for model class inheritance and filtering
46
+ * - Internationalization support
47
+ * - Integration with React view rendering
48
+ *
49
+ * @example
50
+ * const engine = new FlowEngine();
51
+ * engine.registerModels({ MyModel });
52
+ * engine.setModelRepository(new MyRepository());
53
+ * const model = engine.createModel({ use: 'MyModel', uid: 'xxx' });
54
+ */
55
+ export class FlowEngine {
56
+ /**
57
+ * Global action registry
58
+ */
59
+ private _actionRegistry = new EngineActionRegistry();
60
+
61
+ /**
62
+ * Global event registry
63
+ */
64
+ private _eventRegistry = new EngineEventRegistry();
65
+
66
+ /**
67
+ * Registered model classes.
68
+ * Key is the model class name, value is the model class constructor.
69
+ * @private
70
+ */
71
+ private _modelClasses: Map<string, ModelConstructor> = observable.shallow(new Map());
72
+
73
+ /**
74
+ * Created model instances.
75
+ * Key is the model instance UID, value is the model instance object.
76
+ * @private
77
+ */
78
+ private _modelInstances: Map<string, any> = new Map();
79
+
80
+ /**
81
+ * The current model repository instance, implements IFlowModelRepository.
82
+ * Used for model persistence and queries.
83
+ * @private
84
+ */
85
+ private _modelRepository: IFlowModelRepository | null = null;
86
+
87
+ /**
88
+ * Flow application cache.
89
+ * Key is the cache key, value is ApplyFlowCacheEntry.
90
+ * @private
91
+ */
92
+ private _applyFlowCache = new Map<string, ApplyFlowCacheEntry>();
93
+
94
+ /**
95
+ * Model saving state tracking.
96
+ * Key is the model UID, value is the save promise.
97
+ * @private
98
+ */
99
+ private _savingModels = new Map<string, Promise<any>>();
100
+
101
+ /**
102
+ * Flow engine context object.
103
+ * @private
104
+ */
105
+ private _flowContext: FlowEngineContext;
106
+
107
+ /**
108
+ * 视图作用域引擎的栈式链表指针。
109
+ * - previousEngine:打开当前视图的上一个引擎
110
+ * - nextEngine:在当前之上的下一个引擎
111
+ */
112
+ private _previousEngine?: FlowEngine;
113
+ private _nextEngine?: FlowEngine;
114
+
115
+ private _resources = new Map<string, typeof FlowResource>();
116
+
117
+ logger: pino.Logger;
118
+
119
+ /**
120
+ * Flow settings, including components and form scopes.
121
+ * @public
122
+ */
123
+ public flowSettings: FlowSettings;
124
+
125
+ /**
126
+ * Experimental API: Integrates React view rendering capability into FlowEngine.
127
+ * This property may change or be removed in the future. Use with caution.
128
+ * @experimental
129
+ * @public
130
+ */
131
+ public reactView: ReactView;
132
+ /**
133
+ * Flow executor that runs flows and auto-flows.
134
+ */
135
+ public executor: FlowExecutor;
136
+
137
+ /**
138
+ * Constructor. Initializes React view, registers default model and form scopes.
139
+ */
140
+ constructor() {
141
+ this.reactView = new ReactView(this);
142
+ this.flowSettings = new FlowSettings(this);
143
+ this.flowSettings.registerScopes({ t: this.translate.bind(this) });
144
+ this.registerModels({ FlowModel }); // 会造成循环依赖问题,移除掉
145
+ this.registerResources({
146
+ FlowResource,
147
+ SQLResource,
148
+ APIResource,
149
+ SingleRecordResource,
150
+ MultiRecordResource,
151
+ });
152
+ this.logger = pino({
153
+ level: 'trace',
154
+ browser: {
155
+ write: {
156
+ fatal: (o) => console.trace(o),
157
+ error: (o) => console.error(o),
158
+ warn: (o) => console.warn(o),
159
+ info: (o) => console.info(o),
160
+ debug: (o) => console.debug(o),
161
+ trace: (o) => console.trace(o),
162
+ },
163
+ },
164
+ });
165
+ this.executor = new FlowExecutor(this);
166
+ }
167
+
168
+ /** 上一个引擎(根引擎为 undefined) */
169
+ get previousEngine(): FlowEngine | undefined {
170
+ return this._previousEngine;
171
+ }
172
+ /** 下一个引擎(若存在) */
173
+ get nextEngine(): FlowEngine | undefined {
174
+ return this._nextEngine;
175
+ }
176
+
177
+ /**
178
+ * 将当前引擎链接到 prev 之后(用于视图打开时形成栈关系)。
179
+ */
180
+ public linkAfter(engine: FlowEngine): void {
181
+ // 找到栈底
182
+ let prev: FlowEngine = engine;
183
+ while (prev._nextEngine) prev = prev._nextEngine;
184
+ this._previousEngine = prev;
185
+ if (prev) {
186
+ prev._nextEngine = this;
187
+ }
188
+ }
189
+
190
+ /**
191
+ * 将当前引擎从栈中移除并修复相邻指针(用于视图关闭时)。
192
+ */
193
+ public unlinkFromStack(): void {
194
+ const prev = this._previousEngine;
195
+ const next = this._nextEngine;
196
+ if (prev) {
197
+ prev._nextEngine = undefined;
198
+ }
199
+ }
200
+
201
+ // (已移除)getModelGlobal/forEachModelGlobal/getAllModelsGlobal:不再维护冗余全局遍历 API
202
+
203
+ /**
204
+ * Get the flow engine context object.
205
+ * @returns {FlowEngineContext} Flow engine context
206
+ */
207
+ get context() {
208
+ if (!this._flowContext) {
209
+ this._flowContext = new FlowEngineContext(this);
210
+ }
211
+ return this._flowContext;
212
+ }
213
+
214
+ get dataSourceManager() {
215
+ return this.context.dataSourceManager;
216
+ }
217
+
218
+ /**
219
+ * Get the flow application cache.
220
+ * @returns {Map<string, ApplyFlowCacheEntry>} Flow application cache map
221
+ * @internal
222
+ */
223
+ get applyFlowCache() {
224
+ return this._applyFlowCache;
225
+ }
226
+
227
+ /**
228
+ * Set the model repository for persisting and querying model instances.
229
+ * If a model repository was already set, it will be overwritten and a warning will be printed.
230
+ * @param {IFlowModelRepository} modelRepository The model repository instance implementing IFlowModelRepository.
231
+ * @example
232
+ * flowEngine.setModelRepository(new MyFlowModelRepository());
233
+ */
234
+ setModelRepository(modelRepository: IFlowModelRepository) {
235
+ if (this._modelRepository) {
236
+ console.warn('FlowEngine: Model repository is already set and will be overwritten.');
237
+ }
238
+ this._modelRepository = modelRepository;
239
+ }
240
+
241
+ get modelRepository(): IFlowModelRepository | null {
242
+ return this._modelRepository;
243
+ }
244
+
245
+ /**
246
+ * Internationalization translation method, calls the context's t method.
247
+ * @param {string} keyOrTemplate Translation key or template string
248
+ * @param {any} [options] Optional parameters
249
+ * @returns {string} Translated string
250
+ */
251
+ translate(keyOrTemplate: string, options?: any): string {
252
+ return this.context.t(keyOrTemplate, options);
253
+ }
254
+
255
+ /**
256
+ * Register multiple actions.
257
+ * @param {Record<string, ActionDefinition>} actions Action definition object collection
258
+ */
259
+ registerActions(actions: Record<string, ActionDefinition>): void {
260
+ this._actionRegistry.registerActions(actions);
261
+ }
262
+
263
+ /**
264
+ * Get a registered action definition.
265
+ * @template TModel Specific FlowModel subclass type
266
+ * @param {string} name Action name
267
+ * @returns {ActionDefinition<TModel> | undefined} Action definition, or undefined if not found
268
+ */
269
+ public getAction<TModel extends FlowModel = FlowModel, TCtx extends FlowContext = FlowRuntimeContext<TModel>>(
270
+ name: string,
271
+ ): ActionDefinition<TModel, TCtx> | undefined {
272
+ return this._actionRegistry.getAction<TModel, TCtx>(name);
273
+ }
274
+
275
+ /**
276
+ * Get all registered global actions.
277
+ * Returns a new Map to avoid external mutation of internal state.
278
+ */
279
+ public getActions<TModel extends FlowModel = FlowModel, TCtx extends FlowContext = FlowRuntimeContext<TModel>>(): Map<
280
+ string,
281
+ ActionDefinition<TModel, TCtx>
282
+ > {
283
+ return this._actionRegistry.getActions<TModel, TCtx>();
284
+ }
285
+
286
+ /**
287
+ * Register multiple events.
288
+ */
289
+ registerEvents(events: Record<string, EventDefinition>): void {
290
+ this._eventRegistry.registerEvents(events);
291
+ }
292
+
293
+ /**
294
+ * Get a registered event definition.
295
+ */
296
+ public getEvent<TModel extends FlowModel = FlowModel>(name: string): EventDefinition<TModel> | undefined {
297
+ return this._eventRegistry.getEvent<TModel>(name);
298
+ }
299
+
300
+ /**
301
+ * Get all registered global events.
302
+ */
303
+ public getEvents<TModel extends FlowModel = FlowModel>(): Map<string, EventDefinition<TModel>> {
304
+ return this._eventRegistry.getEvents<TModel>();
305
+ }
306
+
307
+ /**
308
+ * Register a single model class.
309
+ * @param {string} name Model class name
310
+ * @param {ModelConstructor} modelClass Model class constructor
311
+ * @private
312
+ */
313
+ #registerModel(name: string, modelClass: ModelConstructor): void {
314
+ if (this._modelClasses.has(name)) {
315
+ console.warn(`FlowEngine: Model class with name '${name}' is already registered and will be overwritten.`);
316
+ }
317
+ Object.defineProperty(modelClass, 'name', { value: name });
318
+ this._modelClasses.set(name, modelClass);
319
+ }
320
+
321
+ /**
322
+ * Register multiple model classes.
323
+ * @param {Record<string, ModelConstructor>} models Model class map, key is model name, value is model constructor
324
+ * @returns {void}
325
+ * @example
326
+ * flowEngine.registerModels({ UserModel, OrderModel });
327
+ */
328
+ public registerModels(models: Record<string, ModelConstructor | typeof FlowModel<any>>) {
329
+ for (const [name, modelClass] of Object.entries(models)) {
330
+ this.#registerModel(name, modelClass);
331
+ }
332
+ }
333
+
334
+ registerResources(resources: Record<string, any>) {
335
+ for (const [name, resourceClass] of Object.entries(resources)) {
336
+ this._resources.set(name, resourceClass);
337
+ }
338
+ }
339
+
340
+ createResource<T = FlowResource>(resourceType: ResourceType<T>, options?: { context?: FlowContext }): T {
341
+ if (typeof resourceType === 'string') {
342
+ const ResourceClass = this._resources.get(resourceType);
343
+ if (!ResourceClass) {
344
+ throw new Error(`Resource class '${resourceType}' not found. Please register it first.`);
345
+ }
346
+ return new ResourceClass((options?.context as any) || this.context) as T;
347
+ }
348
+ const R = resourceType;
349
+ return new R(options?.context || this.context) as T;
350
+ }
351
+
352
+ /**
353
+ * Get all registered model classes.
354
+ * @returns {Map<string, ModelConstructor>} Model class map
355
+ */
356
+ getModelClasses() {
357
+ return this._modelClasses;
358
+ }
359
+
360
+ /**
361
+ * Get a registered model class (constructor).
362
+ * @param {string} name Model class name
363
+ * @returns {ModelConstructor | undefined} Model constructor, or undefined if not found
364
+ */
365
+ public getModelClass(name: string): ModelConstructor | undefined {
366
+ return this._modelClasses.get(name);
367
+ }
368
+
369
+ /**
370
+ * Find a registered model class by predicate.
371
+ * @param predicate Callback function, arguments are (name, ModelClass), returns true if matched
372
+ * @returns {[string, ModelConstructor] | undefined} Matched model class and name
373
+ */
374
+ public findModelClass(
375
+ predicate: (name: string, ModelClass: ModelConstructor) => boolean,
376
+ ): [string, ModelConstructor] | undefined {
377
+ for (const [name, ModelClass] of this._modelClasses) {
378
+ if (predicate(name, ModelClass)) {
379
+ return [name, ModelClass];
380
+ }
381
+ }
382
+ return undefined;
383
+ }
384
+
385
+ /**
386
+ * Filter model classes by base class (supports multi-level inheritance), with optional custom filter.
387
+ * @param {string | ModelConstructor} baseClass Base class name or constructor
388
+ * @param {(ModelClass: ModelConstructor, className: string) => boolean} [filter] Optional filter function
389
+ * @returns {Map<string, ModelConstructor>} Model classes inherited from base class and passed the filter
390
+ */
391
+ public getSubclassesOf(
392
+ baseClass: string | ModelConstructor,
393
+ filter?: (ModelClass: ModelConstructor, className: string) => boolean,
394
+ ): Map<string, ModelConstructor> {
395
+ const parentModelClass = typeof baseClass === 'string' ? this.getModelClass(baseClass) : baseClass;
396
+ const result = new Map<string, ModelConstructor>();
397
+ if (!parentModelClass) return result;
398
+ for (const [className, ModelClass] of this._modelClasses) {
399
+ if (isInheritedFrom(ModelClass, parentModelClass)) {
400
+ if (!filter || filter(ModelClass, className)) {
401
+ result.set(className, ModelClass);
402
+ }
403
+ }
404
+ }
405
+ return result;
406
+ }
407
+
408
+ /**
409
+ * Create and register a model instance.
410
+ * If an instance with the same UID exists, returns the existing instance.
411
+ * @template T FlowModel subclass type, defaults to FlowModel.
412
+ * @param {CreateModelOptions} options Model creation options
413
+ * @returns {T} Created model instance
414
+ */
415
+ public createModel<T extends FlowModel = FlowModel>(
416
+ options: CreateModelOptions,
417
+ extra?: { delegateToParent?: boolean; delegate?: FlowContext },
418
+ ): T {
419
+ const { parentId, uid, use: modelClassName, subModels } = options;
420
+ const ModelClass = typeof modelClassName === 'string' ? this.getModelClass(modelClassName) : modelClassName;
421
+
422
+ if (uid && this._modelInstances.has(uid)) {
423
+ return this._modelInstances.get(uid) as T;
424
+ }
425
+
426
+ let modelInstance: T | ErrorFlowModel;
427
+
428
+ if (!ModelClass) {
429
+ modelInstance = new ErrorFlowModel({ ...options, flowEngine: this } as any);
430
+ modelInstance.setErrorMessage(`Model class '${modelClassName}' not found. Please register it first.`);
431
+ } else {
432
+ modelInstance = new (ModelClass as ModelConstructor<T>)({ ...options, flowEngine: this } as any);
433
+ }
434
+
435
+ if (extra?.delegate) {
436
+ modelInstance.context.addDelegate(extra.delegate);
437
+ }
438
+
439
+ if (parentId && this._modelInstances.has(parentId)) {
440
+ modelInstance.setParent(this._modelInstances.get(parentId));
441
+ if (extra?.delegateToParent === false) {
442
+ modelInstance.removeParentDelegate();
443
+ }
444
+ }
445
+
446
+ this._modelInstances.set(modelInstance.uid, modelInstance);
447
+
448
+ modelInstance.onInit(options);
449
+
450
+ // 在模型实例化阶段应用 flow 级 defaultParams(仅填充缺失的 stepParams,不覆盖)
451
+ // 不阻塞创建流程:允许 defaultParams 为异步函数
452
+ this._applyFlowDefinitionDefaultParams(modelInstance as FlowModel).catch((err) => {
453
+ console.warn('FlowEngine: apply flow defaultParams failed:', err);
454
+ });
455
+
456
+ modelInstance._createSubModels(options.subModels);
457
+
458
+ return modelInstance as T;
459
+ }
460
+
461
+ /**
462
+ * 尝试应用当前模型可用 flow 的 defaultParams(如果存在)到 model.stepParams。
463
+ * 仅对尚未存在的步骤参数进行填充,不覆盖已有值。
464
+ */
465
+ async _applyFlowDefinitionDefaultParams(model: FlowModel) {
466
+ try {
467
+ const flows = model.getFlows();
468
+ if (!flows || flows.size === 0) return;
469
+ const ctx = model.context;
470
+ for (const [flowKey, flowDef] of flows.entries()) {
471
+ const dp = flowDef.defaultParams;
472
+ if (!dp) continue;
473
+
474
+ let resolved: any;
475
+ try {
476
+ resolved = typeof dp === 'function' ? await dp(ctx) : dp;
477
+ } catch (e) {
478
+ console.warn(`FlowEngine: resolve defaultParams of flow '${flowKey}' failed:`, e);
479
+ continue;
480
+ }
481
+
482
+ if (!resolved || typeof resolved !== 'object') continue;
483
+
484
+ // 仅支持:返回当前 flow 的步骤对象 { [stepKey]: params }
485
+ const stepsMap = (flowDef as any).getSteps?.() as Map<string, any> | undefined;
486
+ const stepKeys = stepsMap ? Array.from(stepsMap.keys()) : Object.keys(flowDef.steps || {});
487
+ const entries = Object.entries(resolved).filter(([k]) => stepKeys.includes(k));
488
+ if (entries.length === 0) continue;
489
+
490
+ for (const [stepKey, params] of entries) {
491
+ const exists = model.getStepParams(flowKey, stepKey as string);
492
+ if (exists === undefined && params && typeof params === 'object') {
493
+ model.setStepParams(flowKey, stepKey as string, params as any);
494
+ }
495
+ }
496
+ }
497
+ } catch (error) {
498
+ console.warn('FlowEngine: apply flow defaultParams error:', error);
499
+ }
500
+ }
501
+
502
+ /**
503
+ * Get a model instance by UID.
504
+ * @template T FlowModel subclass type, defaults to FlowModel.
505
+ * @param {string} uid Model instance UID
506
+ * @returns {T | undefined} Model instance, or undefined if not found
507
+ */
508
+ public getModel<T extends FlowModel = FlowModel>(uid: string, global?: boolean): T | undefined {
509
+ // 默认仅在当前引擎查找;只有当 global === true 时才跨视图栈查找
510
+ if (!global) {
511
+ return this._modelInstances.get(uid) as T | undefined;
512
+ }
513
+ // 跨视图栈查找:按视图栈从栈顶到根逐个查找
514
+ // 1) 找到栈顶引擎
515
+ let top: FlowEngine = this;
516
+ while (top.nextEngine) top = top.nextEngine;
517
+ // 2) 从栈顶向下查找,命中即返回
518
+ let eng: FlowEngine | undefined = top;
519
+ while (eng) {
520
+ const found = eng._modelInstances.get(uid) as T | undefined;
521
+ if (found) return found;
522
+ eng = eng.previousEngine;
523
+ }
524
+ return undefined;
525
+ }
526
+
527
+ /**
528
+ * Iterate all registered model instances.
529
+ * @template T FlowModel subclass type, defaults to FlowModel.
530
+ * @param {(model: T) => void} callback Callback function
531
+ */
532
+ forEachModel<T extends FlowModel = FlowModel>(callback: (model: T) => void): void {
533
+ this._modelInstances.forEach(callback);
534
+ }
535
+
536
+ /**
537
+ * Remove a local model instance.
538
+ * @param {string} uid UID of the model instance to destroy
539
+ * @returns {boolean} Returns true if successfully destroyed, false otherwise (e.g. instance does not exist)
540
+ */
541
+ public removeModel(uid: string): boolean {
542
+ if (!this._modelInstances.has(uid)) {
543
+ console.warn(`FlowEngine: Model with UID '${uid}' does not exist.`);
544
+ return false;
545
+ }
546
+ const modelInstance = this._modelInstances.get(uid) as FlowModel;
547
+ modelInstance.clearForks();
548
+ // 从父模型中移除当前模型的引用
549
+ if (modelInstance.parent?.subModels) {
550
+ for (const subKey in modelInstance.parent.subModels) {
551
+ const subModelValue = modelInstance.parent.subModels[subKey];
552
+
553
+ if (Array.isArray(subModelValue)) {
554
+ const index = subModelValue.findIndex((subModel) => subModel == modelInstance);
555
+ if (index !== -1) {
556
+ subModelValue.splice(index, 1);
557
+ modelInstance.parent.emitter.emit('onSubModelRemoved', modelInstance);
558
+ break;
559
+ }
560
+ } else if (subModelValue && subModelValue === modelInstance) {
561
+ delete modelInstance.parent.subModels[subKey];
562
+ modelInstance.parent.emitter.emit('onSubModelRemoved', modelInstance);
563
+ break;
564
+ }
565
+ }
566
+ }
567
+ this._modelInstances.delete(uid);
568
+ return true;
569
+ }
570
+
571
+ /**
572
+ * Check if the model repository is set.
573
+ * @returns {boolean} Returns true if set, false otherwise.
574
+ * @private
575
+ */
576
+ private ensureModelRepository(): boolean {
577
+ if (!this._modelRepository) {
578
+ // 不抛错,直接返回 false
579
+ return false;
580
+ }
581
+ return true;
582
+ }
583
+
584
+ /**
585
+ * Load a model instance (prefers local, falls back to repository).
586
+ * @template T FlowModel subclass type, defaults to FlowModel.
587
+ * @param {any} options Load options
588
+ * @returns {Promise<T | null>} Loaded model instance or null
589
+ */
590
+ async loadModel<T extends FlowModel = FlowModel>(options): Promise<T | null> {
591
+ if (!this.ensureModelRepository()) return;
592
+ const model = this.findModelByParentId(options.parentId, options.subKey);
593
+ if (model) {
594
+ return model as T;
595
+ }
596
+ const data = await this._modelRepository.findOne(options);
597
+ return data?.uid ? this.createModel<T>(data as any) : null;
598
+ }
599
+
600
+ /**
601
+ * Find a sub-model by parent model ID and subKey.
602
+ * @template T FlowModel subclass type, defaults to FlowModel.
603
+ * @param {string} parentId Parent model UID
604
+ * @param {string} subKey Sub-model key
605
+ * @returns {T | null} Found sub-model or null
606
+ */
607
+ findModelByParentId<T extends FlowModel = FlowModel>(parentId: string, subKey: string): T | null {
608
+ if (parentId && this._modelInstances.has(parentId)) {
609
+ const parentModel = this._modelInstances.get(parentId) as FlowModel;
610
+ if (parentModel && parentModel.subModels[subKey]) {
611
+ const subModels = parentModel.subModels[subKey];
612
+ if (Array.isArray(subModels)) {
613
+ return subModels[0] as T; // 返回第一个子模型
614
+ } else {
615
+ return subModels as T;
616
+ }
617
+ }
618
+ }
619
+ }
620
+
621
+ /**
622
+ * Load or create a model instance.
623
+ * @template T FlowModel subclass type, defaults to FlowModel.
624
+ * @param {any} options Load or create options
625
+ * @returns {Promise<T | null>} Model instance or null
626
+ */
627
+ async loadOrCreateModel<T extends FlowModel = FlowModel>(
628
+ options,
629
+ extra?: {
630
+ delegateToParent?: boolean;
631
+ delegate?: FlowContext;
632
+ },
633
+ ): Promise<T | null> {
634
+ if (!this.ensureModelRepository()) return;
635
+ const { uid, parentId, subKey } = options;
636
+ if (uid && this._modelInstances.has(uid)) {
637
+ return this._modelInstances.get(uid) as T;
638
+ }
639
+ const m = this.findModelByParentId<T>(parentId, subKey);
640
+ if (m) {
641
+ return m;
642
+ }
643
+ const data = await this._modelRepository.findOne(options);
644
+ let model: T | null = null;
645
+ if (data?.uid) {
646
+ model = this.createModel<T>(data as any, extra);
647
+ } else {
648
+ model = this.createModel<T>(options, extra);
649
+ await model.save();
650
+ }
651
+ if (model.parent) {
652
+ const subModel = model.parent.findSubModel(model.subKey, (m) => {
653
+ return m.uid === model.uid;
654
+ });
655
+ if (subModel) {
656
+ return model;
657
+ }
658
+ if (model.subType === 'array') {
659
+ model.parent.addSubModel(model.subKey, model);
660
+ } else {
661
+ model.parent.setSubModel(model.subKey, model);
662
+ }
663
+ }
664
+ return model;
665
+ }
666
+
667
+ /**
668
+ * Persist and save a model instance.
669
+ * Prevents concurrent saves of the same model by tracking save operations.
670
+ * If a model is already being saved, subsequent calls will wait for the existing save to complete.
671
+ *
672
+ * @template T FlowModel subclass type, defaults to FlowModel.
673
+ * @param {T} model Model instance to save
674
+ * @param {object} [options] Save options
675
+ * @param {boolean} [options.onlyStepParams] Whether to save only step parameters
676
+ * @returns {Promise<any>} Repository save result
677
+ */
678
+ async saveModel<T extends FlowModel = FlowModel>(model: T, options?: { onlyStepParams?: boolean }): Promise<any> {
679
+ if (!this.ensureModelRepository()) return;
680
+
681
+ const modelUid = model.uid;
682
+
683
+ // 如果这个 model 正在保存中,返回现有的保存 Promise
684
+ if (this._savingModels.has(modelUid)) {
685
+ this.logger.debug(`Model ${modelUid} is already being saved, waiting for existing save operation`);
686
+ return await this._savingModels.get(modelUid);
687
+ }
688
+
689
+ // 创建保存 Promise 并添加到追踪 Map 中
690
+ const savePromise = this._performModelSave(model, options);
691
+ this._savingModels.set(modelUid, savePromise);
692
+
693
+ try {
694
+ const result = await savePromise;
695
+ return result;
696
+ } finally {
697
+ // 无论成功还是失败,都要清除保存状态
698
+ this._savingModels.delete(modelUid);
699
+ }
700
+ }
701
+
702
+ /**
703
+ * Perform the actual model save operation.
704
+ * @template T FlowModel subclass type, defaults to FlowModel.
705
+ * @param {T} model Model instance to save
706
+ * @param {object} [options] Save options
707
+ * @returns {Promise<any>} Repository save result
708
+ * @private
709
+ */
710
+ async _performModelSave<T extends FlowModel = FlowModel>(
711
+ model: T,
712
+ options?: { onlyStepParams?: boolean },
713
+ ): Promise<any> {
714
+ this.logger.debug(`Starting save operation for model ${model.uid}`);
715
+ try {
716
+ const result = await this._modelRepository.save(model, options);
717
+ this.logger.debug(`Successfully saved model ${model.uid}`);
718
+ return result;
719
+ } catch (error) {
720
+ this.logger.error(`Failed to save model ${model.uid}:`, error);
721
+ throw error;
722
+ }
723
+ }
724
+
725
+ /**
726
+ * Destroy a model instance (persistently delete and remove local instance).
727
+ * @param {string} uid UID of the model to destroy
728
+ * @returns {Promise<boolean>} Whether destroyed successfully
729
+ */
730
+ async destroyModel(uid: string) {
731
+ if (this.ensureModelRepository()) {
732
+ await this._modelRepository.destroy(uid);
733
+ }
734
+ return this.removeModel(uid);
735
+ }
736
+
737
+ /**
738
+ * Replace a model instance with a new instance of a class.
739
+ * @template T New model type
740
+ * @param {string} uid UID of the model to replace
741
+ * @param {Partial<FlowModelOptions> | ((oldModel: FlowModel) => Partial<FlowModelOptions>)} [optionsOrFn]
742
+ * Options for creating the new model, supports two forms:
743
+ * 1. Pass options directly
744
+ * 2. Pass a function that receives current options and returns new options
745
+ * @returns {Promise<T | null>} Newly created model instance
746
+ */
747
+ async replaceModel<T extends FlowModel = FlowModel>(
748
+ uid: string,
749
+ optionsOrFn?: Partial<FlowModelOptions> | ((currentOptions: FlowModelOptions) => Partial<FlowModelOptions>),
750
+ ): Promise<T | null> {
751
+ const oldModel = this.getModel(uid);
752
+ if (!oldModel) {
753
+ console.warn(`FlowEngine: Cannot replace model. Model with UID '${uid}' not found.`);
754
+ return null;
755
+ }
756
+
757
+ // 1. 保存当前模型的关键信息
758
+ const currentParent = oldModel.parent;
759
+ const currentSubKey = oldModel.subKey;
760
+ const currentSubType = oldModel.subType;
761
+ const currentOptions = oldModel.serialize();
762
+
763
+ // 2. 确定新的选项
764
+ let userOptions: Partial<FlowModelOptions>;
765
+
766
+ if (typeof optionsOrFn === 'function') {
767
+ // 函数模式:传入当前options,获取新的options
768
+ userOptions = optionsOrFn(oldModel as any);
769
+ } else {
770
+ // 对象模式:直接使用提供的options替换
771
+ userOptions = optionsOrFn || {};
772
+ }
773
+
774
+ // 3. 合并用户选项和关键属性
775
+ const newOptions = {
776
+ ..._.omit(currentOptions, ['subModels']),
777
+ ...userOptions,
778
+ } as CreateModelOptions;
779
+
780
+ // 暂停父模型的事件触发,
781
+ // TODO: find a better way to do this
782
+ if (currentParent) {
783
+ currentParent.emitter.setPaused(true);
784
+ }
785
+
786
+ // 4. 销毁当前模型(这会处理所有清理工作:持久化删除、内存清理、父模型引用等)
787
+ await oldModel.destroy();
788
+
789
+ // 5. 使用createModel创建新的模型实例
790
+ const newModel = this.createModel<T>(newOptions);
791
+
792
+ // 6. 如果有父模型,将新模型添加到父模型的subModels中
793
+ if (currentParent && currentSubKey) {
794
+ if (currentSubType === 'array') {
795
+ // 对于数组类型,使用addSubModel方法
796
+ currentParent.addSubModel(currentSubKey, newModel);
797
+ } else {
798
+ // 对于对象类型,使用setSubModel方法
799
+ currentParent.setSubModel(currentSubKey, newModel);
800
+ }
801
+ }
802
+
803
+ // 7. 触发事件以通知其他部分模型已替换
804
+ if (currentParent) {
805
+ currentParent.emitter.setPaused(false);
806
+ currentParent.parent.invalidateAutoFlowCache(true);
807
+ currentParent.parent?.rerender();
808
+ currentParent.emitter.emit('onSubModelReplaced', { oldModel, newModel });
809
+ }
810
+ await newModel.save();
811
+ return newModel;
812
+ }
813
+
814
+ /**
815
+ * Move a model instance within its parent model.
816
+ * @param {any} sourceId Source model UID
817
+ * @param {any} targetId Target model UID
818
+ * @returns {Promise<void>} No return value
819
+ */
820
+ async moveModel(sourceId: any, targetId: any, options?: PersistOptions): Promise<void> {
821
+ const sourceModel = this.getModel(sourceId);
822
+ const targetModel = this.getModel(targetId);
823
+ if (!sourceModel || !targetModel) {
824
+ console.warn(`FlowEngine: Cannot move model. Source or target model not found.`);
825
+ return;
826
+ }
827
+ const move = (sourceModel: FlowModel, targetModel: FlowModel) => {
828
+ if (!sourceModel.parent || !targetModel.parent || sourceModel.parent !== targetModel.parent) {
829
+ console.error('FlowModel.moveTo: Both models must have the same parent to perform move operation.');
830
+ return false;
831
+ }
832
+
833
+ const subModels = sourceModel.parent.subModels[sourceModel.subKey];
834
+
835
+ if (!subModels || !Array.isArray(subModels)) {
836
+ console.error('FlowModel.moveTo: Parent subModels must be an array to perform move operation.');
837
+ return false;
838
+ }
839
+
840
+ const findIndex = (model: FlowModel) => subModels.findIndex((item) => item.uid === model.uid);
841
+
842
+ const currentIndex = findIndex(sourceModel);
843
+ const targetIndex = findIndex(targetModel);
844
+
845
+ if (currentIndex === -1 || targetIndex === -1) {
846
+ console.error('FlowModel.moveTo: Current or target model not found in parent subModels.');
847
+ return false;
848
+ }
849
+
850
+ if (currentIndex === targetIndex) {
851
+ console.warn('FlowModel.moveTo: Current model is already at the target position. No action taken.');
852
+ return false;
853
+ }
854
+
855
+ // 使用splice直接移动数组元素(O(n)比排序O(n log n)更快)
856
+ const [movedModel] = subModels.splice(currentIndex, 1);
857
+ subModels.splice(targetIndex, 0, movedModel);
858
+
859
+ // 重新分配连续的sortIndex
860
+ subModels.forEach((model, index) => {
861
+ model.sortIndex = index;
862
+ });
863
+
864
+ return true;
865
+ };
866
+ move(sourceModel, targetModel);
867
+ if (options?.persist !== false && this.ensureModelRepository()) {
868
+ const position = sourceModel.sortIndex - targetModel.sortIndex > 0 ? 'after' : 'before';
869
+ await this._modelRepository.move(sourceId, targetId, position);
870
+ }
871
+ // 触发事件以通知其他部分模型已移动
872
+ sourceModel.parent.emitter.emit('onSubModelMoved', { source: sourceModel, target: targetModel });
873
+ }
874
+
875
+ /**
876
+ * Filter model classes by parent class (supports multi-level inheritance).
877
+ * @param {string | ModelConstructor} parentClass Parent class name or constructor
878
+ * @returns {Map<string, ModelConstructor>} Model classes inherited from the specified parent class
879
+ */
880
+ public filterModelClassByParent(parentClass: string | ModelConstructor) {
881
+ const parentModelClass = typeof parentClass === 'string' ? this.getModelClass(parentClass) : parentClass;
882
+ if (!parentModelClass) {
883
+ return new Map();
884
+ }
885
+ const modelClasses = new Map<string, ModelConstructor>();
886
+ for (const [className, ModelClass] of this._modelClasses) {
887
+ if (isInheritedFrom(ModelClass, parentModelClass)) {
888
+ modelClasses.set(className, ModelClass);
889
+ }
890
+ }
891
+ return modelClasses;
892
+ }
893
+
894
+ /**
895
+ * Generate a unique key for the flow application cache.
896
+ * @param {string} prefix Prefix
897
+ * @param {string} flowKey Flow key
898
+ * @param {string} modelUid Model UID
899
+ * @returns {string} Unique cache key
900
+ * @internal
901
+ */
902
+ static generateApplyFlowCacheKey(prefix: string, flowKey: string, modelUid: string): string {
903
+ return `${prefix}:${flowKey}:${modelUid}`;
904
+ }
905
+ }