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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. package/lib/BlockScopedFlowEngine.d.ts +23 -0
  2. package/lib/BlockScopedFlowEngine.js +91 -0
  3. package/lib/FlowContextProvider.d.ts +2 -2
  4. package/lib/FlowContextProvider.js +3 -3
  5. package/lib/FlowDefinition.d.ts +6 -4
  6. package/lib/JSRunner.d.ts +6 -0
  7. package/lib/JSRunner.js +27 -1
  8. package/lib/ViewScopedFlowEngine.d.ts +1 -1
  9. package/lib/ViewScopedFlowEngine.js +18 -1
  10. package/lib/acl/Acl.d.ts +12 -12
  11. package/lib/acl/Acl.js +88 -30
  12. package/lib/components/DynamicFlowsEditor.js +2 -4
  13. package/lib/components/FieldModelRenderer.js +17 -9
  14. package/lib/components/FieldSkeleton.d.ts +10 -0
  15. package/lib/components/FieldSkeleton.js +64 -0
  16. package/lib/components/FlowContextSelector.js +19 -3
  17. package/lib/components/FlowModelRenderer.d.ts +4 -6
  18. package/lib/components/FlowModelRenderer.js +35 -53
  19. package/lib/components/FormItem.js +5 -1
  20. package/lib/components/MobilePopup.d.ts +20 -0
  21. package/lib/components/MobilePopup.js +102 -0
  22. package/lib/components/MobilePopup.style.d.ts +17 -0
  23. package/lib/components/MobilePopup.style.js +186 -0
  24. package/lib/components/common/withFlowDesignMode.d.ts +1 -1
  25. package/lib/components/common/withFlowDesignMode.js +5 -5
  26. package/lib/components/dnd/gridDragPlanner.d.ts +1 -0
  27. package/lib/components/dnd/gridDragPlanner.js +53 -1
  28. package/lib/components/index.d.ts +1 -0
  29. package/lib/components/index.js +3 -1
  30. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +71 -53
  31. package/lib/components/settings/wrappers/component/SelectWithTitle.d.ts +19 -0
  32. package/lib/components/settings/wrappers/component/SelectWithTitle.js +136 -0
  33. package/lib/components/settings/wrappers/component/SwitchWithTitle.d.ts +10 -0
  34. package/lib/components/settings/wrappers/component/SwitchWithTitle.js +111 -0
  35. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +233 -97
  36. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +71 -54
  37. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +2 -2
  38. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +63 -23
  39. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +13 -2
  40. package/lib/components/settings/wrappers/embedded/FlowSettings.js +42 -28
  41. package/lib/components/settings/wrappers/embedded/FlowsSettings.js +3 -3
  42. package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.js +52 -32
  43. package/lib/components/subModel/AddSubModelButton.d.ts +7 -0
  44. package/lib/components/subModel/AddSubModelButton.js +78 -8
  45. package/lib/components/subModel/LazyDropdown.js +14 -15
  46. package/lib/components/subModel/utils.d.ts +1 -1
  47. package/lib/components/subModel/utils.js +21 -11
  48. package/lib/components/variables/VariableInput.js +26 -6
  49. package/lib/components/variables/VariableTag.js +43 -2
  50. package/lib/components/variables/types.d.ts +2 -0
  51. package/lib/components/variables/utils.js +4 -2
  52. package/lib/data-source/index.d.ts +23 -4
  53. package/lib/data-source/index.js +135 -14
  54. package/lib/data-source/jioToJoiSchema.js +1 -0
  55. package/lib/emitter.d.ts +6 -0
  56. package/lib/emitter.js +12 -0
  57. package/lib/executor/FlowExecutor.d.ts +6 -6
  58. package/lib/executor/FlowExecutor.js +302 -99
  59. package/lib/flow-registry/GlobalFlowRegistry.d.ts +1 -0
  60. package/lib/flow-registry/GlobalFlowRegistry.js +3 -0
  61. package/lib/flow-registry/InstanceFlowRegistry.d.ts +1 -0
  62. package/lib/flow-registry/InstanceFlowRegistry.js +3 -0
  63. package/lib/flowContext.d.ts +105 -6
  64. package/lib/flowContext.js +447 -139
  65. package/lib/flowEngine.d.ts +71 -1
  66. package/lib/flowEngine.js +319 -16
  67. package/lib/flowSettings.d.ts +4 -3
  68. package/lib/flowSettings.js +45 -21
  69. package/lib/hooks/useApplyAutoFlows.d.ts +1 -0
  70. package/lib/hooks/useApplyAutoFlows.js +3 -2
  71. package/lib/index.d.ts +14 -3
  72. package/lib/index.js +54 -7
  73. package/lib/locale/de-DE.json +62 -0
  74. package/lib/locale/en-US.json +57 -45
  75. package/lib/locale/es-ES.json +62 -0
  76. package/lib/locale/fr-FR.json +62 -0
  77. package/lib/locale/hu-HU.json +62 -0
  78. package/lib/locale/id-ID.json +62 -0
  79. package/lib/locale/index.d.ts +114 -90
  80. package/lib/locale/it-IT.json +62 -0
  81. package/lib/locale/ja-JP.json +62 -0
  82. package/lib/locale/ko-KR.json +62 -0
  83. package/lib/locale/nl-NL.json +62 -0
  84. package/lib/locale/pt-BR.json +62 -0
  85. package/lib/locale/ru-RU.json +62 -0
  86. package/lib/locale/tr-TR.json +62 -0
  87. package/lib/locale/uk-UA.json +62 -0
  88. package/lib/locale/vi-VN.json +62 -0
  89. package/lib/locale/zh-CN.json +58 -46
  90. package/lib/locale/zh-TW.json +62 -0
  91. package/lib/models/CollectionFieldModel.d.ts +7 -2
  92. package/lib/models/CollectionFieldModel.js +63 -16
  93. package/lib/models/flowModel.d.ts +76 -32
  94. package/lib/models/flowModel.js +300 -112
  95. package/lib/models/forkFlowModel.d.ts +8 -4
  96. package/lib/models/forkFlowModel.js +38 -8
  97. package/lib/provider.d.ts +3 -1
  98. package/lib/provider.js +14 -11
  99. package/lib/reactive/index.d.ts +10 -0
  100. package/lib/{runjs-context/snippets/global/api-request-post.snippet.js → reactive/index.js} +14 -15
  101. package/lib/reactive/observer.d.ts +19 -0
  102. package/lib/reactive/observer.js +109 -0
  103. package/lib/resources/baseRecordResource.d.ts +6 -0
  104. package/lib/resources/baseRecordResource.js +38 -3
  105. package/lib/resources/multiRecordResource.d.ts +5 -2
  106. package/lib/resources/multiRecordResource.js +26 -10
  107. package/lib/resources/singleRecordResource.js +8 -3
  108. package/lib/resources/sqlResource.d.ts +5 -3
  109. package/lib/resources/sqlResource.js +30 -28
  110. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +1 -6
  111. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +37 -20
  112. package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +1 -6
  113. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +46 -33
  114. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +1 -2
  115. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +14 -15
  116. package/lib/runjs-context/contexts/{LinkageRunJSContext.d.ts → JSColumnRunJSContext.d.ts} +6 -3
  117. package/lib/runjs-context/contexts/JSColumnRunJSContext.js +78 -0
  118. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.d.ts +16 -0
  119. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +125 -0
  120. package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +1 -6
  121. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +28 -24
  122. package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +1 -6
  123. package/lib/runjs-context/contexts/JSItemRunJSContext.js +34 -20
  124. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +1 -2
  125. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +16 -17
  126. package/lib/runjs-context/contexts/base.d.ts +9 -0
  127. package/lib/runjs-context/contexts/base.js +879 -0
  128. package/lib/runjs-context/contributions.d.ts +33 -0
  129. package/lib/runjs-context/contributions.js +88 -0
  130. package/lib/runjs-context/helpers.d.ts +5 -2
  131. package/lib/runjs-context/helpers.js +36 -27
  132. package/lib/runjs-context/registry.d.ts +7 -4
  133. package/lib/runjs-context/registry.js +10 -42
  134. package/lib/runjs-context/setup.d.ts +9 -0
  135. package/lib/runjs-context/setup.js +88 -0
  136. package/lib/runjs-context/snippets/global/{copy-record-json.snippet.js → api-request.snippet.js} +25 -10
  137. package/lib/runjs-context/snippets/global/clipboard-copy-text.snippet.js +61 -0
  138. package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.js → import-esm.snippet.js} +26 -12
  139. package/lib/runjs-context/snippets/global/message-error.snippet.js +6 -0
  140. package/lib/runjs-context/snippets/global/message-success.snippet.js +6 -0
  141. package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +3 -8
  142. package/lib/runjs-context/snippets/global/notification-open.snippet.js +8 -1
  143. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +10 -3
  144. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +10 -3
  145. package/lib/runjs-context/snippets/global/query-selector.snippet.js +53 -0
  146. package/lib/runjs-context/snippets/global/require-amd.snippet.d.ts +11 -0
  147. package/lib/runjs-context/snippets/global/{requireAsync.snippet.js → require-amd.snippet.js} +16 -13
  148. package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +3 -8
  149. package/lib/runjs-context/snippets/global/window-open.snippet.js +8 -1
  150. package/lib/runjs-context/snippets/index.d.ts +24 -3
  151. package/lib/runjs-context/snippets/index.js +183 -40
  152. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.d.ts +11 -0
  153. package/lib/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.js +11 -2
  154. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.d.ts +11 -0
  155. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +64 -0
  156. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.d.ts +11 -0
  157. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +99 -0
  158. package/lib/runjs-context/snippets/{libs → scene/block}/echarts-init.snippet.js +24 -7
  159. package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.d.ts +11 -0
  160. package/lib/runjs-context/snippets/scene/block/render-antd-icons.snippet.js +65 -0
  161. package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.d.ts +11 -0
  162. package/lib/runjs-context/snippets/scene/{jsblock → block}/render-button-handler.snippet.js +17 -9
  163. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.d.ts +11 -0
  164. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +57 -0
  165. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.d.ts +11 -0
  166. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.js +71 -0
  167. package/lib/runjs-context/snippets/scene/block/render-react-jsx.snippet.d.ts +11 -0
  168. package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.js → block/render-react-jsx.snippet.js} +26 -13
  169. package/lib/runjs-context/snippets/scene/block/render-react.snippet.d.ts +11 -0
  170. package/lib/runjs-context/snippets/scene/{jsblock → block}/render-react.snippet.js +18 -17
  171. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.d.ts +11 -0
  172. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +95 -0
  173. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.d.ts +11 -0
  174. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +84 -0
  175. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.d.ts +11 -0
  176. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +60 -0
  177. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.d.ts +11 -0
  178. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +283 -0
  179. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.d.ts +11 -0
  180. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +124 -0
  181. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.d.ts +11 -0
  182. package/lib/runjs-context/snippets/scene/{jsfield → detail}/color-by-value.snippet.js +13 -3
  183. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.d.ts +11 -0
  184. package/lib/runjs-context/snippets/{global → scene/detail}/copy-to-clipboard.snippet.js +28 -6
  185. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.d.ts +11 -0
  186. package/lib/runjs-context/snippets/scene/{jsfield → detail}/format-number.snippet.js +13 -3
  187. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.d.ts +11 -0
  188. package/lib/runjs-context/snippets/scene/{jsfield → detail}/innerHTML-value.snippet.js +13 -3
  189. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.d.ts +11 -0
  190. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +82 -0
  191. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.d.ts +11 -0
  192. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +80 -0
  193. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.d.ts +11 -0
  194. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +74 -0
  195. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.d.ts +11 -0
  196. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.js +63 -0
  197. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.d.ts +11 -0
  198. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +81 -0
  199. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.d.ts +11 -0
  200. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.js +64 -0
  201. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.d.ts +11 -0
  202. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.js +74 -0
  203. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.d.ts +11 -0
  204. package/lib/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.js +11 -2
  205. package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.d.ts +11 -0
  206. package/lib/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.js +12 -3
  207. package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.d.ts +11 -0
  208. package/lib/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.js +12 -3
  209. package/lib/runjs-context/snippets/scene/form/set-required.snippet.d.ts +11 -0
  210. package/lib/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.js +12 -3
  211. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.d.ts +11 -0
  212. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.js +67 -0
  213. package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.d.ts +11 -0
  214. package/lib/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.js +12 -3
  215. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.d.ts +11 -0
  216. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +64 -0
  217. package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.d.ts +11 -0
  218. package/lib/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.js +11 -2
  219. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.d.ts +11 -0
  220. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +79 -0
  221. package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.d.ts +11 -0
  222. package/lib/runjs-context/snippets/{global/log-json-record.snippet.js → scene/table/destroy-selected.snippet.js} +24 -11
  223. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.d.ts +11 -0
  224. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.js +64 -0
  225. package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.d.ts +11 -0
  226. package/lib/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.js +11 -2
  227. package/lib/runjs-context/snippets/types.d.ts +9 -1
  228. package/lib/runjsLibs.d.ts +28 -0
  229. package/lib/runjsLibs.js +532 -0
  230. package/lib/scheduler/ModelOperationScheduler.d.ts +53 -0
  231. package/lib/scheduler/ModelOperationScheduler.js +262 -0
  232. package/lib/types.d.ts +66 -7
  233. package/lib/types.js +4 -3
  234. package/lib/utils/associationObjectVariable.d.ts +32 -0
  235. package/lib/utils/associationObjectVariable.js +157 -0
  236. package/lib/utils/createCollectionContextMeta.d.ts +1 -1
  237. package/lib/utils/createCollectionContextMeta.js +9 -4
  238. package/lib/utils/createEphemeralContext.d.ts +13 -0
  239. package/lib/utils/createEphemeralContext.js +140 -0
  240. package/lib/utils/flows.d.ts +10 -0
  241. package/lib/{runjs-context/snippets/global/console-log-ctx.snippet.js → utils/flows.js} +21 -14
  242. package/lib/utils/index.d.ts +9 -3
  243. package/lib/utils/index.js +30 -2
  244. package/lib/utils/jsxTransform.d.ts +15 -0
  245. package/lib/utils/jsxTransform.js +68 -0
  246. package/lib/utils/params-resolvers.js +19 -12
  247. package/lib/utils/parsePathnameToViewParams.d.ts +1 -1
  248. package/lib/utils/parsePathnameToViewParams.js +41 -5
  249. package/lib/utils/pruneFilter.d.ts +21 -0
  250. package/lib/{runjs-context/snippets/global/try-catch-async.snippet.js → utils/pruneFilter.js} +24 -16
  251. package/lib/utils/resolveModuleUrl.d.ts +58 -0
  252. package/lib/utils/resolveModuleUrl.js +65 -0
  253. package/lib/utils/runjsModuleLoader.d.ts +58 -0
  254. package/lib/utils/runjsModuleLoader.js +422 -0
  255. package/lib/utils/runjsTemplateCompat.d.ts +35 -0
  256. package/lib/utils/runjsTemplateCompat.js +743 -0
  257. package/lib/utils/safeGlobals.d.ts +6 -8
  258. package/lib/utils/safeGlobals.js +169 -14
  259. package/lib/utils/schema-utils.d.ts +6 -0
  260. package/lib/utils/schema-utils.js +71 -6
  261. package/lib/utils/serverContextParams.d.ts +4 -0
  262. package/lib/utils/serverContextParams.js +2 -0
  263. package/lib/utils/translation.d.ts +4 -1
  264. package/lib/utils/translation.js +6 -2
  265. package/lib/utils/variablesParams.d.ts +22 -5
  266. package/lib/utils/variablesParams.js +141 -61
  267. package/lib/views/DialogComponent.js +1 -5
  268. package/lib/views/DrawerComponent.js +18 -9
  269. package/lib/views/PageComponent.js +5 -5
  270. package/lib/views/ViewNavigation.d.ts +11 -15
  271. package/lib/views/ViewNavigation.js +37 -19
  272. package/lib/views/createViewMeta.d.ts +27 -5
  273. package/lib/views/createViewMeta.js +338 -72
  274. package/lib/views/index.d.ts +1 -1
  275. package/lib/views/index.js +4 -0
  276. package/lib/views/useDialog.d.ts +10 -9
  277. package/lib/views/useDialog.js +46 -34
  278. package/lib/views/useDrawer.d.ts +10 -9
  279. package/lib/views/useDrawer.js +74 -48
  280. package/lib/views/usePage.d.ts +14 -9
  281. package/lib/views/usePage.js +82 -33
  282. package/lib/views/usePopover.js +4 -1
  283. package/lib/views/viewEvents.d.ts +17 -0
  284. package/lib/views/viewEvents.js +90 -0
  285. package/package.json +6 -3
  286. package/src/BlockScopedFlowEngine.ts +85 -0
  287. package/src/FlowContextProvider.tsx +4 -2
  288. package/src/JSRunner.ts +39 -1
  289. package/src/ViewScopedFlowEngine.ts +21 -1
  290. package/src/__tests__/JSRunner.test.ts +125 -52
  291. package/src/__tests__/blockScopedFlowEngine.test.ts +154 -0
  292. package/src/__tests__/createViewMeta.popup.test.ts +203 -0
  293. package/src/__tests__/flow-engine.test.ts +3 -0
  294. package/src/__tests__/flowContext.test.ts +160 -0
  295. package/src/__tests__/flowContextCreateJSRunner.test.ts +163 -0
  296. package/src/__tests__/flowEngine.dataSourceDirty.test.ts +63 -0
  297. package/src/__tests__/flowEngine.destroyModel.test.ts +74 -0
  298. package/src/__tests__/flowEngine.moveModel.test.ts +43 -0
  299. package/src/__tests__/flowEngine.removeModel.test.ts +72 -0
  300. package/src/__tests__/flowEngine.saveModel.test.ts +4 -0
  301. package/src/__tests__/flowModel.openView.navigation.test.ts +31 -2
  302. package/src/__tests__/flowRunJSContextDefine.test.ts +508 -0
  303. package/src/__tests__/flowSettings.open.test.tsx +71 -15
  304. package/src/__tests__/flowSettings.test.ts +2 -0
  305. package/src/__tests__/globalFlowRegistry.test.ts +1 -1
  306. package/src/__tests__/modelOperationScheduler.test.ts +346 -0
  307. package/src/__tests__/objectVariable.test.ts +464 -0
  308. package/src/__tests__/provider.test.tsx +0 -5
  309. package/src/__tests__/runjsContext.test.ts +219 -35
  310. package/src/__tests__/runjsContextImplementations.test.ts +217 -0
  311. package/src/__tests__/runjsContextRuntime.test.ts +269 -0
  312. package/src/__tests__/runjsEdgeCases.test.ts +281 -0
  313. package/src/__tests__/runjsExternalLibs.test.ts +242 -0
  314. package/src/__tests__/runjsLibsLazyLoading.test.ts +44 -0
  315. package/src/__tests__/runjsLocales.test.ts +39 -0
  316. package/src/__tests__/runjsPreprocessDefault.test.ts +49 -0
  317. package/src/__tests__/runjsRuntimeFeatures.test.ts +461 -0
  318. package/src/__tests__/runjsSnippets.test.ts +140 -0
  319. package/src/__tests__/viewScopedFlowEngine.test.ts +101 -3
  320. package/src/acl/Acl.tsx +85 -31
  321. package/src/acl/__tests__/Acl.test.tsx +43 -1
  322. package/src/components/DynamicFlowsEditor.tsx +0 -10
  323. package/src/components/FieldModelRenderer.tsx +22 -9
  324. package/src/components/FieldSkeleton.tsx +27 -0
  325. package/src/components/FlowContextSelector.tsx +20 -2
  326. package/src/components/FlowModelRenderer.tsx +52 -84
  327. package/src/components/FormItem.tsx +8 -1
  328. package/src/components/MobilePopup.style.ts +220 -0
  329. package/src/components/MobilePopup.tsx +86 -0
  330. package/src/components/__tests__/FlowModelRenderer.test.tsx +89 -0
  331. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +6 -6
  332. package/src/components/__tests__/gridDragPlanner.test.ts +141 -1
  333. package/src/components/common/withFlowDesignMode.tsx +5 -5
  334. package/src/components/dnd/gridDragPlanner.ts +60 -0
  335. package/src/components/index.ts +1 -0
  336. package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +34 -17
  337. package/src/components/settings/wrappers/component/SelectWithTitle.tsx +110 -0
  338. package/src/components/settings/wrappers/component/SwitchWithTitle.tsx +83 -0
  339. package/src/components/settings/wrappers/component/__tests__/InlineControls.test.tsx +74 -0
  340. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +272 -125
  341. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +34 -18
  342. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +56 -18
  343. package/src/components/settings/wrappers/contextual/StepSettings.tsx +1 -2
  344. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +13 -1
  345. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +624 -0
  346. package/src/components/settings/wrappers/embedded/FlowSettings.tsx +47 -35
  347. package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +1 -1
  348. package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +64 -42
  349. package/src/components/subModel/AddSubModelButton.tsx +104 -9
  350. package/src/components/subModel/LazyDropdown.tsx +14 -14
  351. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +168 -7
  352. package/src/components/subModel/__tests__/utils.test.ts +12 -12
  353. package/src/components/subModel/utils.ts +25 -6
  354. package/src/components/variables/VariableInput.tsx +32 -6
  355. package/src/components/variables/VariableTag.tsx +54 -2
  356. package/src/components/variables/types.ts +2 -0
  357. package/src/components/variables/utils.ts +7 -3
  358. package/src/data-source/index.ts +143 -12
  359. package/src/data-source/jioToJoiSchema.ts +1 -0
  360. package/src/emitter.ts +14 -0
  361. package/src/executor/FlowExecutor.ts +383 -119
  362. package/src/executor/__tests__/ctx-defs-injection.test.ts +197 -0
  363. package/src/executor/__tests__/flowExecutor.test.ts +217 -5
  364. package/src/flow-registry/GlobalFlowRegistry.ts +1 -0
  365. package/src/flow-registry/InstanceFlowRegistry.ts +1 -0
  366. package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +54 -0
  367. package/src/flowContext.ts +646 -158
  368. package/src/flowEngine.ts +385 -14
  369. package/src/flowSettings.ts +59 -30
  370. package/src/hooks/useApplyAutoFlows.ts +5 -3
  371. package/src/index.ts +26 -3
  372. package/src/locale/de-DE.json +62 -0
  373. package/src/locale/en-US.json +57 -45
  374. package/src/locale/es-ES.json +62 -0
  375. package/src/locale/fr-FR.json +62 -0
  376. package/src/locale/hu-HU.json +62 -0
  377. package/src/locale/id-ID.json +62 -0
  378. package/src/locale/it-IT.json +62 -0
  379. package/src/locale/ja-JP.json +62 -0
  380. package/src/locale/ko-KR.json +62 -0
  381. package/src/locale/nl-NL.json +62 -0
  382. package/src/locale/pt-BR.json +62 -0
  383. package/src/locale/ru-RU.json +62 -0
  384. package/src/locale/tr-TR.json +62 -0
  385. package/src/locale/uk-UA.json +62 -0
  386. package/src/locale/vi-VN.json +62 -0
  387. package/src/locale/zh-CN.json +58 -46
  388. package/src/locale/zh-TW.json +62 -0
  389. package/src/models/CollectionFieldModel.tsx +82 -18
  390. package/src/models/__tests__/dispatchEvent.behavior.test.ts +169 -0
  391. package/src/models/__tests__/dispatchEvent.when.test.ts +356 -0
  392. package/src/models/__tests__/flowEngine.resolveUse.test.ts +170 -0
  393. package/src/models/__tests__/flowModel.clone.test.ts +416 -0
  394. package/src/models/__tests__/flowModel.getFlows.sort.test.ts +33 -9
  395. package/src/models/__tests__/flowModel.scheduleModelOperation.test.tsx +129 -0
  396. package/src/models/__tests__/flowModel.test.ts +296 -119
  397. package/src/models/__tests__/forkFlowModel.test.ts +40 -7
  398. package/src/models/flowModel.tsx +426 -148
  399. package/src/models/forkFlowModel.ts +48 -8
  400. package/src/provider.tsx +18 -14
  401. package/src/reactive/__tests__/observer.test.tsx +211 -0
  402. package/src/reactive/index.ts +11 -0
  403. package/src/reactive/observer.tsx +101 -0
  404. package/src/resources/__tests__/multiRecordResource.test.ts +44 -0
  405. package/src/resources/__tests__/sqlResource.test.ts +60 -0
  406. package/src/resources/baseRecordResource.ts +46 -3
  407. package/src/resources/multiRecordResource.ts +28 -12
  408. package/src/resources/singleRecordResource.ts +9 -3
  409. package/src/resources/sqlResource.ts +33 -32
  410. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +38 -21
  411. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +50 -34
  412. package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +15 -16
  413. package/src/runjs-context/contexts/JSColumnRunJSContext.ts +58 -0
  414. package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +106 -0
  415. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +30 -25
  416. package/src/runjs-context/contexts/JSItemRunJSContext.ts +35 -21
  417. package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +17 -18
  418. package/src/runjs-context/contexts/base.ts +871 -0
  419. package/src/runjs-context/contributions.ts +88 -0
  420. package/src/runjs-context/helpers.ts +32 -30
  421. package/src/runjs-context/registry.ts +16 -47
  422. package/src/runjs-context/setup.ts +57 -0
  423. package/src/runjs-context/snippets/global/api-request.snippet.ts +38 -0
  424. package/src/runjs-context/snippets/global/clipboard-copy-text.snippet.ts +42 -0
  425. package/src/runjs-context/snippets/global/import-esm.snippet.ts +39 -0
  426. package/src/runjs-context/snippets/global/message-error.snippet.ts +6 -0
  427. package/src/runjs-context/snippets/global/message-success.snippet.ts +6 -0
  428. package/src/runjs-context/snippets/global/notification-open.snippet.ts +11 -1
  429. package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +10 -3
  430. package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +10 -3
  431. package/src/runjs-context/snippets/global/query-selector.snippet.ts +34 -0
  432. package/src/runjs-context/snippets/global/require-amd.snippet.ts +30 -0
  433. package/src/runjs-context/snippets/global/window-open.snippet.ts +11 -1
  434. package/src/runjs-context/snippets/index.ts +212 -39
  435. package/src/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.ts +14 -2
  436. package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +45 -0
  437. package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +80 -0
  438. package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +44 -0
  439. package/src/runjs-context/snippets/scene/block/render-antd-icons.snippet.ts +46 -0
  440. package/src/runjs-context/snippets/scene/block/render-button-handler.snippet.ts +35 -0
  441. package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +38 -0
  442. package/src/runjs-context/snippets/scene/block/render-info-card.snippet.ts +52 -0
  443. package/src/runjs-context/snippets/scene/block/render-react-jsx.snippet.ts +39 -0
  444. package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +38 -0
  445. package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +76 -0
  446. package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +65 -0
  447. package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +46 -0
  448. package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +264 -0
  449. package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +105 -0
  450. package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +33 -0
  451. package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +45 -0
  452. package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +32 -0
  453. package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +31 -0
  454. package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +63 -0
  455. package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +61 -0
  456. package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +55 -0
  457. package/src/runjs-context/snippets/scene/form/calculate-total.snippet.ts +44 -0
  458. package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +62 -0
  459. package/src/runjs-context/snippets/scene/form/conditional-required.snippet.ts +45 -0
  460. package/src/runjs-context/snippets/scene/form/copy-field-values.snippet.ts +55 -0
  461. package/src/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.ts +14 -2
  462. package/src/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.ts +15 -3
  463. package/src/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.ts +15 -3
  464. package/src/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.ts +15 -3
  465. package/src/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.ts +48 -0
  466. package/src/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.ts +15 -3
  467. package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +45 -0
  468. package/src/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.ts +14 -2
  469. package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +60 -0
  470. package/src/runjs-context/snippets/scene/table/destroy-selected.snippet.ts +36 -0
  471. package/src/runjs-context/snippets/scene/table/export-selected-json.snippet.ts +45 -0
  472. package/src/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.ts +14 -2
  473. package/src/runjs-context/snippets/types.ts +5 -1
  474. package/src/runjsLibs.ts +622 -0
  475. package/src/scheduler/ModelOperationScheduler.ts +306 -0
  476. package/src/types.ts +86 -5
  477. package/src/utils/__tests__/createCollectionContextMeta.test.ts +51 -0
  478. package/src/utils/__tests__/flows.test.ts +65 -0
  479. package/src/utils/__tests__/jsxTransform.test.ts +38 -0
  480. package/src/utils/__tests__/params-resolvers.test.ts +40 -0
  481. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +25 -0
  482. package/src/utils/__tests__/pruneFilter.test.ts +38 -0
  483. package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +38 -0
  484. package/src/utils/__tests__/runjsTemplateCompat.test.ts +159 -0
  485. package/src/utils/__tests__/safeGlobals.test.ts +79 -2
  486. package/src/utils/__tests__/utils.test.ts +114 -15
  487. package/src/utils/__tests__/variablesParams.test.ts +120 -0
  488. package/src/utils/associationObjectVariable.ts +180 -0
  489. package/src/utils/createCollectionContextMeta.ts +9 -3
  490. package/src/utils/createEphemeralContext.ts +142 -0
  491. package/src/utils/flows.ts +23 -0
  492. package/src/utils/index.ts +17 -3
  493. package/src/utils/jsxTransform.ts +39 -0
  494. package/src/utils/params-resolvers.ts +25 -11
  495. package/src/utils/parsePathnameToViewParams.ts +50 -6
  496. package/src/utils/pruneFilter.ts +41 -0
  497. package/src/utils/resolveModuleUrl.ts +91 -0
  498. package/src/utils/runjsModuleLoader.ts +553 -0
  499. package/src/utils/runjsTemplateCompat.ts +828 -0
  500. package/src/utils/safeGlobals.ts +181 -15
  501. package/src/utils/schema-utils.ts +81 -3
  502. package/src/utils/serverContextParams.ts +6 -0
  503. package/src/utils/translation.ts +7 -2
  504. package/src/utils/variablesParams.ts +164 -72
  505. package/src/views/DialogComponent.tsx +1 -4
  506. package/src/views/DrawerComponent.tsx +19 -7
  507. package/src/views/PageComponent.tsx +3 -5
  508. package/src/views/ViewNavigation.ts +49 -43
  509. package/src/views/__tests__/FlowView.usePage.test.tsx +186 -0
  510. package/src/views/__tests__/ViewNavigation.test.ts +54 -34
  511. package/src/views/__tests__/useDialog.closeDestroy.test.tsx +159 -0
  512. package/src/views/__tests__/viewEvents.resolveOpenerEngine.test.ts +28 -0
  513. package/src/views/createViewMeta.ts +402 -73
  514. package/src/views/index.tsx +1 -1
  515. package/src/views/useDialog.tsx +52 -31
  516. package/src/views/useDrawer.tsx +99 -55
  517. package/src/views/usePage.tsx +101 -33
  518. package/src/views/usePopover.tsx +4 -1
  519. package/src/views/viewEvents.ts +55 -0
  520. package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +0 -38
  521. package/lib/runjs-context/contexts/FlowRunJSContext.js +0 -217
  522. package/lib/runjs-context/contexts/LinkageRunJSContext.js +0 -62
  523. package/lib/runjs-context/index.d.ts +0 -19
  524. package/lib/runjs-context/index.js +0 -57
  525. package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +0 -16
  526. package/lib/runjs-context/snippets/global/api-request-get.snippet.js +0 -42
  527. package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +0 -16
  528. package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +0 -16
  529. package/lib/runjs-context/snippets/global/requireAsync.snippet.d.ts +0 -16
  530. package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +0 -16
  531. package/lib/runjs-context/snippets/global/sleep.snippet.js +0 -43
  532. package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +0 -16
  533. package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +0 -15
  534. package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +0 -15
  535. package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +0 -15
  536. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +0 -15
  537. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +0 -43
  538. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +0 -15
  539. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +0 -40
  540. package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +0 -15
  541. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +0 -15
  542. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +0 -42
  543. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +0 -15
  544. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js +0 -46
  545. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +0 -15
  546. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +0 -41
  547. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +0 -15
  548. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +0 -41
  549. package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +0 -15
  550. package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +0 -15
  551. package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +0 -15
  552. package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +0 -15
  553. package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +0 -15
  554. package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +0 -15
  555. package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +0 -15
  556. package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +0 -15
  557. package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +0 -15
  558. package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +0 -15
  559. package/src/runjs-context/contexts/FlowRunJSContext.ts +0 -190
  560. package/src/runjs-context/contexts/LinkageRunJSContext.ts +0 -35
  561. package/src/runjs-context/index.ts +0 -20
  562. package/src/runjs-context/snippets/global/api-request-get.snippet.ts +0 -20
  563. package/src/runjs-context/snippets/global/api-request-post.snippet.ts +0 -20
  564. package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +0 -19
  565. package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +0 -21
  566. package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +0 -21
  567. package/src/runjs-context/snippets/global/log-json-record.snippet.ts +0 -21
  568. package/src/runjs-context/snippets/global/requireAsync.snippet.ts +0 -24
  569. package/src/runjs-context/snippets/global/sleep.snippet.ts +0 -21
  570. package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +0 -22
  571. package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +0 -23
  572. package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +0 -24
  573. package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +0 -21
  574. package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +0 -18
  575. package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +0 -20
  576. package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +0 -24
  577. package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +0 -19
  578. package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +0 -24
  579. package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +0 -24
  580. package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +0 -30
  581. package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +0 -34
  582. package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +0 -20
  583. package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +0 -19
  584. package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +0 -18
  585. /package/lib/runjs-context/snippets/global/{copy-record-json.snippet.d.ts → api-request.snippet.d.ts} +0 -0
  586. /package/lib/runjs-context/snippets/global/{copy-to-clipboard.snippet.d.ts → clipboard-copy-text.snippet.d.ts} +0 -0
  587. /package/lib/runjs-context/snippets/global/{log-json-record.snippet.d.ts → import-esm.snippet.d.ts} +0 -0
  588. /package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.d.ts → query-selector.snippet.d.ts} +0 -0
  589. /package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.d.ts → block/echarts-init.snippet.d.ts} +0 -0
