@nocobase/flow-engine 2.0.0-beta.2 → 2.0.0-beta.20

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 (124) hide show
  1. package/lib/BlockScopedFlowEngine.js +0 -1
  2. package/lib/JSRunner.d.ts +6 -0
  3. package/lib/JSRunner.js +2 -1
  4. package/lib/ViewScopedFlowEngine.js +3 -0
  5. package/lib/acl/Acl.js +13 -3
  6. package/lib/components/dnd/gridDragPlanner.d.ts +1 -0
  7. package/lib/components/dnd/gridDragPlanner.js +53 -1
  8. package/lib/components/settings/wrappers/component/SwitchWithTitle.js +2 -1
  9. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +11 -3
  10. package/lib/components/variables/VariableInput.js +8 -2
  11. package/lib/data-source/index.js +6 -0
  12. package/lib/executor/FlowExecutor.d.ts +2 -1
  13. package/lib/executor/FlowExecutor.js +156 -22
  14. package/lib/flowContext.d.ts +4 -1
  15. package/lib/flowContext.js +176 -107
  16. package/lib/flowEngine.d.ts +21 -0
  17. package/lib/flowEngine.js +38 -0
  18. package/lib/flowSettings.js +12 -10
  19. package/lib/index.d.ts +3 -0
  20. package/lib/index.js +16 -0
  21. package/lib/models/CollectionFieldModel.d.ts +1 -0
  22. package/lib/models/CollectionFieldModel.js +3 -2
  23. package/lib/models/flowModel.d.ts +7 -0
  24. package/lib/models/flowModel.js +66 -1
  25. package/lib/provider.js +7 -6
  26. package/lib/resources/baseRecordResource.d.ts +5 -0
  27. package/lib/resources/baseRecordResource.js +24 -0
  28. package/lib/resources/multiRecordResource.d.ts +1 -0
  29. package/lib/resources/multiRecordResource.js +11 -4
  30. package/lib/resources/singleRecordResource.js +2 -0
  31. package/lib/resources/sqlResource.d.ts +1 -0
  32. package/lib/resources/sqlResource.js +8 -3
  33. package/lib/runjs-context/contexts/base.js +10 -4
  34. package/lib/runjsLibs.d.ts +28 -0
  35. package/lib/runjsLibs.js +532 -0
  36. package/lib/scheduler/ModelOperationScheduler.d.ts +2 -0
  37. package/lib/scheduler/ModelOperationScheduler.js +21 -21
  38. package/lib/types.d.ts +15 -0
  39. package/lib/utils/createCollectionContextMeta.js +1 -0
  40. package/lib/utils/index.d.ts +2 -0
  41. package/lib/utils/index.js +10 -0
  42. package/lib/utils/params-resolvers.js +16 -9
  43. package/lib/utils/resolveModuleUrl.d.ts +58 -0
  44. package/lib/utils/resolveModuleUrl.js +65 -0
  45. package/lib/utils/runjsModuleLoader.d.ts +58 -0
  46. package/lib/utils/runjsModuleLoader.js +422 -0
  47. package/lib/utils/runjsTemplateCompat.d.ts +35 -0
  48. package/lib/utils/runjsTemplateCompat.js +743 -0
  49. package/lib/utils/safeGlobals.d.ts +5 -9
  50. package/lib/utils/safeGlobals.js +129 -17
  51. package/lib/views/createViewMeta.d.ts +0 -7
  52. package/lib/views/createViewMeta.js +19 -70
  53. package/lib/views/index.d.ts +1 -2
  54. package/lib/views/index.js +4 -3
  55. package/lib/views/useDialog.js +8 -3
  56. package/lib/views/useDrawer.js +7 -2
  57. package/lib/views/usePage.d.ts +4 -0
  58. package/lib/views/usePage.js +43 -6
  59. package/lib/views/usePopover.js +4 -1
  60. package/lib/views/viewEvents.d.ts +17 -0
  61. package/lib/views/viewEvents.js +90 -0
  62. package/package.json +4 -4
  63. package/src/BlockScopedFlowEngine.ts +2 -5
  64. package/src/JSRunner.ts +8 -1
  65. package/src/ViewScopedFlowEngine.ts +4 -0
  66. package/src/__tests__/createViewMeta.popup.test.ts +62 -1
  67. package/src/__tests__/flowEngine.dataSourceDirty.test.ts +63 -0
  68. package/src/__tests__/flowSettings.open.test.tsx +69 -15
  69. package/src/__tests__/provider.test.tsx +0 -5
  70. package/src/__tests__/runjsExternalLibs.test.ts +242 -0
  71. package/src/__tests__/runjsLibsLazyLoading.test.ts +44 -0
  72. package/src/__tests__/runjsPreprocessDefault.test.ts +49 -0
  73. package/src/acl/Acl.tsx +3 -3
  74. package/src/components/__tests__/gridDragPlanner.test.ts +141 -1
  75. package/src/components/dnd/gridDragPlanner.ts +60 -0
  76. package/src/components/settings/wrappers/component/SwitchWithTitle.tsx +2 -1
  77. package/src/components/settings/wrappers/component/__tests__/InlineControls.test.tsx +74 -0
  78. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +11 -3
  79. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +63 -4
  80. package/src/components/variables/VariableInput.tsx +8 -2
  81. package/src/data-source/index.ts +6 -0
  82. package/src/executor/FlowExecutor.ts +193 -23
  83. package/src/executor/__tests__/flowExecutor.test.ts +66 -0
  84. package/src/flowContext.ts +234 -118
  85. package/src/flowEngine.ts +41 -0
  86. package/src/flowSettings.ts +12 -11
  87. package/src/index.ts +10 -0
  88. package/src/models/CollectionFieldModel.tsx +3 -1
  89. package/src/models/__tests__/dispatchEvent.when.test.ts +356 -0
  90. package/src/models/__tests__/flowModel.clone.test.ts +416 -0
  91. package/src/models/__tests__/flowModel.test.ts +16 -0
  92. package/src/models/flowModel.tsx +94 -1
  93. package/src/provider.tsx +9 -7
  94. package/src/resources/__tests__/multiRecordResource.test.ts +44 -0
  95. package/src/resources/__tests__/sqlResource.test.ts +60 -0
  96. package/src/resources/baseRecordResource.ts +31 -0
  97. package/src/resources/multiRecordResource.ts +11 -4
  98. package/src/resources/singleRecordResource.ts +3 -0
  99. package/src/resources/sqlResource.ts +8 -3
  100. package/src/runjs-context/contexts/base.ts +9 -2
  101. package/src/runjsLibs.ts +622 -0
  102. package/src/scheduler/ModelOperationScheduler.ts +23 -21
  103. package/src/types.ts +26 -1
  104. package/src/utils/__tests__/params-resolvers.test.ts +40 -0
  105. package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +38 -0
  106. package/src/utils/__tests__/runjsTemplateCompat.test.ts +159 -0
  107. package/src/utils/__tests__/safeGlobals.test.ts +49 -2
  108. package/src/utils/createCollectionContextMeta.ts +1 -0
  109. package/src/utils/index.ts +6 -0
  110. package/src/utils/params-resolvers.ts +23 -9
  111. package/src/utils/resolveModuleUrl.ts +91 -0
  112. package/src/utils/runjsModuleLoader.ts +553 -0
  113. package/src/utils/runjsTemplateCompat.ts +828 -0
  114. package/src/utils/safeGlobals.ts +133 -16
  115. package/src/views/__tests__/FlowView.usePage.test.tsx +54 -1
  116. package/src/views/__tests__/useDialog.closeDestroy.test.tsx +35 -8
  117. package/src/views/__tests__/viewEvents.resolveOpenerEngine.test.ts +28 -0
  118. package/src/views/createViewMeta.ts +22 -75
  119. package/src/views/index.tsx +1 -2
  120. package/src/views/useDialog.tsx +9 -2
  121. package/src/views/useDrawer.tsx +8 -1
  122. package/src/views/usePage.tsx +51 -5
  123. package/src/views/usePopover.tsx +4 -1
  124. package/src/views/viewEvents.ts +55 -0
