@nocobase/flow-engine 2.0.0-beta.9 → 2.0.0

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 (245) hide show
  1. package/lib/BlockScopedFlowEngine.js +0 -1
  2. package/lib/FlowDefinition.d.ts +2 -0
  3. package/lib/JSRunner.d.ts +6 -0
  4. package/lib/JSRunner.js +32 -2
  5. package/lib/ViewScopedFlowEngine.js +3 -0
  6. package/lib/acl/Acl.js +13 -3
  7. package/lib/components/FlowContextSelector.js +155 -10
  8. package/lib/components/settings/wrappers/component/SwitchWithTitle.js +2 -1
  9. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +76 -15
  10. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +24 -4
  11. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +5 -1
  12. package/lib/components/variables/VariableInput.js +9 -4
  13. package/lib/components/variables/VariableTag.js +46 -39
  14. package/lib/components/variables/utils.d.ts +7 -0
  15. package/lib/components/variables/utils.js +42 -2
  16. package/lib/data-source/index.d.ts +7 -27
  17. package/lib/data-source/index.js +81 -51
  18. package/lib/executor/FlowExecutor.d.ts +2 -1
  19. package/lib/executor/FlowExecutor.js +163 -22
  20. package/lib/flowContext.d.ts +230 -7
  21. package/lib/flowContext.js +2267 -148
  22. package/lib/flowEngine.d.ts +21 -0
  23. package/lib/flowEngine.js +56 -8
  24. package/lib/flowI18n.js +6 -4
  25. package/lib/flowSettings.js +17 -11
  26. package/lib/index.d.ts +7 -1
  27. package/lib/index.js +21 -0
  28. package/lib/locale/en-US.json +9 -2
  29. package/lib/locale/index.d.ts +14 -0
  30. package/lib/locale/zh-CN.json +8 -1
  31. package/lib/models/CollectionFieldModel.d.ts +1 -0
  32. package/lib/models/CollectionFieldModel.js +3 -2
  33. package/lib/models/flowModel.js +12 -1
  34. package/lib/provider.js +5 -5
  35. package/lib/resources/baseRecordResource.d.ts +5 -0
  36. package/lib/resources/baseRecordResource.js +24 -0
  37. package/lib/resources/multiRecordResource.d.ts +1 -0
  38. package/lib/resources/multiRecordResource.js +11 -4
  39. package/lib/resources/singleRecordResource.js +2 -0
  40. package/lib/resources/sqlResource.d.ts +4 -3
  41. package/lib/resources/sqlResource.js +8 -3
  42. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +12 -2
  43. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +2 -2
  44. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.d.ts +16 -0
  45. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +125 -0
  46. package/lib/runjs-context/contexts/JSItemRunJSContext.js +12 -2
  47. package/lib/runjs-context/contexts/base.js +706 -41
  48. package/lib/runjs-context/contributions.d.ts +33 -0
  49. package/lib/runjs-context/contributions.js +88 -0
  50. package/lib/runjs-context/helpers.js +12 -1
  51. package/lib/runjs-context/setup.js +6 -0
  52. package/lib/runjs-context/snippets/global/api-request.snippet.js +3 -3
  53. package/lib/runjs-context/snippets/global/import-esm.snippet.js +2 -3
  54. package/lib/runjs-context/snippets/global/query-selector.snippet.js +8 -3
  55. package/lib/runjs-context/snippets/global/require-amd.snippet.js +1 -1
  56. package/lib/runjs-context/snippets/index.d.ts +11 -1
  57. package/lib/runjs-context/snippets/index.js +61 -40
  58. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.js +10 -7
  59. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +3 -3
  60. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +2 -2
  61. package/lib/runjs-context/snippets/scene/block/echarts-init.snippet.js +2 -2
  62. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +2 -2
  63. package/lib/runjs-context/snippets/scene/block/render-react.snippet.js +1 -1
  64. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +1 -1
  65. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +1 -1
  66. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +5 -5
  67. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +6 -6
  68. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +3 -4
  69. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.js +1 -1
  70. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.js +20 -3
  71. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.js +1 -1
  72. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.js +1 -1
  73. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +3 -3
  74. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +3 -3
  75. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +2 -2
  76. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +1 -1
  77. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.js +2 -2
  78. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +6 -3
  79. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +3 -1
  80. package/lib/runjsLibs.d.ts +28 -0
  81. package/lib/runjsLibs.js +532 -0
  82. package/lib/scheduler/ModelOperationScheduler.d.ts +2 -0
  83. package/lib/scheduler/ModelOperationScheduler.js +25 -21
  84. package/lib/types.d.ts +27 -0
  85. package/lib/utils/associationObjectVariable.d.ts +2 -2
  86. package/lib/utils/createCollectionContextMeta.js +1 -0
  87. package/lib/utils/createEphemeralContext.js +2 -2
  88. package/lib/utils/dateVariable.d.ts +16 -0
  89. package/lib/utils/dateVariable.js +380 -0
  90. package/lib/utils/exceptions.d.ts +7 -0
  91. package/lib/utils/exceptions.js +10 -0
  92. package/lib/utils/index.d.ts +8 -3
  93. package/lib/utils/index.js +45 -0
  94. package/lib/utils/params-resolvers.js +16 -9
  95. package/lib/utils/resolveModuleUrl.d.ts +58 -0
  96. package/lib/utils/resolveModuleUrl.js +65 -0
  97. package/lib/utils/resolveRunJSObjectValues.d.ts +16 -0
  98. package/lib/utils/resolveRunJSObjectValues.js +61 -0
  99. package/lib/utils/runjsModuleLoader.d.ts +58 -0
  100. package/lib/utils/runjsModuleLoader.js +422 -0
  101. package/lib/utils/runjsTemplateCompat.d.ts +35 -0
  102. package/lib/utils/runjsTemplateCompat.js +743 -0
  103. package/lib/utils/runjsValue.d.ts +29 -0
  104. package/lib/utils/runjsValue.js +275 -0
  105. package/lib/utils/safeGlobals.d.ts +18 -8
  106. package/lib/utils/safeGlobals.js +164 -17
  107. package/lib/utils/schema-utils.d.ts +10 -0
  108. package/lib/utils/schema-utils.js +61 -0
  109. package/lib/views/createViewMeta.d.ts +0 -7
  110. package/lib/views/createViewMeta.js +19 -70
  111. package/lib/views/index.d.ts +1 -2
  112. package/lib/views/index.js +4 -3
  113. package/lib/views/useDialog.js +7 -2
  114. package/lib/views/useDrawer.js +7 -2
  115. package/lib/views/usePage.d.ts +4 -0
  116. package/lib/views/usePage.js +43 -6
  117. package/lib/views/usePopover.js +4 -1
  118. package/lib/views/viewEvents.d.ts +17 -0
  119. package/lib/views/viewEvents.js +90 -0
  120. package/package.json +4 -4
  121. package/src/BlockScopedFlowEngine.ts +2 -5
  122. package/src/JSRunner.ts +44 -2
  123. package/src/ViewScopedFlowEngine.ts +4 -0
  124. package/src/__tests__/JSRunner.test.ts +64 -0
  125. package/src/__tests__/createViewMeta.popup.test.ts +62 -1
  126. package/src/__tests__/flowContext.test.ts +693 -1
  127. package/src/__tests__/flowEngine.dataSourceDirty.test.ts +63 -0
  128. package/src/__tests__/flowModel.openView.navigation.test.ts +28 -0
  129. package/src/__tests__/flowRunJSContextDefine.test.ts +63 -0
  130. package/src/__tests__/flowRuntimeContext.test.ts +2 -1
  131. package/src/__tests__/flowSettings.open.test.tsx +123 -19
  132. package/src/__tests__/runjsContext.test.ts +10 -7
  133. package/src/__tests__/runjsContextImplementations.test.ts +34 -3
  134. package/src/__tests__/runjsContextRuntime.test.ts +3 -3
  135. package/src/__tests__/runjsContributions.test.ts +89 -0
  136. package/src/__tests__/runjsExternalLibs.test.ts +242 -0
  137. package/src/__tests__/runjsLibsLazyLoading.test.ts +44 -0
  138. package/src/__tests__/runjsLocales.test.ts +4 -1
  139. package/src/__tests__/runjsPreprocessDefault.test.ts +49 -0
  140. package/src/__tests__/runjsRuntimeFeatures.test.ts +166 -0
  141. package/src/__tests__/runjsSnippets.test.ts +40 -3
  142. package/src/acl/Acl.tsx +3 -3
  143. package/src/components/FlowContextSelector.tsx +208 -12
  144. package/src/components/settings/wrappers/component/SwitchWithTitle.tsx +2 -1
  145. package/src/components/settings/wrappers/component/__tests__/InlineControls.test.tsx +74 -0
  146. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +109 -16
  147. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +41 -7
  148. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +13 -2
  149. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +157 -5
  150. package/src/components/variables/VariableInput.tsx +12 -4
  151. package/src/components/variables/VariableTag.tsx +54 -45
  152. package/src/components/variables/__tests__/FlowContextSelector.test.tsx +260 -3
  153. package/src/components/variables/__tests__/VariableTag.test.tsx +50 -0
  154. package/src/components/variables/__tests__/utils.test.ts +81 -3
  155. package/src/components/variables/utils.ts +67 -6
  156. package/src/data-source/index.ts +85 -110
  157. package/src/executor/FlowExecutor.ts +200 -23
  158. package/src/executor/__tests__/flowExecutor.test.ts +66 -0
  159. package/src/flowContext.ts +2986 -211
  160. package/src/flowEngine.ts +59 -8
  161. package/src/flowI18n.ts +7 -5
  162. package/src/flowSettings.ts +18 -12
  163. package/src/index.ts +14 -1
  164. package/src/locale/en-US.json +9 -2
  165. package/src/locale/zh-CN.json +8 -1
  166. package/src/models/CollectionFieldModel.tsx +3 -1
  167. package/src/models/__tests__/dispatchEvent.when.test.ts +554 -0
  168. package/src/models/__tests__/flowModel.test.ts +20 -4
  169. package/src/models/flowModel.tsx +13 -1
  170. package/src/provider.tsx +7 -6
  171. package/src/resources/__tests__/multiRecordResource.test.ts +44 -0
  172. package/src/resources/__tests__/sqlResource.test.ts +60 -0
  173. package/src/resources/baseRecordResource.ts +31 -0
  174. package/src/resources/multiRecordResource.ts +11 -4
  175. package/src/resources/singleRecordResource.ts +3 -0
  176. package/src/resources/sqlResource.ts +11 -6
  177. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +10 -0
  178. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +6 -2
  179. package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +106 -0
  180. package/src/runjs-context/contexts/JSItemRunJSContext.ts +10 -0
  181. package/src/runjs-context/contexts/base.ts +715 -44
  182. package/src/runjs-context/contributions.ts +88 -0
  183. package/src/runjs-context/helpers.ts +11 -1
  184. package/src/runjs-context/setup.ts +6 -0
  185. package/src/runjs-context/snippets/global/api-request.snippet.ts +3 -3
  186. package/src/runjs-context/snippets/global/import-esm.snippet.ts +2 -3
  187. package/src/runjs-context/snippets/global/query-selector.snippet.ts +8 -3
  188. package/src/runjs-context/snippets/global/require-amd.snippet.ts +1 -1
  189. package/src/runjs-context/snippets/index.ts +75 -41
  190. package/src/runjs-context/snippets/scene/block/add-event-listener.snippet.ts +11 -13
  191. package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +3 -3
  192. package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +2 -2
  193. package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +2 -2
  194. package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +2 -2
  195. package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +1 -1
  196. package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +1 -1
  197. package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +1 -1
  198. package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +6 -11
  199. package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +6 -6
  200. package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +3 -4
  201. package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +1 -1
  202. package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +20 -3
  203. package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +1 -1
  204. package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +1 -1
  205. package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +3 -3
  206. package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +3 -3
  207. package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +2 -2
  208. package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +1 -1
  209. package/src/runjs-context/snippets/scene/form/render-basic.snippet.ts +3 -8
  210. package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +6 -3
  211. package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +3 -1
  212. package/src/runjsLibs.ts +622 -0
  213. package/src/scheduler/ModelOperationScheduler.ts +27 -21
  214. package/src/types.ts +38 -1
  215. package/src/utils/__tests__/dateVariable.test.ts +101 -0
  216. package/src/utils/__tests__/params-resolvers.test.ts +40 -0
  217. package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +38 -0
  218. package/src/utils/__tests__/runjsTemplateCompat.test.ts +159 -0
  219. package/src/utils/__tests__/runjsValue.test.ts +44 -0
  220. package/src/utils/__tests__/safeGlobals.test.ts +57 -2
  221. package/src/utils/__tests__/utils.test.ts +95 -0
  222. package/src/utils/associationObjectVariable.ts +2 -2
  223. package/src/utils/createCollectionContextMeta.ts +1 -0
  224. package/src/utils/createEphemeralContext.ts +5 -4
  225. package/src/utils/dateVariable.ts +397 -0
  226. package/src/utils/exceptions.ts +11 -0
  227. package/src/utils/index.ts +37 -3
  228. package/src/utils/params-resolvers.ts +23 -9
  229. package/src/utils/resolveModuleUrl.ts +91 -0
  230. package/src/utils/resolveRunJSObjectValues.ts +46 -0
  231. package/src/utils/runjsModuleLoader.ts +553 -0
  232. package/src/utils/runjsTemplateCompat.ts +828 -0
  233. package/src/utils/runjsValue.ts +287 -0
  234. package/src/utils/safeGlobals.ts +188 -17
  235. package/src/utils/schema-utils.ts +79 -0
  236. package/src/views/__tests__/FlowView.usePage.test.tsx +54 -1
  237. package/src/views/__tests__/useDialog.closeDestroy.test.tsx +35 -8
  238. package/src/views/__tests__/viewEvents.resolveOpenerEngine.test.ts +28 -0
  239. package/src/views/createViewMeta.ts +22 -75
  240. package/src/views/index.tsx +1 -2
  241. package/src/views/useDialog.tsx +8 -1
  242. package/src/views/useDrawer.tsx +8 -1
  243. package/src/views/usePage.tsx +51 -5
  244. package/src/views/usePopover.tsx +4 -1
  245. package/src/views/viewEvents.ts +55 -0