@@ -12,6 +12,7 @@ import { FlowForkModelContext, FlowModelContext } from '../flowContext';
12
12
  import type { IModelComponentProps } from '../types';
13
13
  import { FlowModel } from './flowModel';
14
14
  import { FlowEngine } from '../flowEngine';
15
+ import { uid } from 'uid/secure';
15
16
 
16
17
  /**
17
18
  * ForkFlowModel 作为 FlowModel 的独立实例:
@@ -38,7 +39,7 @@ export class ForkFlowModel<TMaster extends FlowModel = FlowModel> {
38
39
  private disposed = false;
39
40
 
40
41
  /** fork 在 master.forks 中的索引 */
41
- public readonly forkId: number;
42
+ public readonly forkId: string;
42
43
 
43
44
  /** 需要与 master 共享的属性列表 */
44
45
  private static readonly SHARED_PROPERTIES = ['stepParams', 'sortIndex'];
@@ -67,12 +68,12 @@ export class ForkFlowModel<TMaster extends FlowModel = FlowModel> {
67
68
  // 不需要定义自己的属性了,现在是SHARED_PROPERTIES中指定的少数几个属性,所有属性设置时会自动添加自己的fork内的独有属性
68
69
  #flowContext: FlowModelContext;
69
70
 
70
- constructor(master: TMaster, initialProps: IModelComponentProps = {}, forkId = 0) {
71
+ constructor(master: TMaster, initialProps: IModelComponentProps = {}, forkId?: string) {
71
72
  void this.localProperties; // 避免 IDE 提示 unused
72
73
  this.master = master;
73
74
  this.uid = master.uid;
74
75
  this.localProps = { ...initialProps };
75
- this.forkId = forkId;
76
+ this.forkId = forkId || uid();
76
77
  this.hidden = this.master.hidden;
77
78
 
78
79
  define(this, {
@@ -206,6 +207,13 @@ export class ForkFlowModel<TMaster extends FlowModel = FlowModel> {
206
207
  }
207
208
  }
208
209
 
210
+ /**
211
+ * 清理局部 props,仅影响当前 fork
212
+ */
213
+ clearProps() {
214
+ return (this.localProps = {});
215
+ }
216
+
209
217
  /**
210
218
  * render 依旧使用 master 的方法,但合并后的 props 需要透传
211
219
  */
@@ -224,10 +232,10 @@ export class ForkFlowModel<TMaster extends FlowModel = FlowModel> {
224
232
  }
225
233
 
226
234
  /**
227
- * 自动流程缓存的作用域标识(fork 专用)。
235
+ * 事件缓存的作用域标识(fork 专用)。
228
236
  */
229
- public getAutoFlowCacheScope(): string {
230
- return String(this.forkId);
237
+ public getFlowCacheScope(eventName: string): string {
238
+ return `${String(eventName)}:${String(this.forkId)}`;
231
239
  }
232
240
 
233
241
  // onUnmount() {
@@ -250,9 +258,41 @@ export class ForkFlowModel<TMaster extends FlowModel = FlowModel> {
250
258
  dispose() {
251
259
  if (this.disposed) return;
252
260
  this.disposed = true;
261
+ // 统一按事件缓存命名规则清理当前 fork 的所有缓存项(覆盖所有事件)
262
+ try {
263
+ const cache = this.flowEngine?.applyFlowCache;
264
+ if (cache && cache.size > 0) {
265
+ const uidSuffixes = [`:${this.uid}`, `-${this.uid}`];
266
+ const forkIdColon = `:${this.forkId}:`;
267
+ const forkIdHyphen = `-${this.forkId}-`;
268
+
269
+ for (const key of cache.keys()) {
270
+ // 事件缓存统一以 event: 或 event- 开头
271
+ const isEventCache = key.startsWith('event:') || key.startsWith('event-');
272
+ if (!isEventCache) continue;
273
+
274
+ // 仅删除当前 fork + 当前 uid 的键
275
+ const endMatches = uidSuffixes.some((s) => key.endsWith(s));
276
+ if (!endMatches) continue;
277
+
278
+ // 限定在去除 uid 后缀的范围内匹配 forkId 片段,避免误伤
279
+ let trimmed = key;
280
+ for (const suf of uidSuffixes) {
281
+ if (trimmed.endsWith(suf)) {
282
+ trimmed = trimmed.slice(0, -suf.length);
283
+ break;
284
+ }
285
+ }
286
+ if (trimmed.includes(forkIdColon) || trimmed.includes(forkIdHyphen)) {
287
+ cache.delete(key);
288
+ }
289
+ }
290
+ }
291
+ } catch {
292
+ // 忽略清理阶段异常,避免影响后续释放
293
+ }
294
+
253
295
  if (this.master && (this.master as any).forks) {
254
- const forkCacheKey = FlowEngine.generateApplyFlowCacheKey(`${this.forkId}`, 'all', this.uid);
255
- this.flowEngine.applyFlowCache.delete(forkCacheKey);
256
296
  (this.master as any).forks.delete(this as any);
257
297
  }
258
298
  // 从 master 的 forkCache 中移除自己
package/src/provider.tsx CHANGED
@@ -22,7 +22,7 @@ interface FlowEngineProviderProps {
22
22
 
23
23
  const FlowEngineReactContext = createContext<FlowEngine | null>(null);
24
24
 
25
- export const FlowEngineProvider: React.FC<FlowEngineProviderProps> = (props) => {
25
+ export const FlowEngineProvider: React.FC<FlowEngineProviderProps> = React.memo((props) => {
26
26
  const { engine, children } = props;
27
27
  if (!engine) {
28
28
  throw new Error('FlowEngineProvider must be supplied with an engine.');
@@ -32,7 +32,9 @@ export const FlowEngineProvider: React.FC<FlowEngineProviderProps> = (props) =>
32
32
  <FlowContextProvider context={engine.context}>{children}</FlowContextProvider>
33
33
  </FlowEngineReactContext.Provider>
34
34
  );
35
- };
35
+ });
36
+
37
+ FlowEngineProvider.displayName = 'FlowEngineProvider';
36
38
 
37
39
  export const FlowEngineGlobalsContextProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
38
40
  const { modal, message, notification } = App.useApp();
@@ -56,41 +58,43 @@ export const FlowEngineGlobalsContextProvider: React.FC<{ children: React.ReactN
56
58
  cache: false,
57
59
  get: (ctx) => new FlowViewer(ctx, { drawer, embed, popover, dialog }),
58
60
  });
59
- // 将 themeToken 定义为 observable, 使组件能够响应主题的变更
60
- engine.context.defineProperty('themeToken', {
61
- get: () => token,
62
- observable: true,
63
- cache: true,
64
- });
65
61
  for (const item of Object.entries(context)) {
66
62
  const [key, value] = item;
67
63
  if (value) {
68
64
  engine.context.defineProperty(key, { value });
69
65
  }
70
66
  }
67
+ // 将 themeToken 定义为 observable, 使组件能够响应主题的变更
68
+ // NOTE: 必须在 antdConfig 写入后再更新 themeToken;否则会读取到旧 antdConfig 的值。
69
+ engine.context.defineProperty('themeToken', {
70
+ get: () => token,
71
+ observable: true,
72
+ cache: true,
73
+ });
71
74
  engine.reactView.refresh();
72
75
  }, [engine, drawer, modal, message, notification, config, popover, token, dialog, embed]);
73
76
 
74
77
  return (
75
- <>
78
+ <ConfigProvider {...config} locale={engine.context.locales?.antd} popupMatchSelectWidth={false}>
76
79
  {children}
77
80
  {contextHolder as any}
78
81
  {popoverContextHolder as any}
79
82
  {pageContextHolder as any}
80
83
  {dialogContextHolder as any}
81
84
  {/* The modal context is provided by App.useApp() */}
82
- </>
85
+ </ConfigProvider>
83
86
  );
84
87
  };
85
-
86
- export const useFlowEngine = (): FlowEngine => {
88
+ // 不 throw Error 怎么处理?
89
+ export const useFlowEngine = ({ throwError = true } = {}): FlowEngine => {
87
90
  const context = useContext(FlowEngineReactContext);
88
- if (!context) {
91
+ if (!context && throwError) {
89
92
  // This error should ideally not be hit if FlowEngineProvider is used correctly at the root
90
93
  // and always supplied with an engine.
91
- throw new Error(
94
+ console.warn(
92
95
  'useFlowEngine must be used within a FlowEngineProvider, and FlowEngineProvider must be supplied with an engine.',
93
96
  );
97
+ return;
94
98
  }
95
99
  return context;
96
100
  };
@@ -0,0 +1,211 @@
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 React from 'react';
11
+ import { render, screen, act } from '@testing-library/react';
12
+ import { observer } from '../observer';
13
+ import { useFlowContext } from '../../FlowContextProvider';
14
+ import { observable } from '@formily/reactive';
15
+ import { vi } from 'vitest';
16
+ import { sleep } from '@nocobase/test/client';
17
+
18
+ // Mock useFlowContext
19
+ vi.mock('../../FlowContextProvider', async () => {
20
+ const actual = await vi.importActual('../../FlowContextProvider');
21
+ return {
22
+ ...actual,
23
+ useFlowContext: vi.fn(),
24
+ };
25
+ });
26
+
27
+ describe('observer', () => {
28
+ beforeEach(() => {
29
+ (useFlowContext as any).mockReturnValue({});
30
+ });
31
+
32
+ afterEach(() => {
33
+ vi.clearAllMocks();
34
+ });
35
+
36
+ it('should render component', () => {
37
+ const Component = observer(() => <div>Hello World</div>);
38
+ render(<Component />);
39
+ expect(screen.getByText('Hello World')).toBeInTheDocument();
40
+ });
41
+
42
+ it('should update when observable changes', async () => {
43
+ const model = observable({ count: 0 });
44
+ const Component = observer(() => <div>Count: {model.count}</div>);
45
+ render(<Component />);
46
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
47
+
48
+ act(() => {
49
+ model.count++;
50
+ });
51
+ expect(screen.getByText('Count: 1')).toBeInTheDocument();
52
+ });
53
+
54
+ it('should delay update when pageActive is false', async () => {
55
+ const model = observable({ count: 0 });
56
+ const pageActive = observable.ref(false);
57
+ const tabActive = observable.ref(true);
58
+
59
+ const context = {
60
+ pageActive: pageActive,
61
+ tabActive: tabActive,
62
+ };
63
+
64
+ (useFlowContext as any).mockReturnValue(context);
65
+
66
+ const Component = observer(() => <div>Count: {model.count}</div>);
67
+
68
+ render(<Component />);
69
+
70
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
71
+
72
+ // Update model, but pageActive is false
73
+ act(() => {
74
+ model.count++;
75
+ });
76
+
77
+ await sleep(30);
78
+
79
+ // Should not update yet
80
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
81
+ expect(screen.queryByText('Count: 1')).not.toBeInTheDocument();
82
+
83
+ // Now make pageActive true
84
+ act(() => {
85
+ pageActive.value = true;
86
+ });
87
+
88
+ await sleep(30);
89
+
90
+ // Should update now
91
+ expect(screen.getByText('Count: 1')).toBeInTheDocument();
92
+ });
93
+
94
+ it('should delay update when tabActive is false', async () => {
95
+ const model = observable({ count: 0 });
96
+ const pageActive = observable.ref(true);
97
+ const tabActive = observable.ref(false);
98
+
99
+ const context = {
100
+ pageActive: pageActive,
101
+ tabActive: tabActive,
102
+ };
103
+
104
+ (useFlowContext as any).mockReturnValue(context);
105
+
106
+ const Component = observer(() => <div>Count: {model.count}</div>);
107
+
108
+ render(<Component />);
109
+
110
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
111
+
112
+ // Update model, but tabActive is false
113
+ act(() => {
114
+ model.count++;
115
+ });
116
+
117
+ await sleep(30);
118
+
119
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
120
+ expect(screen.queryByText('Count: 1')).not.toBeInTheDocument();
121
+
122
+ // Now make tabActive true
123
+ act(() => {
124
+ tabActive.value = true;
125
+ });
126
+
127
+ await sleep(30);
128
+
129
+ // Should update now
130
+ expect(screen.getByText('Count: 1')).toBeInTheDocument();
131
+ });
132
+
133
+ it('should update immediately when pageActive and tabActive are true', async () => {
134
+ const model = observable({ count: 0 });
135
+ const pageActive = observable.ref(true);
136
+ const tabActive = observable.ref(true);
137
+
138
+ const context = {
139
+ pageActive: pageActive,
140
+ tabActive: tabActive,
141
+ };
142
+
143
+ (useFlowContext as any).mockReturnValue(context);
144
+
145
+ const Component = observer(() => <div>Count: {model.count}</div>);
146
+
147
+ render(<Component />);
148
+
149
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
150
+
151
+ act(() => {
152
+ model.count++;
153
+ });
154
+
155
+ expect(screen.getByText('Count: 1')).toBeInTheDocument();
156
+ });
157
+
158
+ it('should handle undefined tabActive as true (backward compatibility or default)', async () => {
159
+ const model = observable({ count: 0 });
160
+ const pageActive = observable.ref(true);
161
+ // tabActive is undefined in context
162
+
163
+ const context = {
164
+ pageActive: pageActive,
165
+ };
166
+
167
+ (useFlowContext as any).mockReturnValue(context);
168
+
169
+ const Component = observer(() => <div>Count: {model.count}</div>);
170
+
171
+ render(<Component />);
172
+
173
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
174
+
175
+ act(() => {
176
+ model.count++;
177
+ });
178
+
179
+ await sleep(30);
180
+
181
+ expect(screen.getByText('Count: 1')).toBeInTheDocument();
182
+ });
183
+
184
+ it('should respect view inputArgs for initial check', async () => {
185
+ const model = observable({ count: 0 });
186
+
187
+ const context = {
188
+ view: {
189
+ inputArgs: { pageActive: false },
190
+ },
191
+ };
192
+
193
+ (useFlowContext as any).mockReturnValue(context);
194
+
195
+ const Component = observer(() => <div>Count: {model.count}</div>);
196
+
197
+ render(<Component />);
198
+
199
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
200
+
201
+ act(() => {
202
+ model.count++;
203
+ });
204
+
205
+ await sleep(30);
206
+
207
+ // Should NOT update because pageActive is false (from view.inputArgs)
208
+ expect(screen.getByText('Count: 0')).toBeInTheDocument();
209
+ expect(screen.queryByText('Count: 1')).not.toBeInTheDocument();
210
+ });
211
+ });
@@ -0,0 +1,11 @@
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
+ export * from '@formily/reactive';
11
+ export { observer, getPageActive } from './observer';
@@ -0,0 +1,101 @@
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 { observer as originalObserver, IObserverOptions, ReactFC } from '@formily/reactive-react';
11
+ import React, { useMemo, useEffect, useRef } from 'react';
12
+ import { useFlowContext } from '../FlowContextProvider';
13
+ import { autorun } from '@formily/reactive';
14
+ import { FlowEngineContext } from '..';
15
+
16
+ type ObserverComponentProps<P, Options extends IObserverOptions> = Options extends {
17
+ forwardRef: true;
18
+ }
19
+ ? P & {
20
+ ref?: 'ref' extends keyof P ? P['ref'] : React.RefAttributes<any>;
21
+ }
22
+ : React.PropsWithoutRef<P>;
23
+
24
+ export const observer = <P, Options extends IObserverOptions = IObserverOptions>(
25
+ Component: ReactFC<P>,
26
+ options?: Options,
27
+ ): React.MemoExoticComponent<ReactFC<ObserverComponentProps<P, Options>>> => {
28
+ const ComponentWithDefaultScheduler = React.memo((props: any) => {
29
+ const ctx = useFlowContext();
30
+ const ctxRef = useRef(ctx);
31
+ ctxRef.current = ctx;
32
+
33
+ // Store the pending disposer to avoid creating multiple listeners
34
+ const pendingDisposerRef = useRef<(() => void) | null>(null);
35
+
36
+ // Cleanup on unmount
37
+ useEffect(() => {
38
+ return () => {
39
+ if (pendingDisposerRef.current) {
40
+ pendingDisposerRef.current();
41
+ pendingDisposerRef.current = null;
42
+ }
43
+ };
44
+ }, []);
45
+
46
+ const ObservedComponent = useMemo(
47
+ () =>
48
+ originalObserver(Component, {
49
+ scheduler(updater) {
50
+ const pageActive = getPageActive(ctxRef.current);
51
+ const tabActive = ctxRef.current?.tabActive?.value;
52
+
53
+ if (pageActive === false || tabActive === false) {
54
+ // Avoid stack overflow
55
+ setTimeout(() => {
56
+ // If there is already a pending updater, do nothing
57
+ if (pendingDisposerRef.current) {
58
+ return;
59
+ }
60
+
61
+ // Delay the update until the page and tab become active
62
+ const disposer = autorun(() => {
63
+ if (
64
+ ctxRef.current?.pageActive?.value &&
65
+ (ctxRef.current?.tabActive?.value === true || ctxRef.current?.tabActive?.value === undefined)
66
+ ) {
67
+ updater();
68
+ disposer?.();
69
+ pendingDisposerRef.current = null;
70
+ }
71
+ });
72
+ pendingDisposerRef.current = disposer;
73
+ });
74
+ return;
75
+ }
76
+
77
+ // If we are updating immediately, clear any pending disposer
78
+ if (pendingDisposerRef.current) {
79
+ pendingDisposerRef.current();
80
+ pendingDisposerRef.current = null;
81
+ }
82
+
83
+ updater();
84
+ },
85
+ ...options,
86
+ }),
87
+ [],
88
+ );
89
+ return <ObservedComponent {...props} />;
90
+ });
91
+
92
+ ComponentWithDefaultScheduler.displayName = `ComponentWithDefaultScheduler`;
93
+
94
+ return ComponentWithDefaultScheduler as React.MemoExoticComponent<ReactFC<ObserverComponentProps<P, Options>>>;
95
+ };
96
+
97
+ export function getPageActive(context: FlowEngineContext): boolean | undefined {
98
+ return typeof context?.pageActive?.value === 'boolean'
99
+ ? context?.pageActive?.value
100
+ : context?.view?.inputArgs.pageActive;
101
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { describe, expect, it, vi } from 'vitest';
11
+ import { FlowEngine } from '../../flowEngine';
12
+ import { MultiRecordResource } from '../multiRecordResource';
13
+
14
+ function createMultiRecordResource() {
15
+ const engine = new FlowEngine();
16
+ return engine.createResource(MultiRecordResource);
17
+ }
18
+
19
+ describe('MultiRecordResource - refresh', () => {
20
+ it('should coalesce multiple refresh calls and settle all awaiters', async () => {
21
+ vi.useFakeTimers();
22
+ try {
23
+ const r = createMultiRecordResource();
24
+ const api = {
25
+ request: vi.fn().mockResolvedValue({
26
+ data: { data: [], meta: { count: 0, page: 1, pageSize: 20 } },
27
+ }),
28
+ };
29
+
30
+ r.setAPIClient(api as any);
31
+ r.setResourceName('posts');
32
+
33
+ const p1 = r.refresh();
34
+ const p2 = r.refresh();
35
+
36
+ await vi.runAllTimersAsync();
37
+ await expect(p1).resolves.toBeUndefined();
38
+ await expect(p2).resolves.toBeUndefined();
39
+ expect(api.request).toHaveBeenCalledTimes(1);
40
+ } finally {
41
+ vi.useRealTimers();
42
+ }
43
+ });
44
+ });
@@ -0,0 +1,60 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { describe, expect, it, vi } from 'vitest';
11
+ import { FlowEngine } from '../../flowEngine';
12
+ import { SQLResource } from '../sqlResource';
13
+
14
+ function createSQLResource() {
15
+ const engine = new FlowEngine();
16
+ return engine.createResource(SQLResource);
17
+ }
18
+
19
+ describe('SQLResource - refresh', () => {
20
+ it('should coalesce multiple refresh calls and settle all awaiters', async () => {
21
+ vi.useFakeTimers();
22
+ try {
23
+ const r = createSQLResource();
24
+ const run = vi.fn().mockResolvedValue({ data: { ok: 1 }, meta: { page: 1 } });
25
+ (r as any).run = run;
26
+
27
+ const p1 = r.refresh();
28
+ const p2 = r.refresh();
29
+
30
+ await vi.runAllTimersAsync();
31
+ await expect(p1).resolves.toBeUndefined();
32
+ await expect(p2).resolves.toBeUndefined();
33
+ expect(run).toHaveBeenCalledTimes(1);
34
+ } finally {
35
+ vi.useRealTimers();
36
+ }
37
+ });
38
+
39
+ it('should reject all awaiters on failure', async () => {
40
+ vi.useFakeTimers();
41
+ try {
42
+ const r = createSQLResource();
43
+ const run = vi.fn().mockRejectedValue(new Error('boom'));
44
+ (r as any).run = run;
45
+
46
+ const p1 = r.refresh();
47
+ const p2 = r.refresh();
48
+
49
+ // Attach handlers before timers run to avoid unhandled rejection warnings.
50
+ const e1 = expect(p1).rejects.toThrow('boom');
51
+ const e2 = expect(p2).rejects.toThrow('boom');
52
+ await vi.runAllTimersAsync();
53
+ await e1;
54
+ await e2;
55
+ expect(run).toHaveBeenCalledTimes(1);
56
+ } finally {
57
+ vi.useRealTimers();
58
+ }
59
+ });
60
+ });
@@ -12,6 +12,7 @@ import _ from 'lodash';
12
12
  import { APIResource } from './apiResource';
13
13
  import { FilterItem } from './filterItem';
14
14
  import { ResourceError } from './flowResource';
15
+ import { DATA_SOURCE_DIRTY_EVENT } from '../views/viewEvents';
15
16
 
16
17
  export abstract class BaseRecordResource<TData = any> extends APIResource<TData> {
17
18
  protected resourceName: string;
@@ -95,6 +96,7 @@ export abstract class BaseRecordResource<TData = any> extends APIResource<TData>
95
96
  }
96
97
 
97
98
  async runAction<TData = any, TMeta = any>(action: string, options: any) {
99
+ const { rawResponse, ...rest } = options;
98
100
  const config = this.mergeRequestConfig(
99
101
  _.omit(this.request, ['params', 'data', 'method']),
100
102
  {
@@ -102,14 +104,18 @@ export abstract class BaseRecordResource<TData = any> extends APIResource<TData>
102
104
  url: this.buildURL(action),
103
105
  },
104
106
  this.runActionOptions?.[action],
105
- options,
107
+ rest,
106
108
  );
107
109
  if (['create', 'update', 'firstOrCreate', 'updateOrCreate'].includes(action)) {
108
110
  config.params = config.params || {};
109
111
  config.params.updateAssociationValues = this.getUpdateAssociationValues();
110
112
  }
111
113
  try {
112
- const { data } = await this.api.request(config);
114
+ const response = await this.api.request(config);
115
+ if (rawResponse) {
116
+ return response;
117
+ }
118
+ const { data } = response;
113
119
  if (!data?.data) {
114
120
  return data;
115
121
  }
@@ -131,6 +137,36 @@ export abstract class BaseRecordResource<TData = any> extends APIResource<TData>
131
137
  return this.resourceName;
132
138
  }
133
139
 
140
+ /**
141
+ * Mark current resource as dirty on the root FlowEngine.
142
+ * Used to coordinate "refresh on active" across view stacks.
143
+ */
144
+ protected markDataSourceDirty(resourceName?: string) {
145
+ const engine = this.context.engine;
146
+ if (!engine) return;
147
+
148
+ const dataSourceKey = this.getDataSourceKey() || 'main';
149
+ const resName = resourceName || this.getResourceName();
150
+ if (!resName) return;
151
+
152
+ const affectedResourceNames = new Set<string>([String(resName)]);
153
+ // Optional safety: association resources like "users.profile" may impact parent collection views.
154
+ if (typeof resName === 'string' && resName.includes('.')) {
155
+ affectedResourceNames.add(resName.split('.')[0]);
156
+ }
157
+
158
+ for (const name of affectedResourceNames) {
159
+ engine.markDataSourceDirty(dataSourceKey, name);
160
+ }
161
+
162
+ // Signal current view to re-evaluate dirty blocks (e.g., same-view sibling refresh).
163
+ // This is emitted on the *current* engine emitter (view-scoped) so it won't affect other views.
164
+ engine.emitter?.emit?.(DATA_SOURCE_DIRTY_EVENT, {
165
+ dataSourceKey,
166
+ resourceNames: Array.from(affectedResourceNames),
167
+ });
168
+ }
169
+
134
170
  setSourceId(sourceId: string | number) {
135
171
  this.sourceId = sourceId;
136
172
  return this;
@@ -227,8 +263,15 @@ export abstract class BaseRecordResource<TData = any> extends APIResource<TData>
227
263
  return this;
228
264
  }
229
265
 
266
+ jsonStringify(value: any): string {
267
+ if (value !== null && typeof value === 'object') {
268
+ return JSON.stringify(value);
269
+ }
270
+ return value;
271
+ }
272
+
230
273
  setFilterByTk(filterByTk: any) {
231
- return this.addRequestParameter('filterByTk', filterByTk);
274
+ return this.addRequestParameter('filterByTk', this.jsonStringify(filterByTk));
232
275
  }
233
276
 
234
277
  getFilterByTk(): any {