@@ -0,0 +1,532 @@
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 __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
17
+ var __export = (target, all) => {
18
+ for (var name in all)
19
+ __defProp(target, name, { get: all[name], enumerable: true });
20
+ };
21
+ var __copyProps = (to, from, except, desc) => {
22
+ if (from && typeof from === "object" || typeof from === "function") {
23
+ for (let key of __getOwnPropNames(from))
24
+ if (!__hasOwnProp.call(to, key) && key !== except)
25
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
26
+ }
27
+ return to;
28
+ };
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
30
+ // If the importer is in node compatibility mode or this is not an ESM
31
+ // file that has been converted to a CommonJS file using a Babel-
32
+ // compatible transform (i.e. "__esModule" has not been set), then set
33
+ // "default" to the CommonJS "module.exports" for node compatibility.
34
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
35
+ mod
36
+ ));
37
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
+ var runjsLibs_exports = {};
39
+ __export(runjsLibs_exports, {
40
+ externalReactRender: () => externalReactRender,
41
+ registerRunJSLib: () => registerRunJSLib,
42
+ setRunJSLibOverride: () => setRunJSLibOverride,
43
+ setupRunJSLibs: () => setupRunJSLibs
44
+ });
45
+ module.exports = __toCommonJS(runjsLibs_exports);
46
+ var antdIcons = __toESM(require("@ant-design/icons"));
47
+ var import_reactive = require("@formily/reactive");
48
+ const __runjsLibRegistry = /* @__PURE__ */ new Map();
49
+ const __runjsLibResolvedCache = /* @__PURE__ */ new Map();
50
+ const __runjsLibPendingCache = /* @__PURE__ */ new Map();
51
+ const __runjsLibPendingByCtx = /* @__PURE__ */ new WeakMap();
52
+ const __runjsErrorBoundaryByReact = /* @__PURE__ */ new WeakMap();
53
+ function __runjsGetPendingMapForCtx(ctx) {
54
+ let m = __runjsLibPendingByCtx.get(ctx);
55
+ if (!m) {
56
+ m = /* @__PURE__ */ new Map();
57
+ __runjsLibPendingByCtx.set(ctx, m);
58
+ }
59
+ return m;
60
+ }
61
+ __name(__runjsGetPendingMapForCtx, "__runjsGetPendingMapForCtx");
62
+ function registerRunJSLib(name, loader, options) {
63
+ if (typeof name !== "string" || !name) return;
64
+ if (typeof loader !== "function") return;
65
+ __runjsLibRegistry.set(name, { loader, cache: (options == null ? void 0 : options.cache) || "global" });
66
+ __runjsLibResolvedCache.delete(name);
67
+ __runjsLibPendingCache.delete(name);
68
+ }
69
+ __name(registerRunJSLib, "registerRunJSLib");
70
+ function __runjsIsObject(val) {
71
+ return !!val && typeof val === "object";
72
+ }
73
+ __name(__runjsIsObject, "__runjsIsObject");
74
+ function __runjsHasOwn(obj, key) {
75
+ return __runjsIsObject(obj) && Object.prototype.hasOwnProperty.call(obj, key);
76
+ }
77
+ __name(__runjsHasOwn, "__runjsHasOwn");
78
+ function __runjsIsPromiseLike(val) {
79
+ if (!__runjsIsObject(val)) return false;
80
+ const then = val.then;
81
+ return typeof then === "function";
82
+ }
83
+ __name(__runjsIsPromiseLike, "__runjsIsPromiseLike");
84
+ function __runjsGetCtxValue(ctx, key) {
85
+ return ctx[key];
86
+ }
87
+ __name(__runjsGetCtxValue, "__runjsGetCtxValue");
88
+ async function __runjsEnsureLib(ctx, name) {
89
+ const libs = ctx == null ? void 0 : ctx.libs;
90
+ if (__runjsHasOwn(libs, name)) {
91
+ const existing = libs[name];
92
+ if (typeof existing !== "undefined") return existing;
93
+ }
94
+ const entry = __runjsLibRegistry.get(name);
95
+ if (!entry) return __runjsIsObject(libs) ? libs[name] : void 0;
96
+ const setLib = /* @__PURE__ */ __name((v2) => {
97
+ if (__runjsIsObject(libs)) libs[name] = v2;
98
+ }, "setLib");
99
+ if (entry.cache === "context") {
100
+ const pendingMap = __runjsGetPendingMapForCtx(ctx);
101
+ const existingPending2 = pendingMap.get(name);
102
+ if (existingPending2) {
103
+ const v3 = await existingPending2;
104
+ setLib(v3);
105
+ return v3;
106
+ }
107
+ const task2 = Promise.resolve().then(() => entry.loader(ctx)).then(
108
+ (v3) => {
109
+ pendingMap.delete(name);
110
+ return v3;
111
+ },
112
+ (err) => {
113
+ pendingMap.delete(name);
114
+ throw err;
115
+ }
116
+ );
117
+ pendingMap.set(name, task2);
118
+ const v2 = await task2;
119
+ setLib(v2);
120
+ return v2;
121
+ }
122
+ if (__runjsLibResolvedCache.has(name)) {
123
+ const v2 = __runjsLibResolvedCache.get(name);
124
+ setLib(v2);
125
+ return v2;
126
+ }
127
+ const existingPending = __runjsLibPendingCache.get(name);
128
+ if (existingPending) {
129
+ const v2 = await existingPending;
130
+ setLib(v2);
131
+ return v2;
132
+ }
133
+ const task = Promise.resolve().then(() => entry.loader(ctx)).then(
134
+ (v2) => {
135
+ __runjsLibResolvedCache.set(name, v2);
136
+ __runjsLibPendingCache.delete(name);
137
+ return v2;
138
+ },
139
+ (err) => {
140
+ __runjsLibPendingCache.delete(name);
141
+ throw err;
142
+ }
143
+ );
144
+ __runjsLibPendingCache.set(name, task);
145
+ const v = await task;
146
+ setLib(v);
147
+ return v;
148
+ }
149
+ __name(__runjsEnsureLib, "__runjsEnsureLib");
150
+ function setupRunJSLibAPIs(ctx) {
151
+ if (!ctx || typeof ctx !== "object") return;
152
+ if (typeof ctx.defineMethod !== "function") return;
153
+ ctx.defineMethod("__ensureLib", async function(name) {
154
+ if (typeof name !== "string" || !name) return void 0;
155
+ return await __runjsEnsureLib(this, name);
156
+ });
157
+ ctx.defineMethod("__ensureLibs", async function(names) {
158
+ if (!Array.isArray(names)) return;
159
+ for (const n of names) {
160
+ if (typeof n !== "string" || !n) continue;
161
+ await __runjsEnsureLib(this, n);
162
+ }
163
+ });
164
+ }
165
+ __name(setupRunJSLibAPIs, "setupRunJSLibAPIs");
166
+ const DEFAULT_RUNJS_LIBS = [
167
+ { name: "React", cache: "context", loader: /* @__PURE__ */ __name((ctx) => __runjsGetCtxValue(ctx, "React"), "loader") },
168
+ { name: "ReactDOM", cache: "context", loader: /* @__PURE__ */ __name((ctx) => __runjsGetCtxValue(ctx, "ReactDOM"), "loader") },
169
+ { name: "antd", cache: "context", loader: /* @__PURE__ */ __name((ctx) => __runjsGetCtxValue(ctx, "antd"), "loader") },
170
+ { name: "dayjs", cache: "context", loader: /* @__PURE__ */ __name((ctx) => __runjsGetCtxValue(ctx, "dayjs"), "loader") },
171
+ { name: "antdIcons", cache: "global", loader: /* @__PURE__ */ __name(() => antdIcons, "loader") },
172
+ { name: "lodash", cache: "global", loader: /* @__PURE__ */ __name(() => import("lodash").then((m) => m.default || m), "loader") },
173
+ { name: "formula", cache: "global", loader: /* @__PURE__ */ __name(() => import("@formulajs/formulajs").then((m) => m.default || m), "loader") },
174
+ { name: "math", cache: "global", loader: /* @__PURE__ */ __name(() => import("mathjs").then((m) => m), "loader") }
175
+ ];
176
+ let __defaultRunJSLibsRegistered = false;
177
+ function ensureDefaultRunJSLibsRegistered() {
178
+ if (__defaultRunJSLibsRegistered) return;
179
+ __defaultRunJSLibsRegistered = true;
180
+ for (const { name, loader, cache } of DEFAULT_RUNJS_LIBS) {
181
+ if (__runjsLibRegistry.has(name)) continue;
182
+ registerRunJSLib(name, loader, { cache });
183
+ }
184
+ }
185
+ __name(ensureDefaultRunJSLibsRegistered, "ensureDefaultRunJSLibsRegistered");
186
+ function resolveRegisteredLibSync(ctx, name) {
187
+ const entry = __runjsLibRegistry.get(name);
188
+ if (!entry) return void 0;
189
+ if (entry.cache === "global" && __runjsLibResolvedCache.has(name)) {
190
+ return __runjsLibResolvedCache.get(name);
191
+ }
192
+ const v = entry.loader(ctx);
193
+ if (__runjsIsPromiseLike(v)) return void 0;
194
+ if (entry.cache === "global") __runjsLibResolvedCache.set(name, v);
195
+ return v;
196
+ }
197
+ __name(resolveRegisteredLibSync, "resolveRegisteredLibSync");
198
+ function setupRunJSLibs(ctx) {
199
+ if (!ctx || typeof ctx !== "object") return;
200
+ if (typeof ctx.defineProperty !== "function") return;
201
+ ensureDefaultRunJSLibsRegistered();
202
+ const libs = {};
203
+ for (const { name } of DEFAULT_RUNJS_LIBS) {
204
+ Object.defineProperty(libs, name, {
205
+ configurable: true,
206
+ enumerable: true,
207
+ get() {
208
+ const v = resolveRegisteredLibSync(ctx, name);
209
+ Object.defineProperty(libs, name, {
210
+ configurable: true,
211
+ enumerable: true,
212
+ writable: true,
213
+ value: v
214
+ });
215
+ return v;
216
+ }
217
+ });
218
+ }
219
+ ctx.defineProperty("libs", { value: libs });
220
+ setupRunJSLibAPIs(ctx);
221
+ }
222
+ __name(setupRunJSLibs, "setupRunJSLibs");
223
+ function setRunJSLibOverride(ctx, name, value, options) {
224
+ const topLevelKey = (options == null ? void 0 : options.topLevelKey) === false ? null : (options == null ? void 0 : options.topLevelKey) || name;
225
+ if (topLevelKey) {
226
+ ctx.defineProperty(topLevelKey, { value });
227
+ }
228
+ const libs = ctx.libs;
229
+ Object.defineProperty(libs, name, {
230
+ configurable: true,
231
+ enumerable: true,
232
+ writable: true,
233
+ value
234
+ });
235
+ }
236
+ __name(setRunJSLibOverride, "setRunJSLibOverride");
237
+ function buildMixedReactHint(options) {
238
+ var _a;
239
+ const { ctx, internalReact, internalAntd } = options;
240
+ const lines = [];
241
+ const externalReact = ctx.React && ctx.React !== internalReact;
242
+ const internalReactDOM = !!((_a = ctx.ReactDOM) == null ? void 0 : _a.__nbRunjsInternalShim);
243
+ const usingInternalAntd = ctx.antd === internalAntd;
244
+ const externalAntd = ctx.antd && ctx.antd !== internalAntd;
245
+ if (externalReact && internalReactDOM) {
246
+ const reactInfo = ctx.__runjsExternalReact;
247
+ const v = reactInfo == null ? void 0 : reactInfo.version;
248
+ const domHint = v ? `react-dom@${v}/client` : "react-dom/client";
249
+ lines.push(
250
+ `- You have imported external React, but you're still using the built-in ReactDOM Root; please also run: await ctx.importAsync("${domHint}")`
251
+ );
252
+ }
253
+ if (externalAntd && !externalReact) {
254
+ lines.push(
255
+ `- You have imported external antd, but you're still using the built-in React; please run: await ctx.importAsync("react@18.x")`
256
+ );
257
+ lines.push(`- And make sure ReactDOM matches: await ctx.importAsync("react-dom@18.x/client")`);
258
+ }
259
+ if (externalReact && usingInternalAntd) {
260
+ lines.push(
261
+ `- You have imported external React, but you're still using the built-in antd; please switch to: await ctx.importAsync("antd@5.x")`
262
+ );
263
+ lines.push(`- If you use icon components, also import: await ctx.importAsync("@ant-design/icons@5.x")`);
264
+ }
265
+ return lines.length ? `
266
+
267
+ [RunJS Hint]
268
+ ${lines.join("\n")}` : "";
269
+ }
270
+ __name(buildMixedReactHint, "buildMixedReactHint");
271
+ function isReactHooksDispatcherNullError(err) {
272
+ const msg = String((err == null ? void 0 : err.message) || "");
273
+ if (!msg) return false;
274
+ if (!/Cannot read (?:properties|property) of (?:null|undefined) \(reading 'use[A-Za-z]+'\)/.test(msg)) return false;
275
+ const stack = String((err == null ? void 0 : err.stack) || "");
276
+ if (!stack) return false;
277
+ return /(?:^|\W)react@[^/\s)]+/i.test(stack) || /react\.mjs/i.test(stack) || /react\.(?:development|production)/i.test(stack);
278
+ }
279
+ __name(isReactHooksDispatcherNullError, "isReactHooksDispatcherNullError");
280
+ function extractReactVersionFromStack(err) {
281
+ var _a;
282
+ const stack = String((err == null ? void 0 : err.stack) || "");
283
+ if (!stack) return void 0;
284
+ const m = stack.match(/(?:^|\W)react@([^/\s)]+)/i);
285
+ const v = (_a = m == null ? void 0 : m[1]) == null ? void 0 : _a.trim();
286
+ return v || void 0;
287
+ }
288
+ __name(extractReactVersionFromStack, "extractReactVersionFromStack");
289
+ function buildReactDispatcherNullHint(options) {
290
+ const { ctx, internalReact, internalAntd, err } = options;
291
+ if (!isReactHooksDispatcherNullError(err)) return "";
292
+ const v = extractReactVersionFromStack(err);
293
+ const lines = [];
294
+ lines.push(`- This looks like a React Hooks crash caused by multiple React instances (hook dispatcher is null).`);
295
+ if (v) {
296
+ lines.push(`- Your stack trace includes external React: react@${v}.`);
297
+ lines.push(
298
+ `- Fix: import the same React BEFORE you read ctx.libs.React / call hooks / import React-based libs: await ctx.importAsync("react@${v}")`
299
+ );
300
+ } else {
301
+ lines.push(
302
+ `- Fix: import external React BEFORE you read ctx.libs.React / call hooks / import React-based libs (use the same version shown in the stack trace).`
303
+ );
304
+ }
305
+ const usingInternalAntd = ctx.antd === internalAntd;
306
+ if (usingInternalAntd) {
307
+ lines.push(`- If you use antd components, also switch to external antd: await ctx.importAsync("antd@5.x")`);
308
+ lines.push(`- If you use icon components, also import: await ctx.importAsync("@ant-design/icons@5.x")`);
309
+ }
310
+ return lines.length ? `
311
+
312
+ [RunJS Hint]
313
+ ${lines.join("\n")}` : "";
314
+ }
315
+ __name(buildReactDispatcherNullHint, "buildReactDispatcherNullHint");
316
+ function wrapErrorWithHint(err, messageWithHint) {
317
+ const e = new Error(messageWithHint);
318
+ e.cause = err;
319
+ try {
320
+ const name = typeof (err == null ? void 0 : err.name) === "string" ? err.name : "";
321
+ if (name) e.name = name;
322
+ } catch (_) {
323
+ }
324
+ try {
325
+ const stack = typeof (err == null ? void 0 : err.stack) === "string" ? err.stack : "";
326
+ if (stack) {
327
+ const lines = String(stack).split("\n");
328
+ if (lines.length) {
329
+ lines[0] = `${e.name}: ${messageWithHint}`;
330
+ e.stack = lines.join("\n");
331
+ }
332
+ }
333
+ } catch (_) {
334
+ }
335
+ return e;
336
+ }
337
+ __name(wrapErrorWithHint, "wrapErrorWithHint");
338
+ function getRunjsErrorBoundary(ReactLike) {
339
+ if (!ReactLike) return null;
340
+ const cached = __runjsErrorBoundaryByReact.get(ReactLike);
341
+ if (cached) return cached;
342
+ if (typeof ReactLike.createElement !== "function") return null;
343
+ const Base = ReactLike.Component;
344
+ if (typeof Base !== "function") return null;
345
+ const _RunjsErrorBoundary = class _RunjsErrorBoundary extends Base {
346
+ static getDerivedStateFromError(error) {
347
+ return { error };
348
+ }
349
+ state = {};
350
+ componentDidCatch(error) {
351
+ var _a, _b, _c;
352
+ try {
353
+ const enhance = (_a = this.props) == null ? void 0 : _a.enhanceReactError;
354
+ const enhanced = typeof enhance === "function" ? enhance(error) : error;
355
+ const msg = String((enhanced == null ? void 0 : enhanced.message) || "");
356
+ if (msg && /\[RunJS Hint\]/.test(msg)) {
357
+ console.error(msg);
358
+ const logger = (_c = (_b = this.props) == null ? void 0 : _b.ctx) == null ? void 0 : _c.logger;
359
+ if (logger && typeof logger.error === "function") {
360
+ logger.error(msg);
361
+ }
362
+ }
363
+ } catch (_) {
364
+ }
365
+ }
366
+ componentDidUpdate(prevProps) {
367
+ var _a, _b;
368
+ if ((prevProps == null ? void 0 : prevProps.resetKey) !== ((_a = this.props) == null ? void 0 : _a.resetKey) && ((_b = this.state) == null ? void 0 : _b.error)) {
369
+ this.setState({ error: void 0 });
370
+ }
371
+ }
372
+ render() {
373
+ var _a, _b;
374
+ const error = (_a = this.state) == null ? void 0 : _a.error;
375
+ if (!error) return this.props.children;
376
+ let msg = "";
377
+ try {
378
+ const enhance = (_b = this.props) == null ? void 0 : _b.enhanceReactError;
379
+ const enhanced = typeof enhance === "function" ? enhance(error) : error;
380
+ msg = String((enhanced == null ? void 0 : enhanced.message) || enhanced || (error == null ? void 0 : error.message) || error || "");
381
+ } catch (_) {
382
+ msg = String((error == null ? void 0 : error.message) || error || "");
383
+ }
384
+ const containerStyle = {
385
+ boxSizing: "border-box",
386
+ padding: 12,
387
+ borderRadius: 6,
388
+ border: "1px solid #ffccc7",
389
+ background: "#fff2f0",
390
+ color: "#a8071a",
391
+ fontSize: 12,
392
+ lineHeight: 1.5,
393
+ maxWidth: "100%",
394
+ overflow: "auto"
395
+ };
396
+ const preStyle = {
397
+ margin: 0,
398
+ whiteSpace: "pre-wrap",
399
+ wordBreak: "break-word",
400
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'
401
+ };
402
+ const titleStyle = { fontWeight: 600, marginBottom: 8 };
403
+ return ReactLike.createElement(
404
+ "div",
405
+ { style: containerStyle },
406
+ ReactLike.createElement("div", { style: titleStyle }, "RunJS render error"),
407
+ ReactLike.createElement("pre", { style: preStyle }, msg)
408
+ );
409
+ }
410
+ };
411
+ __name(_RunjsErrorBoundary, "RunjsErrorBoundary");
412
+ let RunjsErrorBoundary = _RunjsErrorBoundary;
413
+ __runjsErrorBoundaryByReact.set(ReactLike, RunjsErrorBoundary);
414
+ return RunjsErrorBoundary;
415
+ }
416
+ __name(getRunjsErrorBoundary, "getRunjsErrorBoundary");
417
+ function wrapVnodeWithRunjsErrorBoundary(options) {
418
+ const { ctx, vnode, enhanceReactError, resetKey } = options;
419
+ const ReactLike = ctx == null ? void 0 : ctx.React;
420
+ const Boundary = getRunjsErrorBoundary(ReactLike);
421
+ if (!Boundary) return vnode;
422
+ return ReactLike.createElement(Boundary, { ctx, enhanceReactError, resetKey }, vnode);
423
+ }
424
+ __name(wrapVnodeWithRunjsErrorBoundary, "wrapVnodeWithRunjsErrorBoundary");
425
+ function tryRenderWithExternalAntdTheme(options) {
426
+ var _a;
427
+ const { ctx, entry, containerEl, rootMap, unmountContainerRoot, enhanceReactError, internalReact, internalAntd } = options;
428
+ const canUseExternalAntd = !((_a = ctx.ReactDOM) == null ? void 0 : _a.__nbRunjsInternalShim) && ctx.React && ctx.React !== internalReact && ctx.antd && ctx.antd !== internalAntd && typeof ctx.antd.ConfigProvider !== "undefined";
429
+ if (!canUseExternalAntd) {
430
+ if (entry.disposeTheme) {
431
+ try {
432
+ entry.disposeTheme();
433
+ } catch (_) {
434
+ }
435
+ entry.disposeTheme = void 0;
436
+ }
437
+ return false;
438
+ }
439
+ const renderWithExternalAntdTheme = /* @__PURE__ */ __name(() => {
440
+ var _a2, _b, _c, _d, _e, _f, _g;
441
+ const themeToken = (_b = (_a2 = ctx == null ? void 0 : ctx.engine) == null ? void 0 : _a2.context) == null ? void 0 : _b.themeToken;
442
+ const appConfig = (_d = (_c = ctx == null ? void 0 : ctx.engine) == null ? void 0 : _c.context) == null ? void 0 : _d.antdConfig;
443
+ const locale = ((_g = (_f = (_e = ctx == null ? void 0 : ctx.engine) == null ? void 0 : _e.context) == null ? void 0 : _f.locales) == null ? void 0 : _g.antd) || (appConfig == null ? void 0 : appConfig.locale);
444
+ const ConfigProvider = ctx.antd.ConfigProvider;
445
+ const App = ctx.antd.App;
446
+ const configProps = {
447
+ popupMatchSelectWidth: false,
448
+ locale: locale || {}
449
+ };
450
+ if (appConfig && typeof appConfig === "object") {
451
+ if (typeof appConfig.direction !== "undefined") configProps.direction = appConfig.direction;
452
+ if (typeof appConfig.prefixCls === "string") configProps.prefixCls = appConfig.prefixCls;
453
+ if (typeof appConfig.iconPrefixCls === "string") configProps.iconPrefixCls = appConfig.iconPrefixCls;
454
+ if (typeof appConfig.getPopupContainer === "function")
455
+ configProps.getPopupContainer = appConfig.getPopupContainer;
456
+ if (appConfig.theme && typeof appConfig.theme === "object") configProps.theme = appConfig.theme;
457
+ }
458
+ const child = entry.lastVnode;
459
+ const wrapped = App ? ctx.React.createElement(ConfigProvider, configProps, ctx.React.createElement(App, null, child)) : ctx.React.createElement(ConfigProvider, configProps, child);
460
+ entry.root.render(wrapped);
461
+ }, "renderWithExternalAntdTheme");
462
+ if (!entry.disposeTheme) {
463
+ entry.disposeTheme = (0, import_reactive.autorun)(() => {
464
+ try {
465
+ if (containerEl && containerEl.nodeType === 1 && typeof containerEl.isConnected === "boolean" && !containerEl.isConnected && entry.wasConnected) {
466
+ queueMicrotask(() => {
467
+ const cur = rootMap.get(containerEl);
468
+ if (cur === entry) unmountContainerRoot();
469
+ });
470
+ return;
471
+ }
472
+ if (containerEl && containerEl.nodeType === 1 && typeof containerEl.isConnected === "boolean" && containerEl.isConnected) {
473
+ entry.wasConnected = true;
474
+ }
475
+ renderWithExternalAntdTheme();
476
+ } catch (e) {
477
+ throw enhanceReactError(e);
478
+ }
479
+ });
480
+ } else {
481
+ renderWithExternalAntdTheme();
482
+ }
483
+ return true;
484
+ }
485
+ __name(tryRenderWithExternalAntdTheme, "tryRenderWithExternalAntdTheme");
486
+ function externalReactRender(options) {
487
+ const { ctx, entry, vnode, containerEl, rootMap, unmountContainerRoot, internalReact, internalAntd } = options;
488
+ const enhanceReactError = /* @__PURE__ */ __name((err) => {
489
+ const msg = String((err == null ? void 0 : err.message) || err || "");
490
+ if (!msg) return err;
491
+ if (/\[RunJS Hint\]/.test(msg)) return err;
492
+ const invalidHookCall = /invalid hook call/i.test(msg);
493
+ const dispatcherNull = isReactHooksDispatcherNullError(err);
494
+ if (!invalidHookCall && !dispatcherNull) return err;
495
+ const hint = buildMixedReactHint({ ctx, internalReact, internalAntd }) || buildReactDispatcherNullHint({ ctx, internalReact, internalAntd, err });
496
+ if (!hint) return err;
497
+ return wrapErrorWithHint(err, `${msg}${hint}`);
498
+ }, "enhanceReactError");
499
+ try {
500
+ entry.__nbRunjsRenderSeq = (entry.__nbRunjsRenderSeq || 0) + 1;
501
+ entry.lastVnode = wrapVnodeWithRunjsErrorBoundary({
502
+ ctx,
503
+ vnode,
504
+ enhanceReactError,
505
+ resetKey: entry.__nbRunjsRenderSeq
506
+ });
507
+ const renderedWithExternalAntdTheme = tryRenderWithExternalAntdTheme({
508
+ ctx,
509
+ entry,
510
+ containerEl,
511
+ rootMap,
512
+ unmountContainerRoot,
513
+ enhanceReactError,
514
+ internalReact,
515
+ internalAntd
516
+ });
517
+ if (!renderedWithExternalAntdTheme) {
518
+ entry.root.render(entry.lastVnode);
519
+ }
520
+ return entry.root;
521
+ } catch (e) {
522
+ throw enhanceReactError(e);
523
+ }
524
+ }
525
+ __name(externalReactRender, "externalReactRender");
526
+ // Annotate the CommonJS export names for ESM import in node:
527
+ 0 && (module.exports = {
528
+ externalReactRender,
529
+ registerRunJSLib,
530
+ setRunJSLibOverride,
531
+ setupRunJSLibs
532
+ });
@@ -22,6 +22,8 @@ export interface LifecycleEvent {
22
22
  error?: any;
23
23
  inputArgs?: Record<string, any>;
24
24
  result?: any;
25
+ flowKey?: string;
26
+ stepKey?: string;
25
27
  }
