@nocobase/flow-engine 2.1.0-beta.9 → 2.2.0-beta.1
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/FlowContextProvider.d.ts +5 -1
- package/lib/FlowContextProvider.js +9 -2
- package/lib/components/FieldModelRenderer.js +2 -2
- package/lib/components/FlowModelRenderer.d.ts +3 -1
- package/lib/components/FlowModelRenderer.js +12 -6
- package/lib/components/FormItem.d.ts +6 -0
- package/lib/components/FormItem.js +11 -3
- package/lib/components/MobilePopup.js +6 -5
- package/lib/components/dnd/gridDragPlanner.d.ts +59 -2
- package/lib/components/dnd/gridDragPlanner.js +607 -19
- package/lib/components/dnd/index.d.ts +31 -2
- package/lib/components/dnd/index.js +244 -23
- package/lib/components/settings/wrappers/component/SelectWithTitle.d.ts +2 -1
- package/lib/components/settings/wrappers/component/SelectWithTitle.js +14 -12
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +3 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +152 -42
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +23 -43
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +352 -295
- package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.d.ts +36 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.js +274 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.d.ts +30 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +315 -0
- package/lib/components/subModel/AddSubModelButton.js +12 -1
- package/lib/components/subModel/LazyDropdown.js +301 -52
- package/lib/components/subModel/index.d.ts +1 -0
- package/lib/components/subModel/index.js +19 -0
- package/lib/components/subModel/utils.d.ts +2 -1
- package/lib/components/subModel/utils.js +15 -5
- package/lib/components/variables/VariableHybridInput.d.ts +27 -0
- package/lib/components/variables/VariableHybridInput.js +499 -0
- package/lib/components/variables/index.d.ts +2 -0
- package/lib/components/variables/index.js +3 -0
- package/lib/data-source/index.d.ts +84 -0
- package/lib/data-source/index.js +269 -7
- package/lib/executor/FlowExecutor.js +6 -3
- package/lib/flow-registry/DetachedFlowRegistry.d.ts +21 -0
- package/lib/flow-registry/DetachedFlowRegistry.js +80 -0
- package/lib/flow-registry/index.d.ts +1 -0
- package/lib/flow-registry/index.js +3 -1
- package/lib/flowContext.d.ts +9 -1
- package/lib/flowContext.js +77 -6
- package/lib/flowEngine.d.ts +136 -4
- package/lib/flowEngine.js +429 -51
- package/lib/flowI18n.js +2 -1
- package/lib/flowSettings.d.ts +14 -6
- package/lib/flowSettings.js +34 -6
- package/lib/index.d.ts +2 -0
- package/lib/index.js +7 -0
- package/lib/lazy-helper.d.ts +14 -0
- package/lib/lazy-helper.js +71 -0
- package/lib/locale/en-US.json +1 -0
- package/lib/locale/index.d.ts +2 -0
- package/lib/locale/zh-CN.json +1 -0
- package/lib/models/DisplayItemModel.d.ts +1 -1
- package/lib/models/EditableItemModel.d.ts +1 -1
- package/lib/models/FilterableItemModel.d.ts +1 -1
- package/lib/models/flowModel.d.ts +13 -10
- package/lib/models/flowModel.js +126 -34
- package/lib/provider.js +38 -23
- package/lib/reactive/observer.js +46 -16
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +4 -3
- package/lib/runjs-context/contexts/JSBlockRunJSContext.js +4 -15
- package/lib/runjs-context/contexts/JSColumnRunJSContext.js +5 -2
- package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +5 -8
- package/lib/runjs-context/contexts/JSFieldRunJSContext.js +4 -3
- package/lib/runjs-context/contexts/JSItemRunJSContext.js +4 -3
- package/lib/runjs-context/contexts/base.js +464 -29
- package/lib/runjs-context/contexts/elementDoc.d.ts +11 -0
- package/lib/runjs-context/contexts/elementDoc.js +152 -0
- package/lib/runjs-context/setup.js +1 -0
- package/lib/runjs-context/snippets/index.js +13 -2
- package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.js +50 -0
- package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.js +54 -0
- package/lib/types.d.ts +50 -2
- package/lib/types.js +1 -0
- package/lib/utils/createCollectionContextMeta.js +6 -2
- package/lib/utils/index.d.ts +3 -2
- package/lib/utils/index.js +7 -0
- package/lib/utils/loadedPageCache.d.ts +24 -0
- package/lib/utils/loadedPageCache.js +139 -0
- package/lib/utils/parsePathnameToViewParams.d.ts +5 -1
- package/lib/utils/parsePathnameToViewParams.js +28 -4
- package/lib/utils/randomId.d.ts +39 -0
- package/lib/utils/randomId.js +45 -0
- package/lib/utils/runjsTemplateCompat.js +1 -1
- package/lib/utils/runjsValue.js +41 -11
- package/lib/utils/schema-utils.d.ts +7 -1
- package/lib/utils/schema-utils.js +19 -0
- package/lib/views/FlowView.d.ts +7 -1
- package/lib/views/FlowView.js +11 -1
- package/lib/views/PageComponent.js +8 -6
- package/lib/views/ViewNavigation.d.ts +12 -2
- package/lib/views/ViewNavigation.js +28 -9
- package/lib/views/createViewMeta.js +114 -50
- package/lib/views/inheritLayoutContext.d.ts +10 -0
- package/lib/views/inheritLayoutContext.js +50 -0
- package/lib/views/runViewBeforeClose.d.ts +10 -0
- package/lib/views/runViewBeforeClose.js +45 -0
- package/lib/views/useDialog.d.ts +2 -1
- package/lib/views/useDialog.js +12 -3
- package/lib/views/useDrawer.d.ts +2 -1
- package/lib/views/useDrawer.js +12 -3
- package/lib/views/usePage.d.ts +5 -11
- package/lib/views/usePage.js +304 -144
- package/package.json +5 -4
- package/src/FlowContextProvider.tsx +9 -1
- package/src/__tests__/createViewMeta.popup.test.ts +115 -1
- package/src/__tests__/flow-engine.test.ts +166 -0
- package/src/__tests__/flowContext.test.ts +105 -1
- package/src/__tests__/flowEngine.modelLoaders.test.ts +245 -0
- package/src/__tests__/flowEngine.moveModel.test.ts +81 -1
- package/src/__tests__/flowEngine.removeModel.test.ts +47 -3
- package/src/__tests__/flowSettings.test.ts +94 -15
- package/src/__tests__/objectVariable.test.ts +24 -0
- package/src/__tests__/provider.test.tsx +24 -2
- package/src/__tests__/renderHiddenInConfig.test.tsx +6 -6
- package/src/__tests__/runjsContext.test.ts +21 -0
- package/src/__tests__/runjsContextImplementations.test.ts +9 -2
- package/src/__tests__/runjsContextRuntime.test.ts +2 -0
- package/src/__tests__/runjsLocales.test.ts +6 -5
- package/src/__tests__/runjsSnippets.test.ts +21 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +136 -3
- package/src/components/FieldModelRenderer.tsx +2 -1
- package/src/components/FlowModelRenderer.tsx +18 -6
- package/src/components/FormItem.tsx +7 -1
- package/src/components/MobilePopup.tsx +4 -2
- package/src/components/__tests__/FlowModelRenderer.test.tsx +65 -2
- package/src/components/__tests__/FormItem.test.tsx +25 -0
- package/src/components/__tests__/dnd.test.ts +44 -0
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +20 -10
- package/src/components/__tests__/gridDragPlanner.test.ts +472 -5
- package/src/components/dnd/__tests__/DndProvider.test.tsx +98 -0
- package/src/components/dnd/gridDragPlanner.ts +750 -17
- package/src/components/dnd/index.tsx +305 -28
- package/src/components/settings/wrappers/component/SelectWithTitle.tsx +21 -9
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +178 -48
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +487 -440
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +344 -8
- package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +778 -0
- package/src/components/settings/wrappers/contextual/useFloatToolbarPortal.ts +360 -0
- package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +361 -0
- package/src/components/subModel/AddSubModelButton.tsx +16 -2
- package/src/components/subModel/LazyDropdown.tsx +341 -56
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +524 -38
- package/src/components/subModel/__tests__/utils.test.ts +24 -0
- package/src/components/subModel/index.ts +1 -0
- package/src/components/subModel/utils.ts +13 -2
- package/src/components/variables/VariableHybridInput.tsx +531 -0
- package/src/components/variables/index.ts +2 -0
- package/src/data-source/__tests__/collection.test.ts +41 -2
- package/src/data-source/__tests__/index.test.ts +69 -2
- package/src/data-source/index.ts +332 -8
- package/src/executor/FlowExecutor.ts +6 -3
- package/src/executor/__tests__/flowExecutor.test.ts +57 -0
- package/src/flow-registry/DetachedFlowRegistry.ts +46 -0
- package/src/flow-registry/__tests__/detachedFlowRegistry.test.ts +47 -0
- package/src/flow-registry/index.ts +1 -0
- package/src/flowContext.ts +85 -6
- package/src/flowEngine.ts +484 -45
- package/src/flowI18n.ts +2 -1
- package/src/flowSettings.ts +40 -6
- package/src/index.ts +2 -0
- package/src/lazy-helper.tsx +57 -0
- package/src/locale/en-US.json +1 -0
- package/src/locale/zh-CN.json +1 -0
- package/src/models/DisplayItemModel.tsx +1 -1
- package/src/models/EditableItemModel.tsx +1 -1
- package/src/models/FilterableItemModel.tsx +1 -1
- package/src/models/__tests__/flowEngine.resolveUse.test.ts +0 -15
- package/src/models/__tests__/flowModel.test.ts +65 -37
- package/src/models/flowModel.tsx +184 -65
- package/src/provider.tsx +41 -25
- package/src/reactive/__tests__/observer.test.tsx +82 -0
- package/src/reactive/observer.tsx +87 -25
- package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +4 -3
- package/src/runjs-context/contexts/JSBlockRunJSContext.ts +4 -15
- package/src/runjs-context/contexts/JSColumnRunJSContext.ts +4 -2
- package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +5 -9
- package/src/runjs-context/contexts/JSFieldRunJSContext.ts +4 -3
- package/src/runjs-context/contexts/JSItemRunJSContext.ts +4 -3
- package/src/runjs-context/contexts/base.ts +467 -31
- package/src/runjs-context/contexts/elementDoc.ts +130 -0
- package/src/runjs-context/setup.ts +1 -0
- package/src/runjs-context/snippets/index.ts +12 -1
- package/src/runjs-context/snippets/scene/detail/set-field-style.snippet.ts +30 -0
- package/src/runjs-context/snippets/scene/table/set-cell-style.snippet.ts +34 -0
- package/src/types.ts +62 -0
- package/src/utils/__tests__/createCollectionContextMeta.test.ts +48 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +21 -0
- package/src/utils/__tests__/runjsValue.test.ts +11 -0
- package/src/utils/__tests__/utils.test.ts +62 -0
- package/src/utils/createCollectionContextMeta.ts +6 -2
- package/src/utils/index.ts +5 -1
- package/src/utils/loadedPageCache.ts +147 -0
- package/src/utils/parsePathnameToViewParams.ts +45 -5
- package/src/utils/randomId.ts +48 -0
- package/src/utils/runjsTemplateCompat.ts +1 -1
- package/src/utils/runjsValue.ts +50 -11
- package/src/utils/schema-utils.ts +30 -1
- package/src/views/FlowView.tsx +22 -2
- package/src/views/PageComponent.tsx +7 -4
- package/src/views/ViewNavigation.ts +46 -9
- package/src/views/__tests__/FlowView.usePage.test.tsx +243 -3
- package/src/views/__tests__/ViewNavigation.test.ts +52 -0
- package/src/views/__tests__/inheritLayoutContext.test.ts +53 -0
- package/src/views/__tests__/runViewBeforeClose.test.ts +30 -0
- package/src/views/__tests__/useDialog.closeDestroy.test.tsx +12 -12
- package/src/views/createViewMeta.ts +106 -34
- package/src/views/inheritLayoutContext.ts +26 -0
- package/src/views/runViewBeforeClose.ts +19 -0
- package/src/views/useDialog.tsx +13 -3
- package/src/views/useDrawer.tsx +13 -3
- package/src/views/usePage.tsx +367 -180
package/lib/flowEngine.js
CHANGED
|
@@ -61,8 +61,10 @@ var import_ReactView = require("./ReactView");
|
|
|
61
61
|
var import_resources = require("./resources");
|
|
62
62
|
var import_emitter = require("./emitter");
|
|
63
63
|
var import_ModelOperationScheduler = __toESM(require("./scheduler/ModelOperationScheduler"));
|
|
64
|
+
var import_loadedPageCache = require("./utils/loadedPageCache");
|
|
64
65
|
var import_utils = require("./utils");
|
|
65
66
|
var _FlowEngine_instances, registerModel_fn;
|
|
67
|
+
const getFlowEngineLoggerLevel = /* @__PURE__ */ __name(() => process.env.NODE_ENV === "production" ? "warn" : "trace", "getFlowEngineLoggerLevel");
|
|
66
68
|
const _FlowEngine = class _FlowEngine {
|
|
67
69
|
/**
|
|
68
70
|
* Constructor. Initializes React view, registers default model and form scopes.
|
|
@@ -83,6 +85,28 @@ const _FlowEngine = class _FlowEngine {
|
|
|
83
85
|
* @private
|
|
84
86
|
*/
|
|
85
87
|
__publicField(this, "_modelClasses", import_reactive.observable.shallow(/* @__PURE__ */ new Map()));
|
|
88
|
+
/**
|
|
89
|
+
* Registered model entries.
|
|
90
|
+
* Key is the model class name, value is the model loader entry.
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
__publicField(this, "_modelLoaders", /* @__PURE__ */ new Map());
|
|
94
|
+
/**
|
|
95
|
+
* In-flight model loading promises.
|
|
96
|
+
* Key is the model class name, value is the loading promise.
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
__publicField(this, "_loadingModelPromises", /* @__PURE__ */ new Map());
|
|
100
|
+
/**
|
|
101
|
+
* Whether model-loader preload has completed in this session.
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
__publicField(this, "_modelLoadersPreloaded", false);
|
|
105
|
+
/**
|
|
106
|
+
* In-flight model-loader preload promise.
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
109
|
+
__publicField(this, "_modelLoadersPreloadPromise");
|
|
86
110
|
/**
|
|
87
111
|
* Created model instances.
|
|
88
112
|
* Key is the model instance UID, value is the model instance object.
|
|
@@ -107,6 +131,7 @@ const _FlowEngine = class _FlowEngine {
|
|
|
107
131
|
* @private
|
|
108
132
|
*/
|
|
109
133
|
__publicField(this, "_savingModels", /* @__PURE__ */ new Map());
|
|
134
|
+
__publicField(this, "_loadedPageCache", (0, import_loadedPageCache.createLoadedPageCache)());
|
|
110
135
|
/**
|
|
111
136
|
* Flow engine context object.
|
|
112
137
|
* @private
|
|
@@ -173,7 +198,7 @@ const _FlowEngine = class _FlowEngine {
|
|
|
173
198
|
MultiRecordResource: import_resources.MultiRecordResource
|
|
174
199
|
});
|
|
175
200
|
this.logger = (0, import_pino.default)({
|
|
176
|
-
level:
|
|
201
|
+
level: getFlowEngineLoggerLevel(),
|
|
177
202
|
browser: {
|
|
178
203
|
write: {
|
|
179
204
|
fatal: /* @__PURE__ */ __name((o) => console.trace(o), "fatal"),
|
|
@@ -372,6 +397,16 @@ const _FlowEngine = class _FlowEngine {
|
|
|
372
397
|
getEvents() {
|
|
373
398
|
return this._eventRegistry.getEvents();
|
|
374
399
|
}
|
|
400
|
+
/**
|
|
401
|
+
* for proxy instance, the #registerModel can't be called.
|
|
402
|
+
*/
|
|
403
|
+
_registerModel(name, modelClass) {
|
|
404
|
+
if (this._modelClasses.has(name)) {
|
|
405
|
+
console.warn(`FlowEngine: Model class with name '${name}' is already registered and will be overwritten.`);
|
|
406
|
+
}
|
|
407
|
+
Object.defineProperty(modelClass, "name", { value: name });
|
|
408
|
+
this._modelClasses.set(name, modelClass);
|
|
409
|
+
}
|
|
375
410
|
/**
|
|
376
411
|
* Register multiple model classes.
|
|
377
412
|
* @param {Record<string, ModelConstructor>} models Model class map, key is model name, value is model constructor
|
|
@@ -384,6 +419,274 @@ const _FlowEngine = class _FlowEngine {
|
|
|
384
419
|
__privateMethod(this, _FlowEngine_instances, registerModel_fn).call(this, name, modelClass);
|
|
385
420
|
}
|
|
386
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* Register multiple model loader entries.
|
|
424
|
+
* The `extends` field declares parent class(es) for async subclass discovery via `getSubclassesOfAsync`.
|
|
425
|
+
* It accepts `string | ModelConstructor | (string | ModelConstructor)[]` and is normalized to `string[]` internally.
|
|
426
|
+
* @param {FlowModelLoaderInputMap} loaders Model loader input map
|
|
427
|
+
* @returns {void}
|
|
428
|
+
* @example
|
|
429
|
+
* flowEngine.registerModelLoaders({
|
|
430
|
+
* DemoModel: {
|
|
431
|
+
* extends: 'BaseModel',
|
|
432
|
+
* loader: () => import('./models/DemoModel'),
|
|
433
|
+
* },
|
|
434
|
+
* });
|
|
435
|
+
*/
|
|
436
|
+
registerModelLoaders(loaders) {
|
|
437
|
+
let changed = false;
|
|
438
|
+
for (const [name, input] of Object.entries(loaders)) {
|
|
439
|
+
if (this._modelLoaders.has(name)) {
|
|
440
|
+
console.warn(`FlowEngine: Model loader with name '${name}' is already registered and will be overwritten.`);
|
|
441
|
+
}
|
|
442
|
+
const entry = {
|
|
443
|
+
loader: input.loader
|
|
444
|
+
};
|
|
445
|
+
if (input.extends != null) {
|
|
446
|
+
const raw = Array.isArray(input.extends) ? input.extends : [input.extends];
|
|
447
|
+
entry.extends = raw.map((item) => typeof item === "string" ? item : item.name);
|
|
448
|
+
}
|
|
449
|
+
this._modelLoaders.set(name, entry);
|
|
450
|
+
changed = true;
|
|
451
|
+
}
|
|
452
|
+
if (changed) {
|
|
453
|
+
this._modelLoadersPreloaded = false;
|
|
454
|
+
this._modelLoadersPreloadPromise = void 0;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Get a registered model class (constructor) asynchronously.
|
|
459
|
+
* This will first ensure the model loader entry is resolved.
|
|
460
|
+
* @param {string} name Model class name
|
|
461
|
+
* @returns {Promise<ModelConstructor | undefined>} Model constructor, or undefined if not found
|
|
462
|
+
*/
|
|
463
|
+
async getModelClassAsync(name) {
|
|
464
|
+
await this.ensureModel(name);
|
|
465
|
+
return this.getModelClass(name);
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Get all registered model classes asynchronously.
|
|
469
|
+
* This will first ensure all registered model loader entries are resolved.
|
|
470
|
+
* @returns {Promise<Map<string, ModelConstructor>>} Model class map
|
|
471
|
+
*/
|
|
472
|
+
async getModelClassesAsync() {
|
|
473
|
+
await this.ensureModels(Array.from(this._modelLoaders.keys()));
|
|
474
|
+
return this.getModelClasses();
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Create and register a model instance asynchronously.
|
|
478
|
+
* This will first ensure all string-based model references in the model tree are resolved.
|
|
479
|
+
* @template T FlowModel subclass type, defaults to FlowModel.
|
|
480
|
+
* @param {CreateModelOptions} options Model creation options
|
|
481
|
+
* @returns {Promise<T>} Created model instance
|
|
482
|
+
*/
|
|
483
|
+
async createModelAsync(options, extra) {
|
|
484
|
+
await this.resolveModelTree(options);
|
|
485
|
+
return this.createModel(options, extra);
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Normalize a loader result into a model constructor.
|
|
489
|
+
* @param {string} name Model class name
|
|
490
|
+
* @param {FlowModelLoaderResult} loaded Loader result
|
|
491
|
+
* @returns {ModelConstructor | null} Normalized model constructor
|
|
492
|
+
* @private
|
|
493
|
+
*/
|
|
494
|
+
normalizeModelLoaderResult(name, loaded) {
|
|
495
|
+
if (typeof loaded === "function") {
|
|
496
|
+
return loaded;
|
|
497
|
+
}
|
|
498
|
+
if (loaded && typeof loaded === "object") {
|
|
499
|
+
const defaultExport = loaded.default;
|
|
500
|
+
if (typeof defaultExport === "function") {
|
|
501
|
+
return defaultExport;
|
|
502
|
+
}
|
|
503
|
+
const namedExport = loaded[name];
|
|
504
|
+
if (typeof namedExport === "function") {
|
|
505
|
+
return namedExport;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
console.warn(`FlowEngine: model loader for '${name}' did not resolve to a valid model constructor.`);
|
|
509
|
+
return null;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Collect string-based model names from a model tree.
|
|
513
|
+
* @param {unknown} data Model tree data
|
|
514
|
+
* @param {Set<string>} names Model name set
|
|
515
|
+
* @private
|
|
516
|
+
*/
|
|
517
|
+
collectModelNamesFromTree(data, names) {
|
|
518
|
+
if (!data || typeof data !== "object") {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
if (Array.isArray(data)) {
|
|
522
|
+
data.forEach((item) => this.collectModelNamesFromTree(item, names));
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
const tree = data;
|
|
526
|
+
if (typeof tree.use === "string") {
|
|
527
|
+
names.add(tree.use);
|
|
528
|
+
}
|
|
529
|
+
const subModels = tree.subModels;
|
|
530
|
+
if (!subModels || typeof subModels !== "object") {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
Object.values(subModels).forEach((value) => {
|
|
534
|
+
this.collectModelNamesFromTree(value, names);
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Collect additional model names from object-form meta.createModelOptions defaults.
|
|
539
|
+
* @param {ModelConstructor} modelClass Model class constructor
|
|
540
|
+
* @param {Set<string>} names Model name set
|
|
541
|
+
* @private
|
|
542
|
+
*/
|
|
543
|
+
collectModelNamesFromMetaDefaults(modelClass, names) {
|
|
544
|
+
var _a;
|
|
545
|
+
const metaCreate = (_a = modelClass.meta) == null ? void 0 : _a.createModelOptions;
|
|
546
|
+
if (metaCreate && typeof metaCreate === "object") {
|
|
547
|
+
this.collectModelNamesFromTree(metaCreate, names);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Ensure a single model class is available.
|
|
552
|
+
* @param {string} name Model class name
|
|
553
|
+
* @returns {Promise<ModelConstructor | null>} Model constructor or null when resolution fails
|
|
554
|
+
* @private
|
|
555
|
+
*/
|
|
556
|
+
async ensureModel(name) {
|
|
557
|
+
const existing = this._modelClasses.get(name);
|
|
558
|
+
if (existing) {
|
|
559
|
+
return existing;
|
|
560
|
+
}
|
|
561
|
+
const inflight = this._loadingModelPromises.get(name);
|
|
562
|
+
if (inflight) {
|
|
563
|
+
return inflight;
|
|
564
|
+
}
|
|
565
|
+
const entry = this._modelLoaders.get(name);
|
|
566
|
+
if (!entry) {
|
|
567
|
+
console.warn(`FlowEngine: Model entry '${name}' not found. Falling back to ErrorFlowModel when needed.`);
|
|
568
|
+
return null;
|
|
569
|
+
}
|
|
570
|
+
const promise = (async () => {
|
|
571
|
+
try {
|
|
572
|
+
const loaded = await entry.loader();
|
|
573
|
+
const modelClass = this.normalizeModelLoaderResult(name, loaded);
|
|
574
|
+
if (!modelClass) {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
this._registerModel(name, modelClass);
|
|
578
|
+
return modelClass;
|
|
579
|
+
} catch (error) {
|
|
580
|
+
console.warn(`FlowEngine: Failed to load model '${name}'. Falling back to ErrorFlowModel when needed.`, error);
|
|
581
|
+
return null;
|
|
582
|
+
} finally {
|
|
583
|
+
this._loadingModelPromises.delete(name);
|
|
584
|
+
}
|
|
585
|
+
})();
|
|
586
|
+
this._loadingModelPromises.set(name, promise);
|
|
587
|
+
return promise;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Ensure multiple model classes are available.
|
|
591
|
+
* @param {string[]} names Model class names
|
|
592
|
+
* @returns {Promise<EnsureBatchResult>} Batch ensure result
|
|
593
|
+
* @private
|
|
594
|
+
*/
|
|
595
|
+
async ensureModels(names) {
|
|
596
|
+
const requested = Array.from(new Set(names.filter((name) => !!name)));
|
|
597
|
+
const loaded = [];
|
|
598
|
+
const failed = [];
|
|
599
|
+
const results = await Promise.all(
|
|
600
|
+
requested.map(async (name) => {
|
|
601
|
+
const modelClass = await this.ensureModel(name);
|
|
602
|
+
return { name, modelClass };
|
|
603
|
+
})
|
|
604
|
+
);
|
|
605
|
+
results.forEach(({ name, modelClass }) => {
|
|
606
|
+
if (modelClass) {
|
|
607
|
+
loaded.push(name);
|
|
608
|
+
} else {
|
|
609
|
+
failed.push({ name });
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
return { requested, loaded, failed };
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Resolve all unresolved string-based model references in a model tree before synchronous creation begins.
|
|
616
|
+
*
|
|
617
|
+
* Use this when you already have a model tree object, such as repository-returned data or resolved
|
|
618
|
+
* `createModelOptions`, and you need to ensure every string `use` in that tree has been loaded and
|
|
619
|
+
* registered into `_modelClasses` before calling `createModel()`.
|
|
620
|
+
*
|
|
621
|
+
* @param {unknown} data Model tree data
|
|
622
|
+
* @returns {Promise<EnsureBatchResult>} Batch ensure result
|
|
623
|
+
*/
|
|
624
|
+
async resolveModelTree(data) {
|
|
625
|
+
const requested = /* @__PURE__ */ new Set();
|
|
626
|
+
const loaded = /* @__PURE__ */ new Set();
|
|
627
|
+
const failed = /* @__PURE__ */ new Map();
|
|
628
|
+
const processed = /* @__PURE__ */ new Set();
|
|
629
|
+
const pending = /* @__PURE__ */ new Set();
|
|
630
|
+
this.collectModelNamesFromTree(data, pending);
|
|
631
|
+
while (pending.size > 0) {
|
|
632
|
+
const batch = Array.from(pending).filter((name) => !processed.has(name));
|
|
633
|
+
pending.clear();
|
|
634
|
+
if (batch.length === 0) {
|
|
635
|
+
break;
|
|
636
|
+
}
|
|
637
|
+
batch.forEach((name) => requested.add(name));
|
|
638
|
+
const result = await this.ensureModels(batch);
|
|
639
|
+
result.loaded.forEach((name) => {
|
|
640
|
+
processed.add(name);
|
|
641
|
+
loaded.add(name);
|
|
642
|
+
const modelClass = this.getModelClass(name);
|
|
643
|
+
if (modelClass) {
|
|
644
|
+
const discovered = /* @__PURE__ */ new Set();
|
|
645
|
+
this.collectModelNamesFromMetaDefaults(modelClass, discovered);
|
|
646
|
+
discovered.forEach((discoveredName) => {
|
|
647
|
+
if (!processed.has(discoveredName)) {
|
|
648
|
+
pending.add(discoveredName);
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
result.failed.forEach((item) => {
|
|
654
|
+
processed.add(item.name);
|
|
655
|
+
failed.set(item.name, item);
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
return {
|
|
659
|
+
requested: Array.from(requested),
|
|
660
|
+
loaded: Array.from(loaded),
|
|
661
|
+
failed: Array.from(failed.values())
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Preload all currently registered unresolved model loaders.
|
|
666
|
+
*
|
|
667
|
+
* This method is intended for flow-settings/discovery style entry points that need registered model
|
|
668
|
+
* classes to exist before UI is rendered, without requiring callers to know which specific models
|
|
669
|
+
* will be touched next.
|
|
670
|
+
*
|
|
671
|
+
* @returns {Promise<EnsureBatchResult>} Batch ensure result
|
|
672
|
+
*/
|
|
673
|
+
async preloadModelLoaders() {
|
|
674
|
+
const unresolved = Array.from(this._modelLoaders.keys()).filter((name) => !this._modelClasses.has(name));
|
|
675
|
+
if (unresolved.length === 0) {
|
|
676
|
+
this._modelLoadersPreloaded = true;
|
|
677
|
+
return { requested: [], loaded: [], failed: [] };
|
|
678
|
+
}
|
|
679
|
+
if (this._modelLoadersPreloadPromise) {
|
|
680
|
+
return this._modelLoadersPreloadPromise;
|
|
681
|
+
}
|
|
682
|
+
this._modelLoadersPreloadPromise = (async () => {
|
|
683
|
+
const result = await this.ensureModels(unresolved);
|
|
684
|
+
this._modelLoadersPreloaded = result.failed.length === 0;
|
|
685
|
+
this._modelLoadersPreloadPromise = void 0;
|
|
686
|
+
return result;
|
|
687
|
+
})();
|
|
688
|
+
return this._modelLoadersPreloadPromise;
|
|
689
|
+
}
|
|
387
690
|
registerResources(resources) {
|
|
388
691
|
for (const [name, resourceClass] of Object.entries(resources)) {
|
|
389
692
|
this._resources.set(name, resourceClass);
|
|
@@ -447,6 +750,55 @@ const _FlowEngine = class _FlowEngine {
|
|
|
447
750
|
}
|
|
448
751
|
return result;
|
|
449
752
|
}
|
|
753
|
+
/**
|
|
754
|
+
* Asynchronously get all subclasses of a base class, including those registered via model loaders.
|
|
755
|
+
* Merges results from already-loaded classes (_modelClasses) and async loader entries with matching `extends` declarations.
|
|
756
|
+
* Loader-resolved classes are validated with `isInheritedFrom`; mismatches are warned and excluded.
|
|
757
|
+
* @param {string | ModelConstructor} baseClass Base class name or constructor
|
|
758
|
+
* @param {(ModelClass: ModelConstructor, className: string) => boolean} [filter] Optional filter function
|
|
759
|
+
* @returns {Promise<Map<string, ModelConstructor>>} Model classes that are subclasses of the base class
|
|
760
|
+
*/
|
|
761
|
+
async getSubclassesOfAsync(baseClass, filter) {
|
|
762
|
+
var _a;
|
|
763
|
+
const baseClassName = typeof baseClass === "string" ? baseClass : baseClass.name;
|
|
764
|
+
let parentModelClass;
|
|
765
|
+
if (typeof baseClass === "string") {
|
|
766
|
+
if (!this.getModelClass(baseClass)) {
|
|
767
|
+
await this.ensureModel(baseClass);
|
|
768
|
+
}
|
|
769
|
+
parentModelClass = this.getModelClass(baseClass);
|
|
770
|
+
} else {
|
|
771
|
+
parentModelClass = baseClass;
|
|
772
|
+
}
|
|
773
|
+
if (!parentModelClass) {
|
|
774
|
+
return /* @__PURE__ */ new Map();
|
|
775
|
+
}
|
|
776
|
+
const result = this.getSubclassesOf(parentModelClass, filter);
|
|
777
|
+
const loaderCandidates = [];
|
|
778
|
+
for (const [name, entry] of this._modelLoaders) {
|
|
779
|
+
if (result.has(name) || this._modelClasses.has(name)) continue;
|
|
780
|
+
if ((_a = entry.extends) == null ? void 0 : _a.includes(baseClassName)) {
|
|
781
|
+
loaderCandidates.push(name);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
if (loaderCandidates.length > 0) {
|
|
785
|
+
await this.ensureModels(loaderCandidates);
|
|
786
|
+
}
|
|
787
|
+
for (const name of loaderCandidates) {
|
|
788
|
+
const ModelClass = this._modelClasses.get(name);
|
|
789
|
+
if (!ModelClass) continue;
|
|
790
|
+
if (!(0, import_utils.isInheritedFrom)(ModelClass, parentModelClass)) {
|
|
791
|
+
console.warn(
|
|
792
|
+
`FlowEngine: Model '${name}' declares extends '${baseClassName}' but does not actually inherit from it. Skipping.`
|
|
793
|
+
);
|
|
794
|
+
continue;
|
|
795
|
+
}
|
|
796
|
+
if (!filter || filter(ModelClass, name)) {
|
|
797
|
+
result.set(name, ModelClass);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
return result;
|
|
801
|
+
}
|
|
450
802
|
/**
|
|
451
803
|
* Create and register a model instance.
|
|
452
804
|
* If an instance with the same UID exists, returns the existing instance.
|
|
@@ -510,7 +862,6 @@ const _FlowEngine = class _FlowEngine {
|
|
|
510
862
|
const visited = /* @__PURE__ */ new Set();
|
|
511
863
|
while (current) {
|
|
512
864
|
if (visited.has(current)) {
|
|
513
|
-
console.warn(`FlowEngine: resolveUse circular reference detected on '${current.name}'.`);
|
|
514
865
|
break;
|
|
515
866
|
}
|
|
516
867
|
visited.add(current);
|
|
@@ -611,7 +962,7 @@ const _FlowEngine = class _FlowEngine {
|
|
|
611
962
|
removeModel(uid) {
|
|
612
963
|
var _a, _b, _c;
|
|
613
964
|
if (!this._modelInstances.has(uid)) {
|
|
614
|
-
|
|
965
|
+
this.logger.debug(`FlowEngine: Model with UID '${uid}' does not exist.`);
|
|
615
966
|
return false;
|
|
616
967
|
}
|
|
617
968
|
const modelInstance = this._modelInstances.get(uid);
|
|
@@ -732,7 +1083,7 @@ const _FlowEngine = class _FlowEngine {
|
|
|
732
1083
|
* Hydrate a model into current engine from an already-existing model instance in previous engines.
|
|
733
1084
|
* - Avoids repository requests when the model tree is already present in memory.
|
|
734
1085
|
*/
|
|
735
|
-
hydrateModelFromPreviousEngines(options, extra) {
|
|
1086
|
+
async hydrateModelFromPreviousEngines(options, extra) {
|
|
736
1087
|
var _a;
|
|
737
1088
|
const uid = options == null ? void 0 : options.uid;
|
|
738
1089
|
const parentId = options == null ? void 0 : options.parentId;
|
|
@@ -744,7 +1095,7 @@ const _FlowEngine = class _FlowEngine {
|
|
|
744
1095
|
}
|
|
745
1096
|
if (existing) {
|
|
746
1097
|
const data = existing.serialize();
|
|
747
|
-
return this.
|
|
1098
|
+
return this.createModelAsync(data, extra);
|
|
748
1099
|
}
|
|
749
1100
|
}
|
|
750
1101
|
if (parentId && subKey) {
|
|
@@ -755,10 +1106,10 @@ const _FlowEngine = class _FlowEngine {
|
|
|
755
1106
|
if (!localParent) {
|
|
756
1107
|
const parentData = parentFromPrev.serialize();
|
|
757
1108
|
delete parentData.subModels;
|
|
758
|
-
localParent = this.
|
|
1109
|
+
localParent = await this.createModelAsync(parentData, extra);
|
|
759
1110
|
}
|
|
760
1111
|
const modelData = modelFromPrev.serialize();
|
|
761
|
-
const localModel = this.
|
|
1112
|
+
const localModel = await this.createModelAsync(modelData, extra);
|
|
762
1113
|
const mounted = (_a = localParent.subModels) == null ? void 0 : _a[subKey];
|
|
763
1114
|
if (Array.isArray(mounted)) {
|
|
764
1115
|
const exists = mounted.some((m) => (m == null ? void 0 : m.uid) === (localModel == null ? void 0 : localModel.uid));
|
|
@@ -789,25 +1140,36 @@ const _FlowEngine = class _FlowEngine {
|
|
|
789
1140
|
async loadModel(options) {
|
|
790
1141
|
if (!this.ensureModelRepository()) return;
|
|
791
1142
|
const refresh = !!(options == null ? void 0 : options.refresh);
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
1143
|
+
const bypassLoadedPageCache = this._loadedPageCache.shouldBypass(options, () => this.context.flowSettingsEnabled);
|
|
1144
|
+
if (!refresh && !bypassLoadedPageCache) {
|
|
1145
|
+
const model2 = this.findModelByParentId(options.parentId, options.subKey);
|
|
1146
|
+
if (model2) {
|
|
1147
|
+
return model2;
|
|
796
1148
|
}
|
|
797
|
-
const hydrated = this.hydrateModelFromPreviousEngines(options);
|
|
1149
|
+
const hydrated = await this.hydrateModelFromPreviousEngines(options);
|
|
798
1150
|
if (hydrated) {
|
|
799
1151
|
return hydrated;
|
|
800
1152
|
}
|
|
801
1153
|
}
|
|
802
1154
|
const data = await this._modelRepository.findOne(options);
|
|
803
|
-
if (!(data == null ? void 0 : data.uid))
|
|
804
|
-
|
|
1155
|
+
if (!(data == null ? void 0 : data.uid)) {
|
|
1156
|
+
if (bypassLoadedPageCache) {
|
|
1157
|
+
this._loadedPageCache.clear(options);
|
|
1158
|
+
}
|
|
1159
|
+
return null;
|
|
1160
|
+
}
|
|
1161
|
+
if (refresh || bypassLoadedPageCache) {
|
|
805
1162
|
const existing = this.getModel(data.uid);
|
|
806
1163
|
if (existing) {
|
|
807
1164
|
this.removeModelWithSubModels(existing.uid);
|
|
808
1165
|
}
|
|
809
1166
|
}
|
|
810
|
-
|
|
1167
|
+
const model = await this.createModelAsync(data);
|
|
1168
|
+
if (bypassLoadedPageCache) {
|
|
1169
|
+
this._loadedPageCache.mountModelToParent(model, true);
|
|
1170
|
+
this._loadedPageCache.clear(options);
|
|
1171
|
+
}
|
|
1172
|
+
return model;
|
|
811
1173
|
}
|
|
812
1174
|
/**
|
|
813
1175
|
* Find a sub-model by parent model ID and subKey.
|
|
@@ -838,39 +1200,39 @@ const _FlowEngine = class _FlowEngine {
|
|
|
838
1200
|
async loadOrCreateModel(options, extra) {
|
|
839
1201
|
if (!this.ensureModelRepository()) return;
|
|
840
1202
|
const { uid, parentId, subKey } = options;
|
|
841
|
-
|
|
1203
|
+
const bypassLoadedPageCache = this._loadedPageCache.shouldBypass(options, () => this.context.flowSettingsEnabled);
|
|
1204
|
+
if (uid && !bypassLoadedPageCache && this._modelInstances.has(uid)) {
|
|
842
1205
|
return this._modelInstances.get(uid);
|
|
843
1206
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
1207
|
+
if (!bypassLoadedPageCache) {
|
|
1208
|
+
const m = this.findModelByParentId(parentId, subKey);
|
|
1209
|
+
if (m) {
|
|
1210
|
+
return m;
|
|
1211
|
+
}
|
|
1212
|
+
const hydrated = await this.hydrateModelFromPreviousEngines(options, extra);
|
|
1213
|
+
if (hydrated) {
|
|
1214
|
+
return hydrated;
|
|
1215
|
+
}
|
|
851
1216
|
}
|
|
852
1217
|
const data = await this._modelRepository.findOne(options);
|
|
853
1218
|
let model = null;
|
|
854
1219
|
if (data == null ? void 0 : data.uid) {
|
|
855
|
-
|
|
1220
|
+
if (bypassLoadedPageCache) {
|
|
1221
|
+
const existing = this.getModel(data.uid);
|
|
1222
|
+
if (existing) {
|
|
1223
|
+
this.removeModelWithSubModels(existing.uid);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
model = await this.createModelAsync(data, extra);
|
|
856
1227
|
} else {
|
|
857
|
-
model = this.
|
|
1228
|
+
model = await this.createModelAsync(options, extra);
|
|
858
1229
|
if (!(extra == null ? void 0 : extra.skipSave)) {
|
|
859
1230
|
await model.save();
|
|
860
1231
|
}
|
|
861
1232
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
});
|
|
866
|
-
if (subModel) {
|
|
867
|
-
return model;
|
|
868
|
-
}
|
|
869
|
-
if (model.subType === "array") {
|
|
870
|
-
model.parent.addSubModel(model.subKey, model);
|
|
871
|
-
} else {
|
|
872
|
-
model.parent.setSubModel(model.subKey, model);
|
|
873
|
-
}
|
|
1233
|
+
this._loadedPageCache.mountModelToParent(model, bypassLoadedPageCache);
|
|
1234
|
+
if (bypassLoadedPageCache) {
|
|
1235
|
+
this._loadedPageCache.clear(options);
|
|
874
1236
|
}
|
|
875
1237
|
return model;
|
|
876
1238
|
}
|
|
@@ -888,6 +1250,9 @@ const _FlowEngine = class _FlowEngine {
|
|
|
888
1250
|
async saveModel(model, options) {
|
|
889
1251
|
if (!this.ensureModelRepository()) return;
|
|
890
1252
|
const modelUid = model.uid;
|
|
1253
|
+
const dirtyLoadedPageKey = this._loadedPageCache.getDirtyKeyForModel(model, {
|
|
1254
|
+
force: !!(options == null ? void 0 : options.onlyStepParams)
|
|
1255
|
+
});
|
|
891
1256
|
if (this._savingModels.has(modelUid)) {
|
|
892
1257
|
this.logger.debug(`Model ${modelUid} is already being saved, waiting for existing save operation`);
|
|
893
1258
|
return await this._savingModels.get(modelUid);
|
|
@@ -896,6 +1261,7 @@ const _FlowEngine = class _FlowEngine {
|
|
|
896
1261
|
this._savingModels.set(modelUid, savePromise);
|
|
897
1262
|
try {
|
|
898
1263
|
const result = await savePromise;
|
|
1264
|
+
this._loadedPageCache.markDirty(dirtyLoadedPageKey);
|
|
899
1265
|
return result;
|
|
900
1266
|
} finally {
|
|
901
1267
|
this._savingModels.delete(modelUid);
|
|
@@ -926,10 +1292,15 @@ const _FlowEngine = class _FlowEngine {
|
|
|
926
1292
|
* @returns {Promise<boolean>} Whether destroyed successfully
|
|
927
1293
|
*/
|
|
928
1294
|
async destroyModel(uid) {
|
|
929
|
-
|
|
1295
|
+
const modelInstance = this._modelInstances.get(uid);
|
|
1296
|
+
const dirtyLoadedPageKey = this._loadedPageCache.getDirtyKeyForModel(modelInstance);
|
|
1297
|
+
const hasModelRepository = this.ensureModelRepository();
|
|
1298
|
+
if (hasModelRepository) {
|
|
930
1299
|
await this._modelRepository.destroy(uid);
|
|
931
1300
|
}
|
|
932
|
-
|
|
1301
|
+
if (hasModelRepository) {
|
|
1302
|
+
this._loadedPageCache.markDirty(dirtyLoadedPageKey);
|
|
1303
|
+
}
|
|
933
1304
|
const parent = modelInstance == null ? void 0 : modelInstance.parent;
|
|
934
1305
|
const result = this.removeModel(uid);
|
|
935
1306
|
parent && parent.emitter.emit("onSubModelDestroyed", modelInstance);
|
|
@@ -1005,18 +1376,25 @@ const _FlowEngine = class _FlowEngine {
|
|
|
1005
1376
|
}
|
|
1006
1377
|
/**
|
|
1007
1378
|
* Move a model instance within its parent model.
|
|
1008
|
-
* @param {
|
|
1009
|
-
* @param {
|
|
1379
|
+
* @param {string | number} sourceId Source model UID
|
|
1380
|
+
* @param {string | number} targetId Target model UID
|
|
1010
1381
|
* @returns {Promise<void>} No return value
|
|
1011
1382
|
*/
|
|
1012
1383
|
async moveModel(sourceId, targetId, options) {
|
|
1013
1384
|
var _a, _b;
|
|
1014
|
-
const
|
|
1015
|
-
const
|
|
1385
|
+
const sourceUid = String(sourceId);
|
|
1386
|
+
const targetUid = String(targetId);
|
|
1387
|
+
if (!sourceUid || !targetUid || sourceUid === targetUid) {
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
const sourceModel = this.getModel(sourceUid);
|
|
1391
|
+
const targetModel = this.getModel(targetUid);
|
|
1016
1392
|
if (!sourceModel || !targetModel) {
|
|
1017
1393
|
console.warn(`FlowEngine: Cannot move model. Source or target model not found.`);
|
|
1018
1394
|
return;
|
|
1019
1395
|
}
|
|
1396
|
+
let position = "after";
|
|
1397
|
+
const dirtyLoadedPageKey = this._loadedPageCache.getDirtyKeyForModel(sourceModel);
|
|
1020
1398
|
const move = /* @__PURE__ */ __name((sourceModel2, targetModel2) => {
|
|
1021
1399
|
if (!sourceModel2.parent || !targetModel2.parent || sourceModel2.parent !== targetModel2.parent) {
|
|
1022
1400
|
console.error("FlowModel.moveTo: Both models must have the same parent to perform move operation.");
|
|
@@ -1039,6 +1417,7 @@ const _FlowEngine = class _FlowEngine {
|
|
|
1039
1417
|
console.warn("FlowModel.moveTo: Current model is already at the target position. No action taken.");
|
|
1040
1418
|
return false;
|
|
1041
1419
|
}
|
|
1420
|
+
position = currentIndex < targetIndex ? "after" : "before";
|
|
1042
1421
|
const [movedModel] = subModelsCopy.splice(currentIndex, 1);
|
|
1043
1422
|
subModelsCopy.splice(targetIndex, 0, movedModel);
|
|
1044
1423
|
subModelsCopy.forEach((model, index) => {
|
|
@@ -1047,10 +1426,13 @@ const _FlowEngine = class _FlowEngine {
|
|
|
1047
1426
|
subModels.splice(0, subModels.length, ...subModelsCopy);
|
|
1048
1427
|
return true;
|
|
1049
1428
|
}, "move");
|
|
1050
|
-
move(sourceModel, targetModel);
|
|
1429
|
+
const moved = move(sourceModel, targetModel);
|
|
1430
|
+
if (!moved) {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1051
1433
|
if ((options == null ? void 0 : options.persist) !== false && this.ensureModelRepository()) {
|
|
1052
|
-
|
|
1053
|
-
|
|
1434
|
+
await this._modelRepository.move(sourceUid, targetUid, position);
|
|
1435
|
+
this._loadedPageCache.markDirty(dirtyLoadedPageKey);
|
|
1054
1436
|
}
|
|
1055
1437
|
sourceModel.parent.emitter.emit("onSubModelMoved", { source: sourceModel, target: targetModel });
|
|
1056
1438
|
(_b = this.emitter) == null ? void 0 : _b.emit("model:subModel:moved", {
|
|
@@ -1098,11 +1480,7 @@ _FlowEngine_instances = new WeakSet();
|
|
|
1098
1480
|
* @private
|
|
1099
1481
|
*/
|
|
1100
1482
|
registerModel_fn = /* @__PURE__ */ __name(function(name, modelClass) {
|
|
1101
|
-
|
|
1102
|
-
console.warn(`FlowEngine: Model class with name '${name}' is already registered and will be overwritten.`);
|
|
1103
|
-
}
|
|
1104
|
-
Object.defineProperty(modelClass, "name", { value: name });
|
|
1105
|
-
this._modelClasses.set(name, modelClass);
|
|
1483
|
+
return this._registerModel(name, modelClass);
|
|
1106
1484
|
}, "#registerModel");
|
|
1107
1485
|
__name(_FlowEngine, "FlowEngine");
|
|
1108
1486
|
let FlowEngine = _FlowEngine;
|
package/lib/flowI18n.js
CHANGED
|
@@ -71,7 +71,8 @@ const _FlowI18n = class _FlowI18n {
|
|
|
71
71
|
translateKey(key, options) {
|
|
72
72
|
var _a, _b;
|
|
73
73
|
if ((_b = (_a = this.context) == null ? void 0 : _a.i18n) == null ? void 0 : _b.t) {
|
|
74
|
-
|
|
74
|
+
const translated = this.context.i18n.t(key, options);
|
|
75
|
+
return translated == null || translated === "" ? key : translated;
|
|
75
76
|
}
|
|
76
77
|
return key;
|
|
77
78
|
}
|