@@ -29,7 +29,6 @@ var createViewMeta_exports = {};
29
29
  __export(createViewMeta_exports, {
30
30
  buildPopupRuntime: () => buildPopupRuntime,
31
31
  createPopupMeta: () => createPopupMeta,
32
- createViewMeta: () => createViewMeta,
33
32
  registerPopupVariable: () => registerPopupVariable
34
33
  });
35
34
  module.exports = __toCommonJS(createViewMeta_exports);
@@ -82,67 +81,15 @@ function makeMetaFromValue(value, title, seen) {
82
81
  return { type: "any", title };
83
82
  }
84
83
  __name(makeMetaFromValue, "makeMetaFromValue");
85
- function createViewMeta(ctx) {
86
- const viewTitle = ctx.t("\u5F53\u524D\u89C6\u56FE");
87
- const factory = /* @__PURE__ */ __name(async () => {
88
- const view = ctx.view;
89
- return {
90
- type: "object",
91
- title: ctx.t("\u5F53\u524D\u89C6\u56FE"),
92
- buildVariablesParams: /* @__PURE__ */ __name((c) => {
93
- const params = (0, import_variablesParams.inferViewRecordRef)(c);
94
- if (params) {
95
- return {
96
- record: params
97
- };
98
- }
99
- return void 0;
100
- }, "buildVariablesParams"),
101
- properties: /* @__PURE__ */ __name(async () => {
102
- var _a, _b, _c;
103
- const props = {};
104
- const refNow = (0, import_variablesParams.inferViewRecordRef)(ctx);
105
- if (refNow && refNow.collection) {
106
- const recordFactory = /* @__PURE__ */ __name(async () => {
107
- var _a2, _b2, _c2, _d;
108
- try {
109
- const ref = (0, import_variablesParams.inferViewRecordRef)(ctx);
110
- if (!(ref == null ? void 0 : ref.collection)) return null;
111
- const dsKey = ref.dataSourceKey || "main";
112
- const ds = (_b2 = (_a2 = ctx.dataSourceManager) == null ? void 0 : _a2.getDataSource) == null ? void 0 : _b2.call(_a2, dsKey);
113
- const col = (_d = (_c2 = ds == null ? void 0 : ds.collectionManager) == null ? void 0 : _c2.getCollection) == null ? void 0 : _d.call(_c2, ref.collection);
114
- if (!col) return null;
115
- return await (0, import_variablesParams.buildRecordMeta)(
116
- () => col,
117
- ctx.t("\u5F53\u524D\u89C6\u56FE\u8BB0\u5F55"),
118
- (c) => (0, import_variablesParams.inferViewRecordRef)(c)
119
- );
120
- } catch (e) {
121
- return null;
122
- }
123
- }, "recordFactory");
124
- recordFactory.title = ctx.t("\u5F53\u524D\u89C6\u56FE\u8BB0\u5F55");
125
- recordFactory.hasChildren = true;
126
- props.record = recordFactory;
127
- }
128
- props.type = { type: "string", title: ((_a = ctx.t) == null ? void 0 : _a.call(ctx, "\u7C7B\u578B")) || "\u7C7B\u578B" };
129
- props.preventClose = { type: "boolean", title: ((_b = ctx.t) == null ? void 0 : _b.call(ctx, "\u662F\u5426\u5141\u8BB8\u5173\u95ED")) || "\u662F\u5426\u5141\u8BB8\u5173\u95ED" };
130
- props.inputArgs = makeMetaFromValue(view == null ? void 0 : view.inputArgs, ((_c = ctx.t) == null ? void 0 : _c.call(ctx, "\u8F93\u5165\u53C2\u6570")) || "\u8F93\u5165\u53C2\u6570");
131
- return props;
132
- }, "properties")
133
- };
134
- }, "factory");
135
- factory.title = viewTitle;
136
- return factory;
137
- }
138
- __name(createViewMeta, "createViewMeta");
139
84
  function createPopupMeta(ctx, anchorView) {
140
85
  const t = /* @__PURE__ */ __name((k) => ctx.t(k), "t");
141
86
  const isPopupView = /* @__PURE__ */ __name((view) => {
142
- var _a;
87
+ var _a, _b;
143
88
  if (!view) return false;
144
89
  const stack = Array.isArray((_a = view.navigation) == null ? void 0 : _a.viewStack) ? view.navigation.viewStack : [];
145
- return stack.length >= 2;
90
+ const openerUids = (_b = view == null ? void 0 : view.inputArgs) == null ? void 0 : _b.openerUids;
91
+ const hasOpener = Array.isArray(openerUids) && openerUids.length > 0;
92
+ return stack.length >= 2 || hasOpener;
146
93
  }, "isPopupView");
147
94
  const hasPopupNow = /* @__PURE__ */ __name(() => isPopupView(anchorView ?? ctx.view), "hasPopupNow");
148
95
  const resolveRecordRef = /* @__PURE__ */ __name(async (flowCtx) => {
@@ -329,18 +276,21 @@ function createPopupMeta(ctx, anchorView) {
329
276
  var _a, _b, _c, _d, _e, _f;
330
277
  const props = {};
331
278
  props.uid = { type: "string", title: t("Popup uid") };
332
- const recordFactory = /* @__PURE__ */ __name(async () => {
333
- const col = await getCurrentCollection();
334
- if (!col) return null;
335
- return await (0, import_variablesParams.buildRecordMeta)(
336
- () => col,
337
- t("Current popup record"),
338
- (c) => resolveRecordRef(c)
339
- );
340
- }, "recordFactory");
341
- recordFactory.title = t("Current popup record");
342
- recordFactory.hasChildren = true;
343
- props.record = recordFactory;
279
+ const recordRef = await resolveRecordRef(ctx);
280
+ if (recordRef) {
281
+ const recordFactory = /* @__PURE__ */ __name(async () => {
282
+ const col = await getCurrentCollection();
283
+ if (!col) return null;
284
+ return await (0, import_variablesParams.buildRecordMeta)(
285
+ () => col,
286
+ t("Current popup record"),
287
+ (c) => resolveRecordRef(c)
288
+ );
289
+ }, "recordFactory");
290
+ recordFactory.title = t("Current popup record");
291
+ recordFactory.hasChildren = true;
292
+ props.record = recordFactory;
293
+ }
344
294
  try {
345
295
  const inputArgs = (_a = ctx.view) == null ? void 0 : _a.inputArgs;
346
296
  const srcId = inputArgs == null ? void 0 : inputArgs.sourceId;
@@ -483,6 +433,5 @@ __name(registerPopupVariable, "registerPopupVariable");
483
433
  0 && (module.exports = {
484
434
  buildPopupRuntime,
485
435
  createPopupMeta,
486
- createViewMeta,
487
436
  registerPopupVariable
488
437
  });
@@ -8,7 +8,6 @@
8
8
  */
9
9
  export { useDialog } from './useDialog';
10
10
  export { useDrawer } from './useDrawer';
11
- export { usePage } from './usePage';
11
+ export { usePage, GLOBAL_EMBED_CONTAINER_ID, EMBED_REPLACING_DATA_KEY } from './usePage';
12
12
  export { usePopover } from './usePopover';
13
13
  export { ViewNavigation } from './ViewNavigation';
14
- export { createViewMeta } from './createViewMeta';
@@ -26,8 +26,9 @@ var __copyProps = (to, from, except, desc) => {
26
26
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
27
  var views_exports = {};
28
28
  __export(views_exports, {
29
+ EMBED_REPLACING_DATA_KEY: () => import_usePage.EMBED_REPLACING_DATA_KEY,
30
+ GLOBAL_EMBED_CONTAINER_ID: () => import_usePage.GLOBAL_EMBED_CONTAINER_ID,
29
31
  ViewNavigation: () => import_ViewNavigation.ViewNavigation,
30
- createViewMeta: () => import_createViewMeta.createViewMeta,
31
32
  useDialog: () => import_useDialog.useDialog,
32
33
  useDrawer: () => import_useDrawer.useDrawer,
33
34
  usePage: () => import_usePage.usePage,
@@ -39,11 +40,11 @@ var import_useDrawer = require("./useDrawer");
39
40
  var import_usePage = require("./usePage");
40
41
  var import_usePopover = require("./usePopover");
41
42
  var import_ViewNavigation = require("./ViewNavigation");
42
- var import_createViewMeta = require("./createViewMeta");
43
43
  // Annotate the CommonJS export names for ESM import in node:
44
44
  0 && (module.exports = {
45
+ EMBED_REPLACING_DATA_KEY,
46
+ GLOBAL_EMBED_CONTAINER_ID,
45
47
  ViewNavigation,
46
- createViewMeta,
47
48
  useDialog,
48
49
  useDrawer,
49
50
  usePage,
@@ -48,6 +48,7 @@ var import_FlowContextProvider = require("../FlowContextProvider");
48
48
  var import_createViewMeta = require("./createViewMeta");
49
49
  var import_DialogComponent = __toESM(require("./DialogComponent"));
50
50
  var import_usePatchElement = __toESM(require("./usePatchElement"));
51
+ var import_viewEvents = require("./viewEvents");
51
52
  var import_provider = require("../provider");
52
53
  var import_ViewScopedFlowEngine = require("../ViewScopedFlowEngine");
53
54
  var import_variablesParams = require("../utils/variablesParams");
@@ -56,6 +57,7 @@ function useDialog() {
56
57
  const holderRef = React.useRef(null);
57
58
  const open = /* @__PURE__ */ __name((config, flowContext) => {
58
59
  var _a, _b, _c;
60
+ const parentEngine = flowContext == null ? void 0 : flowContext.engine;
59
61
  uuid += 1;
60
62
  const dialogRef = React.createRef();
61
63
  let closeFunc;
@@ -93,6 +95,7 @@ function useDialog() {
93
95
  }, "HeaderComponent");
94
96
  const ctx = new import_flowContext.FlowContext();
95
97
  const scopedEngine = (0, import_ViewScopedFlowEngine.createViewScopedEngine)(flowContext.engine);
98
+ const openerEngine = (0, import_viewEvents.resolveOpenerEngine)(parentEngine, scopedEngine);
96
99
  ctx.defineProperty("engine", { value: scopedEngine });
97
100
  ctx.addDelegate(scopedEngine.context);
98
101
  if (config.inheritContext !== false) {
@@ -105,11 +108,14 @@ function useDialog() {
105
108
  inputArgs: config.inputArgs || {},
106
109
  preventClose: !!config.preventClose,
107
110
  destroy: /* @__PURE__ */ __name((result) => {
108
- var _a2, _b2;
111
+ var _a2, _b2, _c2, _d;
109
112
  (_a2 = config.onClose) == null ? void 0 : _a2.call(config);
110
113
  (_b2 = dialogRef.current) == null ? void 0 : _b2.destroy();
111
114
  closeFunc == null ? void 0 : closeFunc();
112
115
  resolvePromise == null ? void 0 : resolvePromise(result);
116
+ const openerEmitter = openerEngine == null ? void 0 : openerEngine.emitter;
117
+ (0, import_viewEvents.bumpViewActivatedVersion)(openerEmitter);
118
+ (_d = openerEmitter == null ? void 0 : openerEmitter.emit) == null ? void 0 : _d.call(openerEmitter, import_viewEvents.VIEW_ACTIVATED_EVENT, { type: "dialog", viewUid: (_c2 = currentDialog == null ? void 0 : currentDialog.inputArgs) == null ? void 0 : _c2.viewUid });
113
119
  scopedEngine.unlinkFromStack();
114
120
  }, "destroy"),
115
121
  update: /* @__PURE__ */ __name((newConfig) => {
@@ -146,7 +152,6 @@ function useDialog() {
146
152
  };
147
153
  ctx.defineProperty("view", {
148
154
  get: /* @__PURE__ */ __name(() => currentDialog, "get"),
149
- // meta: createViewMeta(ctx),
150
155
  resolveOnServer: (0, import_variablesParams.createViewRecordResolveOnServer)(ctx, () => (0, import_variablesParams.getViewRecordFromParent)(flowContext, ctx))
151
156
  });
152
157
  (0, import_createViewMeta.registerPopupVariable)(ctx, currentDialog);
@@ -48,6 +48,7 @@ var import_FlowContextProvider = require("../FlowContextProvider");
48
48
  var import_createViewMeta = require("./createViewMeta");
49
49
  var import_DrawerComponent = __toESM(require("./DrawerComponent"));
50
50
  var import_usePatchElement = __toESM(require("./usePatchElement"));
51
+ var import_viewEvents = require("./viewEvents");
51
52
  var import_provider = require("../provider");
52
53
  var import_ViewScopedFlowEngine = require("../ViewScopedFlowEngine");
53
54
  var import_variablesParams = require("../utils/variablesParams");
@@ -76,6 +77,7 @@ function useDrawer() {
76
77
  RenderNestedDrawer.displayName = "RenderNestedDrawer";
77
78
  const open = /* @__PURE__ */ __name((config, flowContext) => {
78
79
  var _a, _b;
80
+ const parentEngine = flowContext.engine;
79
81
  const drawerRef = React.createRef();
80
82
  let closeFunc;
81
83
  let resolvePromise;
@@ -112,6 +114,7 @@ function useDrawer() {
112
114
  }, "HeaderComponent");
113
115
  const ctx = new import_flowContext.FlowContext();
114
116
  const scopedEngine = (0, import_ViewScopedFlowEngine.createViewScopedEngine)(flowContext.engine);
117
+ const openerEngine = (0, import_viewEvents.resolveOpenerEngine)(parentEngine, scopedEngine);
115
118
  ctx.defineProperty("engine", { value: scopedEngine });
116
119
  ctx.addDelegate(scopedEngine.context);
117
120
  if (config.inheritContext !== false) {
@@ -124,11 +127,14 @@ function useDrawer() {
124
127
  inputArgs: config.inputArgs || {},
125
128
  preventClose: !!config.preventClose,
126
129
  destroy: /* @__PURE__ */ __name((result) => {
127
- var _a2, _b2;
130
+ var _a2, _b2, _c, _d;
128
131
  (_a2 = config.onClose) == null ? void 0 : _a2.call(config);
129
132
  (_b2 = drawerRef.current) == null ? void 0 : _b2.destroy();
130
133
  closeFunc == null ? void 0 : closeFunc();
131
134
  resolvePromise == null ? void 0 : resolvePromise(result);
135
+ const openerEmitter = openerEngine == null ? void 0 : openerEngine.emitter;
136
+ (0, import_viewEvents.bumpViewActivatedVersion)(openerEmitter);
137
+ (_d = openerEmitter == null ? void 0 : openerEmitter.emit) == null ? void 0 : _d.call(openerEmitter, import_viewEvents.VIEW_ACTIVATED_EVENT, { type: "drawer", viewUid: (_c = currentDrawer == null ? void 0 : currentDrawer.inputArgs) == null ? void 0 : _c.viewUid });
132
138
  scopedEngine.unlinkFromStack();
133
139
  }, "destroy"),
134
140
  update: /* @__PURE__ */ __name((newConfig) => {
@@ -165,7 +171,6 @@ function useDrawer() {
165
171
  };
166
172
  ctx.defineProperty("view", {
167
173
  get: /* @__PURE__ */ __name(() => currentDrawer, "get"),
168
- // meta: createViewMeta(ctx),
169
174
  resolveOnServer: (0, import_variablesParams.createViewRecordResolveOnServer)(ctx, () => (0, import_variablesParams.getViewRecordFromParent)(flowContext, ctx))
170
175
  });
171
176
  (0, import_createViewMeta.registerPopupVariable)(ctx, currentDrawer);
@@ -7,6 +7,10 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import React from 'react';
10
+ /** Global embed container element ID */
11
+ export declare const GLOBAL_EMBED_CONTAINER_ID = "nocobase-embed-container";
12
+ /** Dataset key used to signal embed replacement in progress (skip style reset on close) */
13
+ export declare const EMBED_REPLACING_DATA_KEY = "nocobaseEmbedReplacing";
10
14
  export declare function usePage(): (React.JSX.Element | {
11
15
  open: (config: any, flowContext: any) => Promise<unknown> & {
12
16
  type: "embed";
@@ -37,6 +37,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
37
37
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
38
  var usePage_exports = {};
39
39
  __export(usePage_exports, {
40
+ EMBED_REPLACING_DATA_KEY: () => EMBED_REPLACING_DATA_KEY,
41
+ GLOBAL_EMBED_CONTAINER_ID: () => GLOBAL_EMBED_CONTAINER_ID,
40
42
  usePage: () => usePage
41
43
  });
42
44
  module.exports = __toCommonJS(usePage_exports);
@@ -48,22 +50,26 @@ var import_FlowContextProvider = require("../FlowContextProvider");
48
50
  var import_createViewMeta = require("./createViewMeta");
49
51
  var import_PageComponent = require("./PageComponent");
50
52
  var import_usePatchElement = __toESM(require("./usePatchElement"));
53
+ var import_viewEvents = require("./viewEvents");
51
54
  var import_provider = require("../provider");
52
55
  var import_ViewScopedFlowEngine = require("../ViewScopedFlowEngine");
53
56
  var import_variablesParams = require("../utils/variablesParams");
54
57
  let uuid = 0;
58
+ const GLOBAL_EMBED_CONTAINER_ID = "nocobase-embed-container";
59
+ const EMBED_REPLACING_DATA_KEY = "nocobaseEmbedReplacing";
55
60
  const PageElementsHolder = import_react.default.memo(
56
61
  import_react.default.forwardRef((props, ref) => {
57
62
  const [elements, patchElement] = (0, import_usePatchElement.default)();
58
63
  import_react.default.useImperativeHandle(ref, () => ({ patchElement }), [patchElement]);
59
- console.log("[NocoBase] Rendering PageElementsHolder with elements count:", elements.length);
60
64
  return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, elements);
61
65
  })
62
66
  );
63
67
  function usePage() {
64
68
  const holderRef = import_react.default.useRef(null);
69
+ const globalEmbedActiveRef = import_react.default.useRef(null);
65
70
  const open = /* @__PURE__ */ __name((config, flowContext) => {
66
71
  var _a, _b, _c;
72
+ const parentEngine = flowContext == null ? void 0 : flowContext.engine;
67
73
  uuid += 1;
68
74
  const pageRef = import_react.default.createRef();
69
75
  let closeFunc;
@@ -93,9 +99,27 @@ function usePage() {
93
99
  }, [props]);
94
100
  return null;
95
101
  }, "HeaderComponent");
96
- const { target, content, preventClose, inheritContext = true, inputArgs, ...restConfig } = config;
102
+ const {
103
+ target,
104
+ content,
105
+ preventClose,
106
+ inheritContext = true,
107
+ inputArgs: viewInputArgs = {},
108
+ ...restConfig
109
+ } = config;
110
+ const isGlobalEmbedContainer = target instanceof HTMLElement && target.id === GLOBAL_EMBED_CONTAINER_ID;
111
+ if (isGlobalEmbedContainer && globalEmbedActiveRef.current) {
112
+ try {
113
+ target.dataset[EMBED_REPLACING_DATA_KEY] = "1";
114
+ globalEmbedActiveRef.current.destroy();
115
+ } finally {
116
+ delete target.dataset[EMBED_REPLACING_DATA_KEY];
117
+ globalEmbedActiveRef.current = null;
118
+ }
119
+ }
97
120
  const ctx = new import_flowContext.FlowContext();
98
121
  const scopedEngine = (0, import_ViewScopedFlowEngine.createViewScopedEngine)(flowContext.engine);
122
+ const openerEngine = (0, import_viewEvents.resolveOpenerEngine)(parentEngine, scopedEngine);
99
123
  ctx.defineProperty("engine", { value: scopedEngine });
100
124
  ctx.addDelegate(scopedEngine.context);
101
125
  if (inheritContext) {
@@ -105,14 +129,23 @@ function usePage() {
105
129
  }
106
130
  const currentPage = {
107
131
  type: "embed",
108
- inputArgs: config.inputArgs || {},
132
+ inputArgs: viewInputArgs,
109
133
  preventClose: !!config.preventClose,
110
134
  destroy: /* @__PURE__ */ __name((result) => {
111
- var _a2, _b2;
135
+ var _a2, _b2, _c2, _d, _e;
112
136
  (_a2 = config.onClose) == null ? void 0 : _a2.call(config);
113
137
  resolvePromise == null ? void 0 : resolvePromise(result);
114
138
  (_b2 = pageRef.current) == null ? void 0 : _b2.destroy();
115
139
  closeFunc == null ? void 0 : closeFunc();
140
+ if (isGlobalEmbedContainer) {
141
+ globalEmbedActiveRef.current = null;
142
+ }
143
+ const isReplacing = isGlobalEmbedContainer && target instanceof HTMLElement && ((_c2 = target.dataset) == null ? void 0 : _c2[EMBED_REPLACING_DATA_KEY]) === "1";
144
+ if (!isReplacing) {
145
+ const openerEmitter = openerEngine == null ? void 0 : openerEngine.emitter;
146
+ (0, import_viewEvents.bumpViewActivatedVersion)(openerEmitter);
147
+ (_e = openerEmitter == null ? void 0 : openerEmitter.emit) == null ? void 0 : _e.call(openerEmitter, import_viewEvents.VIEW_ACTIVATED_EVENT, { type: "embed", viewUid: (_d = currentPage == null ? void 0 : currentPage.inputArgs) == null ? void 0 : _d.viewUid });
148
+ }
116
149
  scopedEngine.unlinkFromStack();
117
150
  }, "destroy"),
118
151
  update: /* @__PURE__ */ __name((newConfig) => {
@@ -147,7 +180,6 @@ function usePage() {
147
180
  };
148
181
  ctx.defineProperty("view", {
149
182
  get: /* @__PURE__ */ __name(() => currentPage, "get"),
150
- // meta: createViewMeta(ctx),
151
183
  // 仅当访问关联字段或前端无本地记录数据时,才交给服务端解析
152
184
  resolveOnServer: (0, import_variablesParams.createViewRecordResolveOnServer)(ctx, () => (0, import_variablesParams.getViewRecordFromParent)(flowContext, ctx))
153
185
  });
@@ -186,13 +218,16 @@ function usePage() {
186
218
  displayName: "PageWithContext"
187
219
  }
188
220
  );
189
- const key = (inputArgs == null ? void 0 : inputArgs.viewUid) || `page-${uuid}`;
221
+ const key = (viewInputArgs == null ? void 0 : viewInputArgs.viewUid) || `page-${uuid}`;
190
222
  const page = /* @__PURE__ */ import_react.default.createElement(import_provider.FlowEngineProvider, { key, engine: scopedEngine }, /* @__PURE__ */ import_react.default.createElement(import_FlowContextProvider.FlowViewContextProvider, { context: ctx }, /* @__PURE__ */ import_react.default.createElement(PageWithContext, null)));
191
223
  if (target && target instanceof HTMLElement) {
192
224
  closeFunc = (_b = holderRef.current) == null ? void 0 : _b.patchElement(import_react_dom.default.createPortal(page, target, key));
193
225
  } else {
194
226
  closeFunc = (_c = holderRef.current) == null ? void 0 : _c.patchElement(page);
195
227
  }
228
+ if (isGlobalEmbedContainer) {
229
+ globalEmbedActiveRef.current = { destroy: currentPage.destroy };
230
+ }
196
231
  return Object.assign(promise, currentPage);
197
232
  }, "open");
198
233
  const api = import_react.default.useMemo(() => ({ open }), []);
@@ -201,5 +236,7 @@ function usePage() {
201
236
  __name(usePage, "usePage");
202
237
  // Annotate the CommonJS export names for ESM import in node:
203
238
  0 && (module.exports = {
239
+ EMBED_REPLACING_DATA_KEY,
240
+ GLOBAL_EMBED_CONTAINER_ID,
204
241
  usePage
205
242
  });
@@ -68,8 +68,11 @@ const PopoverComponent = React.forwardRef(({ afterClose, content, placement, rec
68
68
  destroyTooltipOnHide: true,
69
69
  content: config.content,
70
70
  placement: config.placement,
71
- getPopupContainer: () => document.body,
71
+ getPopupContainer: () => document.querySelector("#nocobase-app-container") || document.body,
72
72
  onOpenChange: (nextOpen) => {
73
+ if (!nextOpen && config.preventClose) {
74
+ return;
75
+ }
73
76
  setVisible(nextOpen);
74
77
  if (!nextOpen) {
75
78
  afterClose == null ? void 0 : afterClose();
@@ -0,0 +1,17 @@
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 { FlowEngine } from '../flowEngine';
10
+ export declare const VIEW_ACTIVATED_VERSION: unique symbol;
11
+ export declare const VIEW_ACTIVATED_EVENT: "view:activated";
12
+ export declare const DATA_SOURCE_DIRTY_EVENT: "dataSource:dirty";
13
+ export declare const ENGINE_SCOPE_KEY: "__NOCOBASE_ENGINE_SCOPE__";
14
+ export declare const VIEW_ENGINE_SCOPE: "view";
15
+ export declare function getEmitterViewActivatedVersion(emitter: any): number;
16
+ export declare function bumpViewActivatedVersion(emitter: any): number;
17
+ export declare function resolveOpenerEngine(parentEngine: FlowEngine, scopedEngine: FlowEngine): FlowEngine | undefined;
@@ -0,0 +1,90 @@
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
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
15
+ var __export = (target, all) => {
16
+ for (var name in all)
17
+ __defProp(target, name, { get: all[name], enumerable: true });
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
+ }
25
+ return to;
26
+ };
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var viewEvents_exports = {};
29
+ __export(viewEvents_exports, {
30
+ DATA_SOURCE_DIRTY_EVENT: () => DATA_SOURCE_DIRTY_EVENT,
31
+ ENGINE_SCOPE_KEY: () => ENGINE_SCOPE_KEY,
32
+ VIEW_ACTIVATED_EVENT: () => VIEW_ACTIVATED_EVENT,
33
+ VIEW_ACTIVATED_VERSION: () => VIEW_ACTIVATED_VERSION,
34
+ VIEW_ENGINE_SCOPE: () => VIEW_ENGINE_SCOPE,
35
+ bumpViewActivatedVersion: () => bumpViewActivatedVersion,
36
+ getEmitterViewActivatedVersion: () => getEmitterViewActivatedVersion,
37
+ resolveOpenerEngine: () => resolveOpenerEngine
38
+ });
39
+ module.exports = __toCommonJS(viewEvents_exports);
40
+ const VIEW_ACTIVATED_VERSION = Symbol.for("__NOCOBASE_VIEW_ACTIVATED_VERSION__");
41
+ const VIEW_ACTIVATED_EVENT = "view:activated";
42
+ const DATA_SOURCE_DIRTY_EVENT = "dataSource:dirty";
43
+ const ENGINE_SCOPE_KEY = "__NOCOBASE_ENGINE_SCOPE__";
44
+ const VIEW_ENGINE_SCOPE = "view";
45
+ function getEmitterViewActivatedVersion(emitter) {
46
+ const raw = Reflect.get(emitter, VIEW_ACTIVATED_VERSION);
47
+ const num = typeof raw === "number" ? raw : Number(raw);
48
+ return Number.isFinite(num) && num > 0 ? num : 0;
49
+ }
50
+ __name(getEmitterViewActivatedVersion, "getEmitterViewActivatedVersion");
51
+ function bumpViewActivatedVersion(emitter) {
52
+ const current = getEmitterViewActivatedVersion(emitter);
53
+ if (!Object.isExtensible(emitter)) return current;
54
+ const next = current + 1;
55
+ Reflect.set(emitter, VIEW_ACTIVATED_VERSION, next);
56
+ return next;
57
+ }
58
+ __name(bumpViewActivatedVersion, "bumpViewActivatedVersion");
59
+ function isViewEngine(engine) {
60
+ return Reflect.get(engine, ENGINE_SCOPE_KEY) === VIEW_ENGINE_SCOPE;
61
+ }
62
+ __name(isViewEngine, "isViewEngine");
63
+ function findNearestViewEngine(engine) {
64
+ let cur = engine;
65
+ let guard = 0;
66
+ while (cur && guard++ < 50) {
67
+ if (isViewEngine(cur)) return cur;
68
+ cur = cur.previousEngine;
69
+ }
70
+ }
71
+ __name(findNearestViewEngine, "findNearestViewEngine");
72
+ function resolveOpenerEngine(parentEngine, scopedEngine) {
73
+ if (!parentEngine) return void 0;
74
+ const parentViewEngine = findNearestViewEngine(parentEngine);
75
+ if (parentViewEngine) return parentViewEngine;
76
+ const previousEngine = scopedEngine == null ? void 0 : scopedEngine.previousEngine;
77
+ return findNearestViewEngine(previousEngine) || parentEngine;
78
+ }
79
+ __name(resolveOpenerEngine, "resolveOpenerEngine");
80
+ // Annotate the CommonJS export names for ESM import in node:
81
+ 0 && (module.exports = {
82
+ DATA_SOURCE_DIRTY_EVENT,
83
+ ENGINE_SCOPE_KEY,
84
+ VIEW_ACTIVATED_EVENT,
85
+ VIEW_ACTIVATED_VERSION,
86
+ VIEW_ENGINE_SCOPE,
87
+ bumpViewActivatedVersion,
88
+ getEmitterViewActivatedVersion,
89
+ resolveOpenerEngine
90
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/flow-engine",
3
- "version": "2.0.0-beta.9",
3
+ "version": "2.0.0",
4
4
  "private": false,
5
5
  "description": "A standalone flow engine for NocoBase, managing workflows, models, and actions.",
6
6
  "main": "lib/index.js",
@@ -8,8 +8,8 @@
8
8
  "dependencies": {
9
9
  "@formily/antd-v5": "1.x",
10
10
  "@formily/reactive": "2.x",
11
- "@nocobase/sdk": "2.0.0-beta.9",
12
- "@nocobase/shared": "2.0.0-beta.9",
11
+ "@nocobase/sdk": "2.0.0",
12
+ "@nocobase/shared": "2.0.0",
13
13
  "ahooks": "^3.7.2",
14
14
  "dayjs": "^1.11.9",
15
15
  "dompurify": "^3.0.2",
@@ -36,5 +36,5 @@
36
36
  ],
37
37
  "author": "NocoBase Team",
38
38
  "license": "AGPL-3.0",
39
- "gitHead": "36ef50291e22fe1024c819b8748d51a59a5ea4f8"
39
+ "gitHead": "3590c0087a56f0f285a5357f43a80bdc62b11bec"
40
40
  }
@@ -31,16 +31,13 @@ export function createBlockScopedEngine(parent: FlowEngine): FlowEngine {
31
31
  local.context.addDelegate(parent.context);
32
32
 
33
33
  // 覆盖 unlinkFromStack:BlockScoped 引擎被移除时,修复前后指针,避免“截断”后续视图/作用域
34
- const originalUnlink = local.unlinkFromStack.bind(local);
35
34
  local.unlinkFromStack = function () {
36
- // 修复指针:prev -> next,next -> prev,然后清理自身指针
37
- // 若不这么做,移除位于中间的 block 引擎会导致后续整段链丢失
38
35
  const prev = (local as any)._previousEngine as FlowEngine | undefined;
39
36
  const next = (local as any)._nextEngine as FlowEngine | undefined;
40
37
  if (prev) (prev as any)._nextEngine = next;
41
38
  if (next) (next as any)._previousEngine = prev;
42
- (local as any)._previousEngine = undefined as any;
43
- (local as any)._nextEngine = undefined as any;
39
+ (local as any)._previousEngine = undefined;
40
+ (local as any)._nextEngine = undefined;
44
41
  };
45
42
 
46
43
  // 默认全部代理到父引擎,只有少数字段(实例/缓存/执行器/上下文/链表指针)使用本地值
package/src/JSRunner.ts CHANGED
@@ -8,11 +8,18 @@
8
8
  */
9
9
 
10
10
  import 'ses';
11
+ import { FlowExitAllException, FlowExitException } from './utils/exceptions';
11
12
 
12
13
  export interface JSRunnerOptions {
13
14
  timeoutMs?: number;
14
15
  globals?: Record<string, any>;
15
16
  version?: string;
17
+ /**
18
+ * Enable RunJS template compatibility preprocessing for `{{ ... }}`.
19
+ * When enabled via `ctx.runjs(code, vars, { preprocessTemplates: true })` (default),
20
+ * the code will be rewritten to call `ctx.resolveJsonTemplate(...)` at runtime.
21
+ */
22
+ preprocessTemplates?: boolean;
16
23
  }
17
24
 
18
25
  export class JSRunner {
@@ -28,13 +35,41 @@ export class JSRunner {
28
35
  return typeof fn === 'function' ? fn.bind(globalThis) : fn;
29
36
  };
30
37
 
38
+ const providedGlobals = options.globals || {};
39
+ const liftedGlobals: Record<string, any> = {};
40
+
41
+ // Auto-lift selected globals from safe window into top-level sandbox globals
42
+ // so user code can access them directly (e.g. `new Blob(...)`).
43
+ if (!Object.prototype.hasOwnProperty.call(providedGlobals, 'Blob')) {
44
+ try {
45
+ const blobCtor = (providedGlobals as any).window?.Blob;
46
+ if (typeof blobCtor !== 'undefined') {
47
+ liftedGlobals.Blob = blobCtor;
48
+ }
49
+ } catch {
50
+ // ignore when window proxy blocks property access
51
+ }
52
+ }
53
+
54
+ if (!Object.prototype.hasOwnProperty.call(providedGlobals, 'URL')) {
55
+ try {
56
+ const urlCtor = (providedGlobals as any).window?.URL;
57
+ if (typeof urlCtor !== 'undefined') {
58
+ liftedGlobals.URL = urlCtor;
59
+ }
60
+ } catch {
61
+ // ignore when window proxy blocks property access
62
+ }
63
+ }
64
+
31
65
  this.globals = {
32
66
  console,
33
67
  setTimeout: bindWindowFn('setTimeout'),
34
68
  clearTimeout: bindWindowFn('clearTimeout'),
35
69
  setInterval: bindWindowFn('setInterval'),
36
70
  clearInterval: bindWindowFn('clearInterval'),
37
- ...(options.globals || {}),
71
+ ...liftedGlobals,
72
+ ...providedGlobals,
38
73
  };
39
74
  this.timeoutMs = options.timeoutMs ?? 5000; // 默认 5 秒超时
40
75
  }
@@ -55,7 +90,8 @@ export class JSRunner {
55
90
  error?: any;
56
91
  timeout?: boolean;
57
92
  }> {
58
- if (location?.search.includes('skipRunJs=true')) {
93
+ const search = typeof location !== 'undefined' ? location.search : undefined;
94
+ if (typeof search === 'string' && search.includes('skipRunJs=true')) {
59
95
  return { success: true, value: null };
60
96
  }
61
97
  const wrapped = `(async () => {
@@ -76,6 +112,12 @@ export class JSRunner {
76
112
  const result = await Promise.race([task, timeoutPromise]);
77
113
  return { success: true, value: result };
78
114
  } catch (err) {
115
+ if (err instanceof FlowExitException) {
116
+ throw err;
117
+ }
118
+ if (err instanceof FlowExitAllException) {
119
+ throw err;
120
+ }
79
121
  console.error(err);
80
122
  return {
81
123
  success: false,
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  import { FlowEngine } from './flowEngine';
11
+ import { ENGINE_SCOPE_KEY, VIEW_ENGINE_SCOPE } from './views/viewEvents';
11
12
 
12
13
  /**
13
14
  * ViewScopedFlowEngine(视图作用域引擎)
@@ -24,6 +25,8 @@ import { FlowEngine } from './flowEngine';
24
25
  */
25
26
  export function createViewScopedEngine(parent: FlowEngine): FlowEngine {
26
27
  const local = new FlowEngine();
28
+ // Mark for view-stack traversal (used by view activation events).
29
+ Object.defineProperty(local, ENGINE_SCOPE_KEY, { value: VIEW_ENGINE_SCOPE, configurable: true });
27
30
  if (parent.modelRepository) {
28
31
  local.setModelRepository(parent.modelRepository);
29
32
  }
@@ -43,6 +46,7 @@ export function createViewScopedEngine(parent: FlowEngine): FlowEngine {
43
46
  '_applyFlowCache',
44
47
  'executor',
45
48
  'context',
49
+ ENGINE_SCOPE_KEY,
46
50
  'previousEngine',
47
51
  'nextEngine',
48
52
  // 调度器与事件总线局部化