26
28
  export declare class ModelOperationScheduler {
27
29
  private engine;
@@ -125,32 +125,32 @@ const _ModelOperationScheduler = class _ModelOperationScheduler {
125
125
  bindEngineLifecycle() {
126
126
  const emitter = this.engine.emitter;
127
127
  if (!emitter || typeof emitter.on !== "function") return;
128
- const onCreated = /* @__PURE__ */ __name((e) => {
129
- this.processLifecycleEvent(e.uid, { ...e, type: "created" });
128
+ const onCreated = /* @__PURE__ */ __name(async (e) => {
129
+ await this.processLifecycleEvent(e.uid, { ...e, type: "created" });
130
130
  }, "onCreated");
131
131
  emitter.on("model:created", onCreated);
132
132
  this.unbindHandlers.push(() => emitter.off("model:created", onCreated));
133
- const onMounted = /* @__PURE__ */ __name((e) => {
134
- this.processLifecycleEvent(e.uid, { ...e, type: "mounted" });
133
+ const onMounted = /* @__PURE__ */ __name(async (e) => {
134
+ await this.processLifecycleEvent(e.uid, { ...e, type: "mounted" });
135
135
  }, "onMounted");
136
136
  emitter.on("model:mounted", onMounted);
137
137
  this.unbindHandlers.push(() => emitter.off("model:mounted", onMounted));
138
- const onGenericBeforeStart = /* @__PURE__ */ __name((e) => {
139
- this.processLifecycleEvent(e.uid, { ...e, type: "event:beforeRender:start" });
138
+ const onGenericBeforeStart = /* @__PURE__ */ __name(async (e) => {
139
+ await this.processLifecycleEvent(e.uid, { ...e, type: "event:beforeRender:start" });
140
140
  }, "onGenericBeforeStart");
141
141
  emitter.on("model:event:beforeRender:start", onGenericBeforeStart);
142
142
  this.unbindHandlers.push(() => emitter.off("model:event:beforeRender:start", onGenericBeforeStart));
143
- const onGenericBeforeEnd = /* @__PURE__ */ __name((e) => {
144
- this.processLifecycleEvent(e.uid, { ...e, type: "event:beforeRender:end" });
143
+ const onGenericBeforeEnd = /* @__PURE__ */ __name(async (e) => {
144
+ await this.processLifecycleEvent(e.uid, { ...e, type: "event:beforeRender:end" });
145
145
  }, "onGenericBeforeEnd");
146
146
  emitter.on("model:event:beforeRender:end", onGenericBeforeEnd);
147
147
  this.unbindHandlers.push(() => emitter.off("model:event:beforeRender:end", onGenericBeforeEnd));
148
- const onUnmounted = /* @__PURE__ */ __name((e) => {
149
- this.processLifecycleEvent(e.uid, { ...e, type: "unmounted" });
148
+ const onUnmounted = /* @__PURE__ */ __name(async (e) => {
149
+ await this.processLifecycleEvent(e.uid, { ...e, type: "unmounted" });
150
150
  }, "onUnmounted");
151
151
  emitter.on("model:unmounted", onUnmounted);
152
152
  this.unbindHandlers.push(() => emitter.off("model:unmounted", onUnmounted));
153
- const onDestroyed = /* @__PURE__ */ __name((e) => {
153
+ const onDestroyed = /* @__PURE__ */ __name(async (e) => {
154
154
  const targetBucket = this.itemsByTargetUid.get(e.uid);
155
155
  const event = { ...e, type: "destroyed" };
156
156
  if (targetBucket && targetBucket.size) {
@@ -159,7 +159,7 @@ const _ModelOperationScheduler = class _ModelOperationScheduler {
159
159
  const it = this.itemsById.get(id);
160
160
  if (!it) continue;
161
161
  if (this.shouldTrigger(it.options.when, event)) {
162
- void this.tryExecuteOnce(id, event);
162
+ await this.tryExecuteOnce(id, event);
163
163
  } else {
164
164
  this.internalCancel(id);
165
165
  }
@@ -177,14 +177,14 @@ const _ModelOperationScheduler = class _ModelOperationScheduler {
177
177
  if (this.subscribedEventNames.has(name)) return;
178
178
  this.subscribedEventNames.add(name);
179
179
  const emitter = this.engine.emitter;
180
- const onStart = /* @__PURE__ */ __name((e) => {
181
- this.processLifecycleEvent(e.uid, { ...e, type: `event:${name}:start` });
180
+ const onStart = /* @__PURE__ */ __name(async (e) => {
181
+ await this.processLifecycleEvent(e.uid, { ...e, type: `event:${name}:start` });
182
182
  }, "onStart");
183
- const onEnd = /* @__PURE__ */ __name((e) => {
184
- this.processLifecycleEvent(e.uid, { ...e, type: `event:${name}:end` });
183
+ const onEnd = /* @__PURE__ */ __name(async (e) => {
184
+ await this.processLifecycleEvent(e.uid, { ...e, type: `event:${name}:end` });
185
185
  }, "onEnd");
186
- const onError = /* @__PURE__ */ __name((e) => {
187
- this.processLifecycleEvent(e.uid, { ...e, type: `event:${name}:error` });
186
+ const onError = /* @__PURE__ */ __name(async (e) => {
187
+ await this.processLifecycleEvent(e.uid, { ...e, type: `event:${name}:error` });
188
188
  }, "onError");
189
189
  emitter.on(`model:event:${name}:start`, onStart);
190
190
  emitter.on(`model:event:${name}:end`, onEnd);
@@ -195,11 +195,11 @@ const _ModelOperationScheduler = class _ModelOperationScheduler {
195
195
  }
196
196
  parseEventWhen(when) {
197
197
  if (!when || typeof when !== "string") return null;
198
- const m = /^event:([^:]+):(start|end|error)$/.exec(when);
198
+ const m = /^event:(.+):(start|end|error)$/.exec(when);
199
199
  if (!m) return null;
200
200
  return { name: m[1], phase: m[2] };
201
201
  }
202
- processLifecycleEvent(targetUid, event) {
202
+ async processLifecycleEvent(targetUid, event) {
203
203
  const targetBucket = this.itemsByTargetUid.get(targetUid);
204
204
  if (!targetBucket || targetBucket.size === 0) return;
205
205
  const ids = Array.from(targetBucket.keys());
@@ -208,7 +208,7 @@ const _ModelOperationScheduler = class _ModelOperationScheduler {
208
208
  if (!item) continue;
209
209
  const should = this.shouldTrigger(item.options.when, event);
210
210
  if (!should) continue;
211
- void this.tryExecuteOnce(id, event);
211
+ await this.tryExecuteOnce(id, event);
212
212
  }
213
213
  }
214
214
  shouldTrigger(when, event) {
package/lib/types.d.ts CHANGED
@@ -166,12 +166,27 @@ export interface ActionDefinition<TModel extends FlowModel = FlowModel, TCtx ext
166
166
  * - 允许扩展字符串以保持向后兼容。
167
167
  */
168
168
  export type FlowEventName = 'click' | 'submit' | 'reset' | 'remove' | 'openView' | 'dropdownOpen' | 'popupScroll' | 'search' | 'customRequest' | 'collapseToggle' | (string & {});
169
+ /**
170
+ * 事件流的执行时机(phase)。
171
+ *
172
+ * 说明:
173
+ * - 缺省(phase 未配置)表示保持现有行为;
174
+ * - 当配置了 phase 时,运行时会将其映射为 `scheduleModelOperation` 的 `when` 锚点;
175
+ * - phase 同时适用于动态事件流(实例级)与静态流(内置)。
176
+ */
177
+ export type FlowEventPhase = 'beforeAllFlows' | 'afterAllFlows' | 'beforeFlow' | 'afterFlow' | 'beforeStep' | 'afterStep';
169
178
  /**
170
179
  * Flow 事件类型(供 FlowDefinitionOptions.on 使用)。
171
180
  */
172
181
  export type FlowEvent<TModel extends FlowModel = FlowModel> = FlowEventName | {
173
182
  eventName: FlowEventName;
174
183
  defaultParams?: Record<string, any>;
184
+ /** 动态事件流的执行时机(默认 beforeAllFlows) */
185
+ phase?: FlowEventPhase;
186
+ /** phase 为 beforeFlow/afterFlow/beforeStep/afterStep 时使用 */
187
+ flowKey?: string;
188
+ /** phase 为 beforeStep/afterStep 时使用 */
189
+ stepKey?: string;
175
190
  };
176
191
  /**
177
192
  * 事件分发选项。
@@ -87,6 +87,7 @@ function createMetaBaseProperties(field) {
87
87
  return {
88
88
  title: field.title || field.name,
89
89
  interface: field.interface,
90
+ options: field.options,
90
91
  uiSchema: field.uiSchema || {}
91
92
  };
92
93
  }