@nocobase/flow-engine 2.0.0-alpha.67 → 2.0.0-alpha.69
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.
- package/lib/BlockScopedFlowEngine.js +0 -1
- package/lib/ViewScopedFlowEngine.js +3 -0
- package/lib/components/variables/VariableInput.js +8 -2
- package/lib/data-source/index.js +3 -0
- package/lib/flowContext.d.ts +64 -0
- package/lib/flowContext.js +138 -64
- package/lib/flowEngine.d.ts +21 -0
- package/lib/flowEngine.js +38 -0
- package/lib/index.d.ts +5 -1
- package/lib/index.js +18 -0
- package/lib/models/flowModel.js +12 -1
- package/lib/provider.js +5 -5
- package/lib/resources/baseRecordResource.d.ts +5 -0
- package/lib/resources/baseRecordResource.js +24 -0
- package/lib/resources/multiRecordResource.d.ts +1 -0
- package/lib/resources/multiRecordResource.js +11 -4
- package/lib/resources/singleRecordResource.js +2 -0
- package/lib/resources/sqlResource.d.ts +1 -0
- package/lib/resources/sqlResource.js +8 -3
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +12 -2
- package/lib/runjs-context/contexts/JSBlockRunJSContext.js +2 -2
- package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.d.ts +16 -0
- package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +125 -0
- package/lib/runjs-context/contexts/JSItemRunJSContext.js +12 -2
- package/lib/runjs-context/contexts/base.js +691 -23
- package/lib/runjs-context/contributions.d.ts +33 -0
- package/lib/runjs-context/contributions.js +88 -0
- package/lib/runjs-context/setup.js +6 -0
- package/lib/runjs-context/snippets/index.d.ts +11 -1
- package/lib/runjs-context/snippets/index.js +61 -40
- package/lib/runjsLibs.d.ts +13 -0
- package/lib/runjsLibs.js +309 -0
- package/lib/utils/createCollectionContextMeta.js +1 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +5 -0
- package/lib/utils/resolveModuleUrl.d.ts +58 -0
- package/lib/utils/resolveModuleUrl.js +65 -0
- package/lib/utils/runjsModuleLoader.d.ts +58 -0
- package/lib/utils/runjsModuleLoader.js +422 -0
- package/lib/utils/safeGlobals.d.ts +5 -9
- package/lib/utils/safeGlobals.js +129 -17
- package/lib/views/useDialog.js +7 -1
- package/lib/views/useDrawer.js +7 -1
- package/lib/views/usePage.js +10 -1
- package/lib/views/viewEvents.d.ts +17 -0
- package/lib/views/viewEvents.js +90 -0
- package/package.json +4 -4
- package/src/BlockScopedFlowEngine.ts +2 -5
- package/src/ViewScopedFlowEngine.ts +4 -0
- package/src/__tests__/flowContext.test.ts +12 -0
- package/src/__tests__/flowEngine.dataSourceDirty.test.ts +63 -0
- package/src/__tests__/runjsContext.test.ts +4 -1
- package/src/__tests__/runjsExternalLibs.test.ts +242 -0
- package/src/__tests__/runjsLocales.test.ts +4 -1
- package/src/components/variables/VariableInput.tsx +8 -2
- package/src/data-source/index.ts +3 -0
- package/src/flowContext.ts +226 -65
- package/src/flowEngine.ts +41 -0
- package/src/index.ts +12 -1
- package/src/models/flowModel.tsx +13 -1
- package/src/provider.tsx +7 -6
- package/src/resources/__tests__/multiRecordResource.test.ts +44 -0
- package/src/resources/__tests__/sqlResource.test.ts +60 -0
- package/src/resources/baseRecordResource.ts +31 -0
- package/src/resources/multiRecordResource.ts +11 -4
- package/src/resources/singleRecordResource.ts +3 -0
- package/src/resources/sqlResource.ts +8 -3
- package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +10 -0
- package/src/runjs-context/contexts/JSBlockRunJSContext.ts +6 -2
- package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +106 -0
- package/src/runjs-context/contexts/JSItemRunJSContext.ts +10 -0
- package/src/runjs-context/contexts/base.ts +698 -30
- package/src/runjs-context/contributions.ts +88 -0
- package/src/runjs-context/setup.ts +6 -0
- package/src/runjs-context/snippets/index.ts +75 -41
- package/src/runjsLibs.ts +404 -0
- package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +38 -0
- package/src/utils/__tests__/safeGlobals.test.ts +49 -2
- package/src/utils/createCollectionContextMeta.ts +1 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/resolveModuleUrl.ts +91 -0
- package/src/utils/runjsModuleLoader.ts +553 -0
- package/src/utils/safeGlobals.ts +133 -16
- package/src/views/__tests__/useDialog.closeDestroy.test.tsx +35 -4
- package/src/views/__tests__/viewEvents.resolveOpenerEngine.test.ts +28 -0
- package/src/views/useDialog.tsx +8 -0
- package/src/views/useDrawer.tsx +8 -0
- package/src/views/usePage.tsx +13 -0
- package/src/views/viewEvents.ts +55 -0
|
@@ -37,7 +37,6 @@ function createBlockScopedEngine(parent) {
|
|
|
37
37
|
local.setModelRepository(parent.modelRepository);
|
|
38
38
|
}
|
|
39
39
|
local.context.addDelegate(parent.context);
|
|
40
|
-
const originalUnlink = local.unlinkFromStack.bind(local);
|
|
41
40
|
local.unlinkFromStack = function() {
|
|
42
41
|
const prev = local._previousEngine;
|
|
43
42
|
const next = local._nextEngine;
|
|
@@ -31,8 +31,10 @@ __export(ViewScopedFlowEngine_exports, {
|
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(ViewScopedFlowEngine_exports);
|
|
33
33
|
var import_flowEngine = require("./flowEngine");
|
|
34
|
+
var import_viewEvents = require("./views/viewEvents");
|
|
34
35
|
function createViewScopedEngine(parent) {
|
|
35
36
|
const local = new import_flowEngine.FlowEngine();
|
|
37
|
+
Object.defineProperty(local, import_viewEvents.ENGINE_SCOPE_KEY, { value: import_viewEvents.VIEW_ENGINE_SCOPE, configurable: true });
|
|
36
38
|
if (parent.modelRepository) {
|
|
37
39
|
local.setModelRepository(parent.modelRepository);
|
|
38
40
|
}
|
|
@@ -48,6 +50,7 @@ function createViewScopedEngine(parent) {
|
|
|
48
50
|
"_applyFlowCache",
|
|
49
51
|
"executor",
|
|
50
52
|
"context",
|
|
53
|
+
import_viewEvents.ENGINE_SCOPE_KEY,
|
|
51
54
|
"previousEngine",
|
|
52
55
|
"nextEngine",
|
|
53
56
|
// 调度器与事件总线局部化
|
|
@@ -230,12 +230,18 @@ const VariableInputComponent = /* @__PURE__ */ __name(({
|
|
|
230
230
|
);
|
|
231
231
|
const handleVariableSelect = (0, import_react.useCallback)(
|
|
232
232
|
(variableValue, metaTreeNode) => {
|
|
233
|
+
if (!metaTreeNode && variableValue === "") {
|
|
234
|
+
const cleared = clearValue !== void 0 ? clearValue : null;
|
|
235
|
+
setInnerValue(cleared);
|
|
236
|
+
emitChange(cleared);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
233
239
|
setCurrentMetaTreeNode(metaTreeNode);
|
|
234
240
|
const finalValue = (resolveValueFromPath == null ? void 0 : resolveValueFromPath(metaTreeNode)) || variableValue;
|
|
235
241
|
setInnerValue(finalValue);
|
|
236
242
|
emitChange(finalValue, metaTreeNode);
|
|
237
243
|
},
|
|
238
|
-
[emitChange, resolveValueFromPath]
|
|
244
|
+
[emitChange, resolveValueFromPath, clearValue]
|
|
239
245
|
);
|
|
240
246
|
const { disabled } = restProps;
|
|
241
247
|
const handleClear = (0, import_react.useCallback)(() => {
|
|
@@ -265,7 +271,7 @@ const VariableInputComponent = /* @__PURE__ */ __name(({
|
|
|
265
271
|
}, [restProps]);
|
|
266
272
|
const inputProps = (0, import_react.useMemo)(() => {
|
|
267
273
|
const baseProps = {
|
|
268
|
-
value: innerValue ?? "",
|
|
274
|
+
value: ValueComponent === import_antd.Input ? innerValue ?? "" : innerValue,
|
|
269
275
|
onChange: handleInputChange,
|
|
270
276
|
disabled
|
|
271
277
|
};
|
package/lib/data-source/index.js
CHANGED
|
@@ -400,6 +400,9 @@ const _Collection = class _Collection {
|
|
|
400
400
|
if (typeof this.filterTargetKey === "string") {
|
|
401
401
|
return record[this.filterTargetKey];
|
|
402
402
|
}
|
|
403
|
+
if (Array.isArray(this.filterTargetKey) && this.filterTargetKey.length === 1) {
|
|
404
|
+
return record[this.filterTargetKey[0]];
|
|
405
|
+
}
|
|
403
406
|
return import_lodash.default.pick(record, this.filterTargetKey);
|
|
404
407
|
}
|
|
405
408
|
get titleableFields() {
|
package/lib/flowContext.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export interface MetaTreeNode {
|
|
|
31
31
|
title: string;
|
|
32
32
|
type: string;
|
|
33
33
|
interface?: string;
|
|
34
|
+
options?: any;
|
|
34
35
|
uiSchema?: ISchema;
|
|
35
36
|
render?: (props: any) => JSX.Element;
|
|
36
37
|
paths: string[];
|
|
@@ -44,6 +45,7 @@ export interface PropertyMeta {
|
|
|
44
45
|
type: string;
|
|
45
46
|
title: string;
|
|
46
47
|
interface?: string;
|
|
48
|
+
options?: any;
|
|
47
49
|
uiSchema?: ISchema;
|
|
48
50
|
render?: (props: any) => JSX.Element;
|
|
49
51
|
sort?: number;
|
|
@@ -141,6 +143,29 @@ export declare class FlowContext {
|
|
|
141
143
|
* @returns 属性定义选项,或 undefined(未定义)
|
|
142
144
|
*/
|
|
143
145
|
getPropertyOptions(key: string): PropertyOptions | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* 获取当前上下文可用的顶层 API 信息(主要用于编辑器补全/工具)。
|
|
148
|
+
*
|
|
149
|
+
* 注意:
|
|
150
|
+
* - 目前返回值以“尽量可用”为目标,允许不完整。
|
|
151
|
+
* - 该方法不会展开变量 meta(变量结构应由 `getPropertyMetaTree()`/VariableInput 等机制负责)。
|
|
152
|
+
*/
|
|
153
|
+
getApiInfos(options?: {
|
|
154
|
+
version?: string;
|
|
155
|
+
}): Promise<Record<string, any>>;
|
|
156
|
+
/**
|
|
157
|
+
* 变量结构信息(保留给编辑器/工具使用)。
|
|
158
|
+
* 当前实现为保底空对象,避免 RunJS doc 中补全到该方法时调用报错。
|
|
159
|
+
*/
|
|
160
|
+
getVarInfos(_options?: {
|
|
161
|
+
path?: string | string[];
|
|
162
|
+
maxDepth?: number;
|
|
163
|
+
}): Promise<Record<string, any>>;
|
|
164
|
+
/**
|
|
165
|
+
* 运行时环境信息(保留给编辑器/工具使用)。
|
|
166
|
+
* 当前实现为保底空对象,避免 RunJS doc 中补全到该方法时调用报错。
|
|
167
|
+
*/
|
|
168
|
+
getEnvInfos(): Promise<Record<string, any>>;
|
|
144
169
|
}
|
|
145
170
|
declare class BaseFlowEngineContext extends FlowContext {
|
|
146
171
|
router: Router;
|
|
@@ -156,6 +181,7 @@ declare class BaseFlowEngineContext extends FlowContext {
|
|
|
156
181
|
*/
|
|
157
182
|
renderJson: (template: JSONValue) => Promise<any>;
|
|
158
183
|
resolveJsonTemplate: (template: JSONValue) => Promise<any>;
|
|
184
|
+
getVar: (path: string) => Promise<any>;
|
|
159
185
|
runjs: (code: string, variables?: Record<string, any>, options?: JSRunnerOptions) => Promise<any>;
|
|
160
186
|
getAction: <TModel extends FlowModel = FlowModel, TCtx extends FlowContext = FlowContext>(name: string) => ActionDefinition<TModel, TCtx> | undefined;
|
|
161
187
|
getActions: <TModel extends FlowModel = FlowModel, TCtx extends FlowContext = FlowContext>() => Map<string, ActionDefinition<TModel, TCtx>>;
|
|
@@ -217,22 +243,60 @@ export declare class FlowRuntimeContext<TModel extends FlowModel = FlowModel, TM
|
|
|
217
243
|
get mode(): TMode;
|
|
218
244
|
}
|
|
219
245
|
export type FlowSettingsContext<TModel extends FlowModel = FlowModel> = FlowRuntimeContext<TModel, 'settings'>;
|
|
246
|
+
export type FlowContextDocRef = string | {
|
|
247
|
+
url: string;
|
|
248
|
+
title?: string;
|
|
249
|
+
};
|
|
250
|
+
export type FlowDeprecationDoc = boolean | {
|
|
251
|
+
message?: string;
|
|
252
|
+
replacedBy?: string | string[];
|
|
253
|
+
since?: string;
|
|
254
|
+
removedIn?: string;
|
|
255
|
+
ref?: FlowContextDocRef;
|
|
256
|
+
};
|
|
257
|
+
export type FlowContextDocParam = {
|
|
258
|
+
name: string;
|
|
259
|
+
description?: string;
|
|
260
|
+
type?: string;
|
|
261
|
+
optional?: boolean;
|
|
262
|
+
default?: JSONValue;
|
|
263
|
+
};
|
|
264
|
+
export type FlowContextDocReturn = {
|
|
265
|
+
description?: string;
|
|
266
|
+
type?: string;
|
|
267
|
+
};
|
|
220
268
|
export type RunJSDocCompletionDoc = {
|
|
221
269
|
insertText?: string;
|
|
222
270
|
};
|
|
271
|
+
export type RunJSDocHiddenDoc = boolean | ((ctx: any) => boolean | Promise<boolean>);
|
|
272
|
+
export type RunJSDocHiddenOrPathsDoc = boolean | string[] | ((ctx: any) => boolean | string[] | Promise<boolean | string[]>);
|
|
223
273
|
export type RunJSDocPropertyDoc = string | {
|
|
224
274
|
description?: string;
|
|
225
275
|
detail?: string;
|
|
226
276
|
type?: string;
|
|
227
277
|
examples?: string[];
|
|
228
278
|
completion?: RunJSDocCompletionDoc;
|
|
279
|
+
ref?: FlowContextDocRef;
|
|
280
|
+
deprecated?: FlowDeprecationDoc;
|
|
281
|
+
params?: FlowContextDocParam[];
|
|
282
|
+
returns?: FlowContextDocReturn;
|
|
229
283
|
properties?: Record<string, RunJSDocPropertyDoc>;
|
|
284
|
+
hidden?: RunJSDocHiddenOrPathsDoc;
|
|
285
|
+
disabled?: boolean | ((ctx: any) => boolean | Promise<boolean>);
|
|
286
|
+
disabledReason?: string | ((ctx: any) => string | undefined | Promise<string | undefined>);
|
|
230
287
|
};
|
|
231
288
|
export type RunJSDocMethodDoc = string | {
|
|
232
289
|
description?: string;
|
|
233
290
|
detail?: string;
|
|
234
291
|
examples?: string[];
|
|
235
292
|
completion?: RunJSDocCompletionDoc;
|
|
293
|
+
ref?: FlowContextDocRef;
|
|
294
|
+
deprecated?: FlowDeprecationDoc;
|
|
295
|
+
params?: FlowContextDocParam[];
|
|
296
|
+
returns?: FlowContextDocReturn;
|
|
297
|
+
hidden?: RunJSDocHiddenDoc;
|
|
298
|
+
disabled?: boolean | ((ctx: any) => boolean | Promise<boolean>);
|
|
299
|
+
disabledReason?: string | ((ctx: any) => string | undefined | Promise<string | undefined>);
|
|
236
300
|
};
|
|
237
301
|
export type RunJSDocMeta = {
|
|
238
302
|
label?: string;
|
package/lib/flowContext.js
CHANGED
|
@@ -78,6 +78,7 @@ var import_registry = require("./runjs-context/registry");
|
|
|
78
78
|
var import_createEphemeralContext = require("./utils/createEphemeralContext");
|
|
79
79
|
var import_dayjs = __toESM(require("dayjs"));
|
|
80
80
|
var import_runjsLibs = require("./runjsLibs");
|
|
81
|
+
var import_runjsModuleLoader = require("./utils/runjsModuleLoader");
|
|
81
82
|
var _proxy, _FlowContext_instances, createChildNodes_fn, findMetaByPath_fn, findMetaInDelegatesDeep_fn, findMetaInProperty_fn, resolvePathInMeta_fn, resolvePathInMetaAsync_fn, buildParentTitles_fn, toTreeNode_fn;
|
|
82
83
|
function isRecordRefLike(val) {
|
|
83
84
|
return !!(val && typeof val === "object" && "collection" in val && "filterByTk" in val);
|
|
@@ -468,6 +469,73 @@ const _FlowContext = class _FlowContext {
|
|
|
468
469
|
}
|
|
469
470
|
return this._findPropertyInDelegates(this._delegates, key);
|
|
470
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* 获取当前上下文可用的顶层 API 信息(主要用于编辑器补全/工具)。
|
|
474
|
+
*
|
|
475
|
+
* 注意:
|
|
476
|
+
* - 目前返回值以“尽量可用”为目标,允许不完整。
|
|
477
|
+
* - 该方法不会展开变量 meta(变量结构应由 `getPropertyMetaTree()`/VariableInput 等机制负责)。
|
|
478
|
+
*/
|
|
479
|
+
async getApiInfos(options = {}) {
|
|
480
|
+
var _a, _b, _c, _d, _e;
|
|
481
|
+
const version = (options == null ? void 0 : options.version) || "v1";
|
|
482
|
+
const modelClass = (0, import_registry.getModelClassName)(this);
|
|
483
|
+
const Ctor = import_registry.RunJSContextRegistry.resolve(version, modelClass) || import_registry.RunJSContextRegistry.resolve(version, "*");
|
|
484
|
+
const locale = ((_b = (_a = this == null ? void 0 : this.api) == null ? void 0 : _a.auth) == null ? void 0 : _b.locale) || ((_c = this == null ? void 0 : this.i18n) == null ? void 0 : _c.language) || (this == null ? void 0 : this.locale);
|
|
485
|
+
let doc = {};
|
|
486
|
+
try {
|
|
487
|
+
if ((_d = Ctor == null ? void 0 : Ctor.getDoc) == null ? void 0 : _d.length) doc = Ctor.getDoc(locale) || {};
|
|
488
|
+
else doc = ((_e = Ctor == null ? void 0 : Ctor.getDoc) == null ? void 0 : _e.call(Ctor)) || {};
|
|
489
|
+
} catch (_2) {
|
|
490
|
+
doc = {};
|
|
491
|
+
}
|
|
492
|
+
const isPrivateKey = /* @__PURE__ */ __name((key) => typeof key === "string" && key.startsWith("_"), "isPrivateKey");
|
|
493
|
+
const out = {};
|
|
494
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
495
|
+
const walk = /* @__PURE__ */ __name((ctx) => {
|
|
496
|
+
if (!ctx || visited.has(ctx)) return;
|
|
497
|
+
visited.add(ctx);
|
|
498
|
+
try {
|
|
499
|
+
for (const key of Object.keys(ctx._props || {})) {
|
|
500
|
+
if (isPrivateKey(key)) continue;
|
|
501
|
+
if (typeof out[key] === "undefined") out[key] = { type: "property" };
|
|
502
|
+
}
|
|
503
|
+
} catch (_2) {
|
|
504
|
+
}
|
|
505
|
+
try {
|
|
506
|
+
for (const key of Object.keys(ctx._methods || {})) {
|
|
507
|
+
if (isPrivateKey(key)) continue;
|
|
508
|
+
if (typeof out[key] === "undefined") out[key] = { type: "function" };
|
|
509
|
+
}
|
|
510
|
+
} catch (_2) {
|
|
511
|
+
}
|
|
512
|
+
try {
|
|
513
|
+
const delegates = Array.isArray(ctx._delegates) ? ctx._delegates : [];
|
|
514
|
+
for (const d of delegates) walk(d);
|
|
515
|
+
} catch (_2) {
|
|
516
|
+
}
|
|
517
|
+
}, "walk");
|
|
518
|
+
walk(this);
|
|
519
|
+
return {
|
|
520
|
+
...out,
|
|
521
|
+
...(doc == null ? void 0 : doc.properties) || {},
|
|
522
|
+
...(doc == null ? void 0 : doc.methods) || {}
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* 变量结构信息(保留给编辑器/工具使用)。
|
|
527
|
+
* 当前实现为保底空对象,避免 RunJS doc 中补全到该方法时调用报错。
|
|
528
|
+
*/
|
|
529
|
+
async getVarInfos(_options = {}) {
|
|
530
|
+
return {};
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* 运行时环境信息(保留给编辑器/工具使用)。
|
|
534
|
+
* 当前实现为保底空对象,避免 RunJS doc 中补全到该方法时调用报错。
|
|
535
|
+
*/
|
|
536
|
+
async getEnvInfos() {
|
|
537
|
+
return {};
|
|
538
|
+
}
|
|
471
539
|
};
|
|
472
540
|
_proxy = new WeakMap();
|
|
473
541
|
_FlowContext_instances = new WeakSet();
|
|
@@ -652,6 +720,7 @@ toTreeNode_fn = /* @__PURE__ */ __name(function(name, metaOrFactory, paths = [na
|
|
|
652
720
|
type: "object",
|
|
653
721
|
// 初始类型
|
|
654
722
|
interface: void 0,
|
|
723
|
+
options: void 0,
|
|
655
724
|
uiSchema: void 0,
|
|
656
725
|
paths,
|
|
657
726
|
parentTitles: parentTitles.length > 0 ? parentTitles : void 0,
|
|
@@ -680,6 +749,7 @@ toTreeNode_fn = /* @__PURE__ */ __name(function(name, metaOrFactory, paths = [na
|
|
|
680
749
|
node.title = finalTitle;
|
|
681
750
|
node.type = meta == null ? void 0 : meta.type;
|
|
682
751
|
node.interface = meta == null ? void 0 : meta.interface;
|
|
752
|
+
node.options = meta == null ? void 0 : meta.options;
|
|
683
753
|
node.uiSchema = meta == null ? void 0 : meta.uiSchema;
|
|
684
754
|
if (!(meta == null ? void 0 : meta.properties)) return [];
|
|
685
755
|
const childNodes = __privateMethod(this, _FlowContext_instances, createChildNodes_fn).call(this, meta.properties, paths, [...parentTitles, finalTitle], meta);
|
|
@@ -700,6 +770,7 @@ toTreeNode_fn = /* @__PURE__ */ __name(function(name, metaOrFactory, paths = [na
|
|
|
700
770
|
title: nodeTitle,
|
|
701
771
|
type: metaOrFactory.type,
|
|
702
772
|
interface: metaOrFactory.interface,
|
|
773
|
+
options: metaOrFactory.options,
|
|
703
774
|
uiSchema: metaOrFactory.uiSchema,
|
|
704
775
|
paths,
|
|
705
776
|
parentTitles: parentTitles.length > 0 ? parentTitles : void 0,
|
|
@@ -911,6 +982,19 @@ const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContex
|
|
|
911
982
|
}
|
|
912
983
|
return (0, import_utils.resolveExpressions)(serverResolved, this);
|
|
913
984
|
});
|
|
985
|
+
this.defineMethod(
|
|
986
|
+
"getVar",
|
|
987
|
+
async function(varPath) {
|
|
988
|
+
const raw = typeof varPath === "string" ? varPath : String(varPath ?? "");
|
|
989
|
+
const s = raw.trim();
|
|
990
|
+
if (!s) return void 0;
|
|
991
|
+
if (s !== "ctx" && !s.startsWith("ctx.")) {
|
|
992
|
+
throw new Error(`ctx.getVar(path) expects an expression starting with "ctx.", got: "${s}"`);
|
|
993
|
+
}
|
|
994
|
+
return this.resolveJsonTemplate(`{{ ${s} }}`);
|
|
995
|
+
},
|
|
996
|
+
'Resolve a ctx expression value by path (expression starts with "ctx.").'
|
|
997
|
+
);
|
|
914
998
|
this.defineProperty("requirejs", {
|
|
915
999
|
get: /* @__PURE__ */ __name(() => {
|
|
916
1000
|
var _a, _b;
|
|
@@ -1000,7 +1084,8 @@ const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContex
|
|
|
1000
1084
|
user: this.user
|
|
1001
1085
|
}), "get")
|
|
1002
1086
|
});
|
|
1003
|
-
this.defineMethod("loadCSS", async (
|
|
1087
|
+
this.defineMethod("loadCSS", async (href) => {
|
|
1088
|
+
const url = (0, import_utils.resolveModuleUrl)(href);
|
|
1004
1089
|
return new Promise((resolve, reject) => {
|
|
1005
1090
|
const existingLink = document.querySelector(`link[href="${url}"]`);
|
|
1006
1091
|
if (existingLink) {
|
|
@@ -1016,51 +1101,14 @@ const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContex
|
|
|
1016
1101
|
});
|
|
1017
1102
|
});
|
|
1018
1103
|
this.defineMethod("requireAsync", async (url) => {
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
reject(new Error("requirejs is not available"));
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
1024
|
-
this.requirejs(
|
|
1025
|
-
[url],
|
|
1026
|
-
(...args) => {
|
|
1027
|
-
resolve(args[0]);
|
|
1028
|
-
},
|
|
1029
|
-
reject
|
|
1030
|
-
);
|
|
1031
|
-
});
|
|
1104
|
+
const u = (0, import_utils.resolveModuleUrl)(url, { raw: true });
|
|
1105
|
+
return await (0, import_runjsModuleLoader.runjsRequireAsync)(this.requirejs, u);
|
|
1032
1106
|
});
|
|
1033
|
-
this.defineMethod("importAsync", async (url)
|
|
1034
|
-
if (
|
|
1035
|
-
|
|
1107
|
+
this.defineMethod("importAsync", async function(url) {
|
|
1108
|
+
if ((0, import_utils.isCssFile)(url)) {
|
|
1109
|
+
return this.loadCSS(url);
|
|
1036
1110
|
}
|
|
1037
|
-
|
|
1038
|
-
const g = globalThis;
|
|
1039
|
-
g.__nocobaseImportAsyncCache = g.__nocobaseImportAsyncCache || /* @__PURE__ */ new Map();
|
|
1040
|
-
const cache = g.__nocobaseImportAsyncCache;
|
|
1041
|
-
if (cache.has(u)) return cache.get(u);
|
|
1042
|
-
const nativeImport = /* @__PURE__ */ __name(() => import(
|
|
1043
|
-
/* @vite-ignore */
|
|
1044
|
-
/* webpackIgnore: true */
|
|
1045
|
-
u
|
|
1046
|
-
), "nativeImport");
|
|
1047
|
-
const evalImport = /* @__PURE__ */ __name(() => {
|
|
1048
|
-
const importer = (0, eval)("u => import(u)");
|
|
1049
|
-
return importer(u);
|
|
1050
|
-
}, "evalImport");
|
|
1051
|
-
const p = (async () => {
|
|
1052
|
-
try {
|
|
1053
|
-
return await nativeImport();
|
|
1054
|
-
} catch (err) {
|
|
1055
|
-
try {
|
|
1056
|
-
return await evalImport();
|
|
1057
|
-
} catch (err2) {
|
|
1058
|
-
throw err2 || err;
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
})();
|
|
1062
|
-
cache.set(u, p);
|
|
1063
|
-
return p;
|
|
1111
|
+
return await (0, import_runjsModuleLoader.runjsImportModule)(this, url, { importer: import_runjsModuleLoader.runjsImportAsync });
|
|
1064
1112
|
});
|
|
1065
1113
|
this.defineMethod("createJSRunner", async function(options) {
|
|
1066
1114
|
try {
|
|
@@ -1389,6 +1437,7 @@ const _FlowRunJSContext = class _FlowRunJSContext extends FlowContext {
|
|
|
1389
1437
|
return this.engine.reactView.createRoot(realContainer, options);
|
|
1390
1438
|
}, "createRoot")
|
|
1391
1439
|
};
|
|
1440
|
+
ReactDOMShim.__nbRunjsInternalShim = true;
|
|
1392
1441
|
this.defineProperty("ReactDOM", { value: ReactDOMShim });
|
|
1393
1442
|
(0, import_runjsLibs.setupRunJSLibs)(this);
|
|
1394
1443
|
this.defineMethod(
|
|
@@ -1400,39 +1449,64 @@ const _FlowRunJSContext = class _FlowRunJSContext extends FlowContext {
|
|
|
1400
1449
|
const globalRef = globalThis;
|
|
1401
1450
|
globalRef.__nbRunjsRoots = globalRef.__nbRunjsRoots || /* @__PURE__ */ new WeakMap();
|
|
1402
1451
|
const rootMap = globalRef.__nbRunjsRoots;
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
if (
|
|
1452
|
+
const disposeEntry = /* @__PURE__ */ __name((entry2) => {
|
|
1453
|
+
if (!entry2) return;
|
|
1454
|
+
if (entry2.disposeTheme && typeof entry2.disposeTheme === "function") {
|
|
1406
1455
|
try {
|
|
1407
|
-
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1456
|
+
entry2.disposeTheme();
|
|
1457
|
+
} catch (_2) {
|
|
1458
|
+
}
|
|
1459
|
+
entry2.disposeTheme = void 0;
|
|
1460
|
+
}
|
|
1461
|
+
const root = entry2.root || entry2;
|
|
1462
|
+
if (root && typeof root.unmount === "function") {
|
|
1463
|
+
try {
|
|
1464
|
+
root.unmount();
|
|
1465
|
+
} catch (_2) {
|
|
1410
1466
|
}
|
|
1411
1467
|
}
|
|
1468
|
+
}, "disposeEntry");
|
|
1469
|
+
const unmountContainerRoot = /* @__PURE__ */ __name(() => {
|
|
1470
|
+
const existing = rootMap.get(containerEl);
|
|
1471
|
+
if (existing) {
|
|
1472
|
+
disposeEntry(existing);
|
|
1473
|
+
rootMap.delete(containerEl);
|
|
1474
|
+
}
|
|
1475
|
+
}, "unmountContainerRoot");
|
|
1476
|
+
if (typeof vnode === "string") {
|
|
1477
|
+
unmountContainerRoot();
|
|
1412
1478
|
const proxy = new import_ElementProxy.ElementProxy(containerEl);
|
|
1413
1479
|
proxy.innerHTML = String(vnode ?? "");
|
|
1414
1480
|
return null;
|
|
1415
1481
|
}
|
|
1416
1482
|
if (vnode && vnode.nodeType && (vnode.nodeType === 1 || vnode.nodeType === 3 || vnode.nodeType === 11)) {
|
|
1417
|
-
|
|
1418
|
-
if (existingRoot && typeof existingRoot.unmount === "function") {
|
|
1419
|
-
try {
|
|
1420
|
-
existingRoot.unmount();
|
|
1421
|
-
} finally {
|
|
1422
|
-
rootMap.delete(containerEl);
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1483
|
+
unmountContainerRoot();
|
|
1425
1484
|
while (containerEl.firstChild) containerEl.removeChild(containerEl.firstChild);
|
|
1426
1485
|
containerEl.appendChild(vnode);
|
|
1427
1486
|
return null;
|
|
1428
1487
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1488
|
+
const rendererKey = this.ReactDOM;
|
|
1489
|
+
const ownerKey = this;
|
|
1490
|
+
let entry = rootMap.get(containerEl);
|
|
1491
|
+
if (!entry || entry.rendererKey !== rendererKey || entry.ownerKey !== ownerKey) {
|
|
1492
|
+
if (entry) {
|
|
1493
|
+
disposeEntry(entry);
|
|
1494
|
+
rootMap.delete(containerEl);
|
|
1495
|
+
}
|
|
1496
|
+
const root = this.ReactDOM.createRoot(containerEl);
|
|
1497
|
+
entry = { rendererKey, ownerKey, root, disposeTheme: void 0, lastVnode: void 0 };
|
|
1498
|
+
rootMap.set(containerEl, entry);
|
|
1433
1499
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1500
|
+
return (0, import_runjsLibs.externalReactRender)({
|
|
1501
|
+
ctx: this,
|
|
1502
|
+
entry,
|
|
1503
|
+
vnode,
|
|
1504
|
+
containerEl,
|
|
1505
|
+
rootMap,
|
|
1506
|
+
unmountContainerRoot,
|
|
1507
|
+
internalReact: import_react.default,
|
|
1508
|
+
internalAntd: antd
|
|
1509
|
+
});
|
|
1436
1510
|
}
|
|
1437
1511
|
);
|
|
1438
1512
|
}
|
package/lib/flowEngine.d.ts
CHANGED
|
@@ -84,6 +84,17 @@ export declare class FlowEngine {
|
|
|
84
84
|
private _previousEngine?;
|
|
85
85
|
private _nextEngine?;
|
|
86
86
|
private _resources;
|
|
87
|
+
/**
|
|
88
|
+
* Data change registry used to coordinate "refresh on active" across view-scoped engines.
|
|
89
|
+
*
|
|
90
|
+
* Keyed by: dataSourceKey -> resourceName -> version.
|
|
91
|
+
* - mark: increments version
|
|
92
|
+
* - get: returns current version (default 0)
|
|
93
|
+
*
|
|
94
|
+
* NOTE: ViewScopedFlowEngine proxies delegate non-local fields/methods to parents, so this
|
|
95
|
+
* registry naturally lives on the root engine instance and is shared across the whole view stack.
|
|
96
|
+
*/
|
|
97
|
+
private _dataSourceDirtyVersions;
|
|
87
98
|
/**
|
|
88
99
|
* 引擎事件总线(目前用于模型生命周期等事件)。
|
|
89
100
|
* ViewScopedFlowEngine 持有自己的实例,实现作用域隔离。
|
|
@@ -116,6 +127,16 @@ export declare class FlowEngine {
|
|
|
116
127
|
getScheduler(): ModelOperationScheduler;
|
|
117
128
|
/** 释放并清理当前引擎本地调度器(若存在) */
|
|
118
129
|
disposeScheduler(): void;
|
|
130
|
+
/**
|
|
131
|
+
* Mark a data source resource as "dirty" (changed).
|
|
132
|
+
* This is used by data blocks to decide whether to refresh when a view becomes active.
|
|
133
|
+
*/
|
|
134
|
+
markDataSourceDirty(dataSourceKey: string, resourceName: string): number;
|
|
135
|
+
/**
|
|
136
|
+
* Get current dirty version for a data source resource.
|
|
137
|
+
* Returns 0 when no writes have been recorded.
|
|
138
|
+
*/
|
|
139
|
+
getDataSourceDirtyVersion(dataSourceKey: string, resourceName: string): number;
|
|
119
140
|
/** 在目标模型生命周期达成时执行操作(仅在 View 引擎本地存储计划) */
|
|
120
141
|
scheduleModelOperation(fromModelOrUid: FlowModel | string, toUid: string, fn: (model: FlowModel) => Promise<void> | void, options?: ScheduleOptions): ScheduledCancel;
|
|
121
142
|
/** 上一个引擎(根引擎为 undefined) */
|
package/lib/flowEngine.js
CHANGED
|
@@ -120,6 +120,17 @@ const _FlowEngine = class _FlowEngine {
|
|
|
120
120
|
__publicField(this, "_previousEngine");
|
|
121
121
|
__publicField(this, "_nextEngine");
|
|
122
122
|
__publicField(this, "_resources", /* @__PURE__ */ new Map());
|
|
123
|
+
/**
|
|
124
|
+
* Data change registry used to coordinate "refresh on active" across view-scoped engines.
|
|
125
|
+
*
|
|
126
|
+
* Keyed by: dataSourceKey -> resourceName -> version.
|
|
127
|
+
* - mark: increments version
|
|
128
|
+
* - get: returns current version (default 0)
|
|
129
|
+
*
|
|
130
|
+
* NOTE: ViewScopedFlowEngine proxies delegate non-local fields/methods to parents, so this
|
|
131
|
+
* registry naturally lives on the root engine instance and is shared across the whole view stack.
|
|
132
|
+
*/
|
|
133
|
+
__publicField(this, "_dataSourceDirtyVersions", /* @__PURE__ */ new Map());
|
|
123
134
|
/**
|
|
124
135
|
* 引擎事件总线(目前用于模型生命周期等事件)。
|
|
125
136
|
* ViewScopedFlowEngine 持有自己的实例,实现作用域隔离。
|
|
@@ -187,6 +198,33 @@ const _FlowEngine = class _FlowEngine {
|
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Mark a data source resource as "dirty" (changed).
|
|
203
|
+
* This is used by data blocks to decide whether to refresh when a view becomes active.
|
|
204
|
+
*/
|
|
205
|
+
markDataSourceDirty(dataSourceKey, resourceName) {
|
|
206
|
+
const dsKey = String(dataSourceKey || "main");
|
|
207
|
+
const resName = String(resourceName || "");
|
|
208
|
+
if (!resName) return this.getDataSourceDirtyVersion(dsKey, resName);
|
|
209
|
+
const ds = this._dataSourceDirtyVersions.get(dsKey) || /* @__PURE__ */ new Map();
|
|
210
|
+
if (!this._dataSourceDirtyVersions.has(dsKey)) {
|
|
211
|
+
this._dataSourceDirtyVersions.set(dsKey, ds);
|
|
212
|
+
}
|
|
213
|
+
const next = (ds.get(resName) || 0) + 1;
|
|
214
|
+
ds.set(resName, next);
|
|
215
|
+
return next;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get current dirty version for a data source resource.
|
|
219
|
+
* Returns 0 when no writes have been recorded.
|
|
220
|
+
*/
|
|
221
|
+
getDataSourceDirtyVersion(dataSourceKey, resourceName) {
|
|
222
|
+
var _a;
|
|
223
|
+
const dsKey = String(dataSourceKey || "main");
|
|
224
|
+
const resName = String(resourceName || "");
|
|
225
|
+
if (!resName) return 0;
|
|
226
|
+
return ((_a = this._dataSourceDirtyVersions.get(dsKey)) == null ? void 0 : _a.get(resName)) || 0;
|
|
227
|
+
}
|
|
190
228
|
/** 在目标模型生命周期达成时执行操作(仅在 View 引擎本地存储计划) */
|
|
191
229
|
scheduleModelOperation(fromModelOrUid, toUid, fn, options) {
|
|
192
230
|
return this.getScheduler().schedule(fromModelOrUid, toUid, fn, options);
|
package/lib/index.d.ts
CHANGED
|
@@ -27,8 +27,12 @@ export * from './JSRunner';
|
|
|
27
27
|
export { getRunJSDocFor, createJSRunnerWithVersion, getRunJSScenesForModel, getRunJSScenesForContext, } from './runjs-context/helpers';
|
|
28
28
|
export { RunJSContextRegistry, getModelClassName } from './runjs-context/registry';
|
|
29
29
|
export { setupRunJSContexts } from './runjs-context/setup';
|
|
30
|
-
export {
|
|
30
|
+
export type { RunJSContextContribution, RunJSContextContributionApi } from './runjs-context/contributions';
|
|
31
|
+
export { registerRunJSContextContribution } from './runjs-context/contributions';
|
|
32
|
+
export type { RunJSSnippetLoader } from './runjs-context/snippets';
|
|
33
|
+
export { getSnippetBody, listSnippetsForContext, registerRunJSSnippet } from './runjs-context/snippets';
|
|
31
34
|
export * from './views';
|
|
35
|
+
export { DATA_SOURCE_DIRTY_EVENT, ENGINE_SCOPE_KEY, getEmitterViewActivatedVersion, VIEW_ACTIVATED_EVENT, VIEW_ACTIVATED_VERSION, VIEW_ENGINE_SCOPE, } from './views/viewEvents';
|
|
32
36
|
export * from './FlowDefinition';
|
|
33
37
|
export { createViewScopedEngine } from './ViewScopedFlowEngine';
|
|
34
38
|
export { createBlockScopedEngine } from './BlockScopedFlowEngine';
|
package/lib/index.js
CHANGED
|
@@ -27,18 +27,26 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
var src_exports = {};
|
|
29
29
|
__export(src_exports, {
|
|
30
|
+
DATA_SOURCE_DIRTY_EVENT: () => import_viewEvents.DATA_SOURCE_DIRTY_EVENT,
|
|
31
|
+
ENGINE_SCOPE_KEY: () => import_viewEvents.ENGINE_SCOPE_KEY,
|
|
30
32
|
RunJSContextRegistry: () => import_registry.RunJSContextRegistry,
|
|
33
|
+
VIEW_ACTIVATED_EVENT: () => import_viewEvents.VIEW_ACTIVATED_EVENT,
|
|
34
|
+
VIEW_ACTIVATED_VERSION: () => import_viewEvents.VIEW_ACTIVATED_VERSION,
|
|
35
|
+
VIEW_ENGINE_SCOPE: () => import_viewEvents.VIEW_ENGINE_SCOPE,
|
|
31
36
|
compileRunJs: () => import_jsxTransform.compileRunJs,
|
|
32
37
|
createBlockScopedEngine: () => import_BlockScopedFlowEngine.createBlockScopedEngine,
|
|
33
38
|
createJSRunnerWithVersion: () => import_helpers.createJSRunnerWithVersion,
|
|
34
39
|
createViewScopedEngine: () => import_ViewScopedFlowEngine.createViewScopedEngine,
|
|
40
|
+
getEmitterViewActivatedVersion: () => import_viewEvents.getEmitterViewActivatedVersion,
|
|
35
41
|
getModelClassName: () => import_registry.getModelClassName,
|
|
36
42
|
getRunJSDocFor: () => import_helpers.getRunJSDocFor,
|
|
37
43
|
getRunJSScenesForContext: () => import_helpers.getRunJSScenesForContext,
|
|
38
44
|
getRunJSScenesForModel: () => import_helpers.getRunJSScenesForModel,
|
|
39
45
|
getSnippetBody: () => import_snippets.getSnippetBody,
|
|
40
46
|
listSnippetsForContext: () => import_snippets.listSnippetsForContext,
|
|
47
|
+
registerRunJSContextContribution: () => import_contributions.registerRunJSContextContribution,
|
|
41
48
|
registerRunJSLib: () => import_runjsLibs.registerRunJSLib,
|
|
49
|
+
registerRunJSSnippet: () => import_snippets.registerRunJSSnippet,
|
|
42
50
|
setupRunJSContexts: () => import_setup.setupRunJSContexts
|
|
43
51
|
});
|
|
44
52
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -62,25 +70,35 @@ __reExport(src_exports, require("./JSRunner"), module.exports);
|
|
|
62
70
|
var import_helpers = require("./runjs-context/helpers");
|
|
63
71
|
var import_registry = require("./runjs-context/registry");
|
|
64
72
|
var import_setup = require("./runjs-context/setup");
|
|
73
|
+
var import_contributions = require("./runjs-context/contributions");
|
|
65
74
|
var import_snippets = require("./runjs-context/snippets");
|
|
66
75
|
__reExport(src_exports, require("./views"), module.exports);
|
|
76
|
+
var import_viewEvents = require("./views/viewEvents");
|
|
67
77
|
__reExport(src_exports, require("./FlowDefinition"), module.exports);
|
|
68
78
|
var import_ViewScopedFlowEngine = require("./ViewScopedFlowEngine");
|
|
69
79
|
var import_BlockScopedFlowEngine = require("./BlockScopedFlowEngine");
|
|
70
80
|
// Annotate the CommonJS export names for ESM import in node:
|
|
71
81
|
0 && (module.exports = {
|
|
82
|
+
DATA_SOURCE_DIRTY_EVENT,
|
|
83
|
+
ENGINE_SCOPE_KEY,
|
|
72
84
|
RunJSContextRegistry,
|
|
85
|
+
VIEW_ACTIVATED_EVENT,
|
|
86
|
+
VIEW_ACTIVATED_VERSION,
|
|
87
|
+
VIEW_ENGINE_SCOPE,
|
|
73
88
|
compileRunJs,
|
|
74
89
|
createBlockScopedEngine,
|
|
75
90
|
createJSRunnerWithVersion,
|
|
76
91
|
createViewScopedEngine,
|
|
92
|
+
getEmitterViewActivatedVersion,
|
|
77
93
|
getModelClassName,
|
|
78
94
|
getRunJSDocFor,
|
|
79
95
|
getRunJSScenesForContext,
|
|
80
96
|
getRunJSScenesForModel,
|
|
81
97
|
getSnippetBody,
|
|
82
98
|
listSnippetsForContext,
|
|
99
|
+
registerRunJSContextContribution,
|
|
83
100
|
registerRunJSLib,
|
|
101
|
+
registerRunJSSnippet,
|
|
84
102
|
setupRunJSContexts,
|
|
85
103
|
...require("./types"),
|
|
86
104
|
...require("./utils"),
|
package/lib/models/flowModel.js
CHANGED
|
@@ -353,7 +353,18 @@ const _FlowModel = class _FlowModel {
|
|
|
353
353
|
const meta = Cls.meta;
|
|
354
354
|
const metaCreate = meta == null ? void 0 : meta.createModelOptions;
|
|
355
355
|
if (metaCreate && typeof metaCreate === "object" && metaCreate.subModels) {
|
|
356
|
-
|
|
356
|
+
const replaceArrays = /* @__PURE__ */ __name((objValue, srcValue) => {
|
|
357
|
+
if (Array.isArray(objValue) && Array.isArray(srcValue)) {
|
|
358
|
+
return srcValue;
|
|
359
|
+
}
|
|
360
|
+
return void 0;
|
|
361
|
+
}, "replaceArrays");
|
|
362
|
+
mergedSubModels = import_lodash.default.mergeWith(
|
|
363
|
+
{},
|
|
364
|
+
import_lodash.default.cloneDeep(metaCreate.subModels || {}),
|
|
365
|
+
import_lodash.default.cloneDeep(subModels || {}),
|
|
366
|
+
replaceArrays
|
|
367
|
+
);
|
|
357
368
|
}
|
|
358
369
|
} catch (e) {
|
|
359
370
|
}
|