cabloy 5.1.172 → 5.1.173
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/.cabloy-version +1 -1
- package/CHANGELOG.md +6 -0
- package/package.json +2 -2
- package/repo-docs/frontend/component-guide.md +33 -0
- package/repo-docs/frontend/model-resource-cookbook.md +0 -8
- package/repo-docs/frontend/model-resource-usage-guide.md +0 -4
- package/repo-e2e/specs/cabloy-basic.spec.ts +158 -0
- package/repo-e2e/specs/controller-boundary.spec.ts +261 -0
- package/test-results/.last-run.json +1 -1
- package/vona/packages-utils/lint/package.json +1 -1
- package/vona/packages-utils/lint/src/oxc/lint.ts +1 -1
- package/vona/packages-utils/lint/src/oxc/lintVue.ts +1 -1
- package/zova/package.original.json +1 -1
- package/zova/packages-cli/cli/package.json +2 -2
- package/zova/packages-cli/cli-set-front/package.json +3 -3
- package/zova/packages-utils/babel-plugin-zova-behavior/package.json +2 -1
- package/zova/packages-utils/babel-plugin-zova-behavior/src/index.ts +21 -8
- package/zova/packages-utils/babel-plugin-zova-behavior/test/behaviorSlots.test.ts +111 -0
- package/zova/packages-utils/zova-jsx/package.json +2 -2
- package/zova/packages-utils/zova-vite/package.json +2 -2
- package/zova/packages-zova/zova/package.json +3 -3
- package/zova/packages-zova/zova-core/package.json +1 -1
- package/zova/packages-zova/zova-core/src/bean/beanBase.ts +1 -1
- package/zova/packages-zova/zova-core/src/bean/beanContainer.ts +95 -39
- package/zova/packages-zova/zova-core/src/bean/resource/error/type.ts +9 -0
- package/zova/packages-zova/zova-core/src/bean/type.ts +18 -0
- package/zova/packages-zova/zova-core/src/components/component.ts +2 -1
- package/zova/packages-zova/zova-core/src/composables/useController.ts +155 -25
- package/zova/packages-zova/zova-core/src/core/component/error.ts +62 -5
- package/zova/packages-zova/zova-core/src/core/context/component.ts +37 -2
- package/zova/packages-zova/zova-core/src/core/context/hooks.ts +13 -2
- package/zova/packages-zova/zova-core/src/core/context/meta.ts +1 -0
- package/zova/packages-zova/zova-core/src/core/context/state.ts +161 -0
- package/zova/packages-zova/zova-core/src/core/sys/config.ts +32 -7
- package/zova/packages-zova/zova-core/src/types/interface/monkey.ts +15 -0
- package/zova/packages-zova/zova-core/src/types/utils/powerPartial.ts +1 -1
- package/zova/pnpm-lock.yaml +69 -54
- package/zova/src/front/config/config/config.ts +11 -0
- package/zova/src/front/config/config/render.tsx +79 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/order.ts +0 -1
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/component/controllerBoundaryProbe.ts +31 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/component/controllerBoundaryProbeInline.ts +34 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/component/controllerBoundaryProbeOverride.ts +34 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/index.ts +58 -1
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/page/controllerBoundary.ts +23 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/component/controllerBoundaryProbe/controller.tsx +36 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/component/controllerBoundaryProbeInline/controller.tsx +34 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/component/controllerBoundaryProbeOverride/controller.tsx +46 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/page/controllerBoundary/controller.tsx +185 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/routes.ts +6 -0
- package/zova/src/suite/a-home/modules/home-base/src/config/locale/en-us.ts +1 -0
- package/zova/src/suite/a-home/modules/home-base/src/config/locale/zh-cn.ts +1 -0
- package/zova/src/suite/a-training/modules/training-student/src/model/student.ts +0 -3
- package/zova/src/suite/cabloy-basic/modules/basic-button/package.json +58 -0
- package/zova/src/suite/cabloy-basic/modules/basic-button/src/.metadata/component/button.ts +31 -0
- package/zova/src/suite/cabloy-basic/modules/basic-button/src/.metadata/index.ts +122 -0
- package/zova/src/suite/cabloy-basic/modules/basic-button/src/.metadata/this.ts +2 -0
- package/zova/src/suite/cabloy-basic/modules/basic-button/src/bean/behavior.perform.tsx +103 -0
- package/zova/src/suite/cabloy-basic/modules/basic-button/src/component/button/controller.tsx +39 -0
- package/zova/src/suite/cabloy-basic/modules/basic-button/src/index.ts +1 -0
- package/zova/src/suite/cabloy-basic/modules/basic-button/tsconfig.build.json +13 -0
- package/zova/src/suite/cabloy-basic/modules/basic-button/tsconfig.json +5 -0
- package/zova/src/suite/cabloy-basic/modules/basic-details/package.json +2 -1
- package/zova/src/suite/cabloy-basic/modules/basic-details/src/bean/tableCell.actionDelete.tsx +4 -4
- package/zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx +5 -1
- package/zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx +5 -1
- package/zova/src/suite/cabloy-basic/modules/basic-table/package.json +2 -1
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/bean/tableCell.actionDelete.tsx +4 -4
- package/zova/src/suite/cabloy-basic/modules/basic-table/src/component/actionRefresh/controller.tsx +10 -8
- package/zova/src/suite/cabloy-basic/package.json +1 -0
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/a-layoutprofile/src/model/layoutprofile.ts +0 -3
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/page/resource.ts +6 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +0 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resource/controller.tsx +5 -1
- package/zova/src/suite-vendor/a-cabloy/package.json +3 -3
- package/zova/src/suite-vendor/a-zova/modules/a-bean/cli/controller/metadata/generateFilePage.ts +3 -1
- package/zova/src/suite-vendor/a-zova/modules/a-bean/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-model/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useMutation.ts +1 -11
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useQuery.ts +1 -17
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/lib/utils.ts +2 -1
- package/zova/src/suite-vendor/a-zova/modules/a-model/src/types/query.ts +2 -7
- package/zova/src/suite-vendor/a-zova/modules/a-model/test/lib/mutation.types.ts +14 -0
- package/zova/src/suite-vendor/a-zova/modules/a-model/test/lib/queryEnsureLoaded.test.ts +56 -0
- package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkey.ts +8 -0
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssr.ts +85 -1
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/monkey.ts +25 -1
- package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/types/ssr.ts +15 -1
- package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/package.json +6 -6
|
@@ -92,13 +92,16 @@ function createVisitor(context: ContextInfo) {
|
|
|
92
92
|
),
|
|
93
93
|
);
|
|
94
94
|
// -> ()=>{}
|
|
95
|
-
const children = (nodePath.container as
|
|
96
|
-
if (children
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
const children = (nodePath.container as t.JSXElement).children;
|
|
96
|
+
if (children.length > 0 && _shouldWrapChildrenInSlot(tag, children)) {
|
|
97
|
+
const expressionSlot = t.arrowFunctionExpression(
|
|
98
|
+
[],
|
|
99
|
+
t.arrayExpression([
|
|
100
|
+
t.jsxFragment(t.jsxOpeningFragment(), t.jsxClosingFragment(), children),
|
|
101
|
+
]),
|
|
102
|
+
);
|
|
100
103
|
const expressionSlotContainer = t.jsxExpressionContainer(expressionSlot);
|
|
101
|
-
(nodePath.container as
|
|
104
|
+
(nodePath.container as t.JSXElement).children = [expressionSlotContainer];
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
}
|
|
@@ -106,8 +109,18 @@ function createVisitor(context: ContextInfo) {
|
|
|
106
109
|
};
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
function
|
|
110
|
-
|
|
112
|
+
function _shouldWrapChildrenInSlot(tag: t.Expression, children: t.JSXElement['children']) {
|
|
113
|
+
if (_hasExplicitDefaultSlotFunction(children)) return false;
|
|
114
|
+
return t.isStringLiteral(tag) || !children.some(child => t.isJSXExpressionContainer(child));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function _hasExplicitDefaultSlotFunction(children: t.JSXElement['children']) {
|
|
118
|
+
if (children.length !== 1) return false;
|
|
119
|
+
const [child] = children;
|
|
120
|
+
return (
|
|
121
|
+
t.isJSXExpressionContainer(child) &&
|
|
122
|
+
(t.isArrowFunctionExpression(child.expression) || t.isFunctionExpression(child.expression))
|
|
123
|
+
);
|
|
111
124
|
}
|
|
112
125
|
|
|
113
126
|
// bs-providerId-moduleName-beanName
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { transformSync, traverse, types as t } from '@babel/core';
|
|
2
|
+
import vueJsx from '@vue/babel-plugin-jsx';
|
|
3
|
+
import { renderToString } from '@vue/server-renderer';
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import test from 'node:test';
|
|
6
|
+
import { createVNode, Fragment } from 'vue';
|
|
7
|
+
|
|
8
|
+
import behavior from '../src/index.ts';
|
|
9
|
+
|
|
10
|
+
function transform(source: string) {
|
|
11
|
+
const result = transformSync(source, {
|
|
12
|
+
filename: 'fixture.tsx',
|
|
13
|
+
configFile: false,
|
|
14
|
+
babelrc: false,
|
|
15
|
+
ast: true,
|
|
16
|
+
plugins: [behavior, vueJsx],
|
|
17
|
+
});
|
|
18
|
+
assert.ok(result?.ast);
|
|
19
|
+
return result.ast;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getBehaviorVNodeChildren(ast: t.File) {
|
|
23
|
+
let children: t.Expression | null | undefined;
|
|
24
|
+
traverse(ast, {
|
|
25
|
+
CallExpression(path) {
|
|
26
|
+
if (!t.isIdentifier(path.node.callee, { name: '_createVNode' })) return;
|
|
27
|
+
const [tag, , vnodeChildren] = path.node.arguments;
|
|
28
|
+
if (!t.isCallExpression(tag)) return;
|
|
29
|
+
if (!t.isIdentifier(tag.callee, { name: '_resolveComponent' })) return;
|
|
30
|
+
if (!t.isStringLiteral(tag.arguments[0], { value: 'ZBehavior__' })) return;
|
|
31
|
+
children = vnodeChildren as t.Expression | null | undefined;
|
|
32
|
+
path.stop();
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
assert.notEqual(children, undefined, 'should render ZBehavior__');
|
|
36
|
+
return children;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getDefaultSlot(children: t.Expression | null | undefined) {
|
|
40
|
+
assert.ok(t.isObjectExpression(children), 'ZBehavior__ children should be a slot object');
|
|
41
|
+
const defaultSlot = children.properties.find(
|
|
42
|
+
property =>
|
|
43
|
+
t.isObjectProperty(property) &&
|
|
44
|
+
t.isIdentifier(property.key, { name: 'default' }) &&
|
|
45
|
+
t.isArrowFunctionExpression(property.value),
|
|
46
|
+
);
|
|
47
|
+
assert.ok(defaultSlot && t.isObjectProperty(defaultSlot));
|
|
48
|
+
assert.ok(t.isArrowFunctionExpression(defaultSlot.value));
|
|
49
|
+
return defaultSlot.value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getSlotFragmentChildren(defaultSlot: t.ArrowFunctionExpression) {
|
|
53
|
+
assert.ok(t.isArrayExpression(defaultSlot.body));
|
|
54
|
+
assert.equal(defaultSlot.body.elements.length, 1);
|
|
55
|
+
const [fragment] = defaultSlot.body.elements;
|
|
56
|
+
assert.ok(t.isCallExpression(fragment));
|
|
57
|
+
const children = fragment.arguments[2];
|
|
58
|
+
assert.ok(t.isArrayExpression(children));
|
|
59
|
+
return children.elements;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
test('native behavior target wraps a dynamic child in a default slot', () => {
|
|
63
|
+
const ast = transform(
|
|
64
|
+
'const dom = <button bs-basic-button-perform={options}>{this.$slotDefault?.()}</button>;',
|
|
65
|
+
);
|
|
66
|
+
const defaultSlot = getDefaultSlot(getBehaviorVNodeChildren(ast));
|
|
67
|
+
const children = getSlotFragmentChildren(defaultSlot);
|
|
68
|
+
assert.equal(children.length, 1);
|
|
69
|
+
assert.ok(t.isOptionalCallExpression(children[0]));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('native behavior target wraps static children in a default slot', () => {
|
|
73
|
+
const ast = transform('const dom = <button bs-basic-button-perform={options}>Delete</button>;');
|
|
74
|
+
const defaultSlot = getDefaultSlot(getBehaviorVNodeChildren(ast));
|
|
75
|
+
assert.equal(getSlotFragmentChildren(defaultSlot).length, 1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('native behavior target preserves an explicit default slot function', () => {
|
|
79
|
+
const ast = transform(
|
|
80
|
+
'const dom = <button bs-basic-button-perform={options}>{() => this.$slotDefault?.()}</button>;',
|
|
81
|
+
);
|
|
82
|
+
const defaultSlot = getDefaultSlot(getBehaviorVNodeChildren(ast));
|
|
83
|
+
assert.ok(t.isOptionalCallExpression(defaultSlot.body));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('native behavior target without children does not create a default slot', () => {
|
|
87
|
+
const ast = transform('const dom = <button bs-basic-button-perform={options} />;');
|
|
88
|
+
assert.ok(t.isNullLiteral(getBehaviorVNodeChildren(ast)));
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('component behavior target keeps dynamic children as a default slot', () => {
|
|
92
|
+
const ast = transform(
|
|
93
|
+
'const dom = <VBtn bs-start-button-perform={options}>{this.$slotDefault?.()}</VBtn>;',
|
|
94
|
+
);
|
|
95
|
+
const defaultSlot = getDefaultSlot(getBehaviorVNodeChildren(ast));
|
|
96
|
+
assert.ok(t.isArrayExpression(defaultSlot.body));
|
|
97
|
+
assert.equal(defaultSlot.body.elements.length, 1);
|
|
98
|
+
assert.ok(t.isOptionalCallExpression(defaultSlot.body.elements[0]));
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('native targets render a default slot that returns an array', async () => {
|
|
102
|
+
const fragment = createVNode(Fragment, null, ['Delete']);
|
|
103
|
+
const html = await renderToString(createVNode('button', null, { default: () => [fragment] }));
|
|
104
|
+
assert.match(html, /Delete/);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('native targets do not render a default slot that returns a bare Fragment', async () => {
|
|
108
|
+
const fragment = createVNode(Fragment, null, ['Delete']);
|
|
109
|
+
const html = await renderToString(createVNode('button', null, { default: () => fragment }));
|
|
110
|
+
assert.doesNotMatch(html, /Delete/);
|
|
111
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova-jsx",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.90",
|
|
4
4
|
"gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
|
|
5
5
|
"description": "Zova JSX",
|
|
6
6
|
"keywords": [
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@cabloy/word-utils": "^2.1.14",
|
|
51
51
|
"typestyle": "^2.4.0",
|
|
52
52
|
"vue": "^3.5.38",
|
|
53
|
-
"zova-core": "^5.1.
|
|
53
|
+
"zova-core": "^5.1.90"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"clean-package": "^2.2.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova-vite",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.46",
|
|
4
4
|
"gitHead": "09d901d17140a80ee0764211b441cda72fd94663",
|
|
5
5
|
"description": "zova vite",
|
|
6
6
|
"keywords": [
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"babel-plugin-transform-typescript-metadata": "^0.4.0",
|
|
59
59
|
"babel-plugin-zova-bean-module": "^1.2.15",
|
|
60
60
|
"babel-plugin-zova-bean-use": "^1.1.15",
|
|
61
|
-
"babel-plugin-zova-behavior": "^1.1.
|
|
61
|
+
"babel-plugin-zova-behavior": "^1.1.16",
|
|
62
62
|
"babel-plugin-zova-component": "^1.1.15",
|
|
63
63
|
"chalk": "^3.0.0",
|
|
64
64
|
"esbuild": "^0.25.12",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zova",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.163",
|
|
4
4
|
"gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
|
|
5
5
|
"description": "A vue3 framework with ioc",
|
|
6
6
|
"keywords": [
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"postpack": "clean-package restore"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"zova-core": "^5.1.
|
|
49
|
-
"zova-suite-a-zova": "^5.1.
|
|
48
|
+
"zova-core": "^5.1.90",
|
|
49
|
+
"zova-suite-a-zova": "^5.1.162"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"clean-package": "^2.2.0",
|
|
@@ -192,7 +192,7 @@ export class BeanBase extends BeanBaseSimple {
|
|
|
192
192
|
|
|
193
193
|
protected $controllerMounted(fn: any) {
|
|
194
194
|
return this.ctx.util.instanceScope(() => {
|
|
195
|
-
return this.ctx.meta.hooks.onMounted(fn);
|
|
195
|
+
return this.ctx.meta.hooks.onMounted(fn, this);
|
|
196
196
|
});
|
|
197
197
|
}
|
|
198
198
|
|
|
@@ -74,50 +74,90 @@ export class BeanContainer {
|
|
|
74
74
|
/** @internal */
|
|
75
75
|
public dispose() {
|
|
76
76
|
const beanInstances = this[SymbolBeanContainerInstances];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
this
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
this
|
|
103
|
-
|
|
104
|
-
|
|
77
|
+
let error: Error | undefined;
|
|
78
|
+
try {
|
|
79
|
+
for (const prop in beanInstances) {
|
|
80
|
+
if (prop.startsWith('$$')) continue;
|
|
81
|
+
const beanInstance = cast(beanInstances[prop]);
|
|
82
|
+
if (!beanInstance || beanInstance instanceof BeanAopBase || !beanInstance.__dispose__)
|
|
83
|
+
continue;
|
|
84
|
+
try {
|
|
85
|
+
if (this.containerType === 'sys') {
|
|
86
|
+
this.sys.meta.module._monkeyModuleSync(
|
|
87
|
+
false,
|
|
88
|
+
'beanDispose',
|
|
89
|
+
undefined,
|
|
90
|
+
this,
|
|
91
|
+
beanInstance,
|
|
92
|
+
);
|
|
93
|
+
beanInstance.__dispose__();
|
|
94
|
+
this.sys.meta.module._monkeyModuleSync(
|
|
95
|
+
false,
|
|
96
|
+
'beanDisposed',
|
|
97
|
+
undefined,
|
|
98
|
+
this,
|
|
99
|
+
beanInstance,
|
|
100
|
+
);
|
|
101
|
+
} else {
|
|
102
|
+
this.app.meta.module._monkeyModuleSync(
|
|
103
|
+
false,
|
|
104
|
+
'beanDispose',
|
|
105
|
+
undefined,
|
|
106
|
+
this,
|
|
107
|
+
beanInstance,
|
|
108
|
+
);
|
|
109
|
+
this.runWithInstanceScopeOrAppContext(() => {
|
|
110
|
+
return beanInstance.__dispose__();
|
|
111
|
+
});
|
|
112
|
+
this.app.meta.module._monkeyModuleSync(
|
|
113
|
+
false,
|
|
114
|
+
'beanDisposed',
|
|
115
|
+
undefined,
|
|
116
|
+
this,
|
|
117
|
+
beanInstance,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
} catch (err) {
|
|
121
|
+
error ??= err as Error;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} finally {
|
|
125
|
+
this[SymbolBeanContainerInstances] = shallowReactive({});
|
|
126
|
+
this[SymbolBeanContainerParent] = undefined;
|
|
127
|
+
this[SymbolGetBeanSelectorInnerPromises] = {};
|
|
128
|
+
}
|
|
129
|
+
// eslint-disable no-throw-literal
|
|
130
|
+
if (error) throw error;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** @internal */
|
|
134
|
+
public retryReset(ownedBeans: Set<object>) {
|
|
135
|
+
const beanInstances = this[SymbolBeanContainerInstances];
|
|
136
|
+
let error: Error | undefined;
|
|
137
|
+
try {
|
|
138
|
+
for (const prop in beanInstances) {
|
|
139
|
+
const beanInstance = cast(beanInstances[prop]);
|
|
140
|
+
if (!ownedBeans.has(beanInstance)) continue;
|
|
141
|
+
if (!beanInstance || beanInstance instanceof BeanAopBase || !beanInstance.__dispose__)
|
|
142
|
+
continue;
|
|
143
|
+
try {
|
|
105
144
|
this.runWithInstanceScopeOrAppContext(() => {
|
|
106
145
|
return beanInstance.__dispose__();
|
|
107
146
|
});
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
'beanDisposed',
|
|
111
|
-
undefined,
|
|
112
|
-
this,
|
|
113
|
-
beanInstance,
|
|
114
|
-
);
|
|
147
|
+
} catch (err) {
|
|
148
|
+
error ??= err as Error;
|
|
115
149
|
}
|
|
116
150
|
}
|
|
151
|
+
} finally {
|
|
152
|
+
for (const prop in beanInstances) {
|
|
153
|
+
if (ownedBeans.has(cast(beanInstances[prop]))) {
|
|
154
|
+
delete beanInstances[prop];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
this[SymbolGetBeanSelectorInnerPromises] = {};
|
|
117
158
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this[SymbolGetBeanSelectorInnerPromises] = {};
|
|
159
|
+
// eslint-disable no-throw-literal
|
|
160
|
+
if (error) throw error;
|
|
121
161
|
}
|
|
122
162
|
|
|
123
163
|
get containerType(): ContainerType {
|
|
@@ -355,6 +395,7 @@ export class BeanContainer {
|
|
|
355
395
|
fullName,
|
|
356
396
|
markReactive,
|
|
357
397
|
withSelector,
|
|
398
|
+
undefined,
|
|
358
399
|
...args,
|
|
359
400
|
);
|
|
360
401
|
}
|
|
@@ -382,7 +423,16 @@ export class BeanContainer {
|
|
|
382
423
|
markReactive?: boolean,
|
|
383
424
|
...args
|
|
384
425
|
): Promise<T> {
|
|
385
|
-
return await this._newBeanInner(
|
|
426
|
+
return await this._newBeanInner(
|
|
427
|
+
false,
|
|
428
|
+
null,
|
|
429
|
+
null,
|
|
430
|
+
beanFullName,
|
|
431
|
+
markReactive,
|
|
432
|
+
false,
|
|
433
|
+
undefined,
|
|
434
|
+
...args,
|
|
435
|
+
);
|
|
386
436
|
}
|
|
387
437
|
|
|
388
438
|
async _newBeanSelector<T>(
|
|
@@ -415,6 +465,7 @@ export class BeanContainer {
|
|
|
415
465
|
beanFullName: Constructable<T> | string | undefined,
|
|
416
466
|
markReactive?: boolean,
|
|
417
467
|
withSelector?: boolean,
|
|
468
|
+
onBeanRecorded?: (beanInstance: T) => void,
|
|
418
469
|
...args
|
|
419
470
|
): Promise<T> {
|
|
420
471
|
// bean options
|
|
@@ -432,6 +483,7 @@ export class BeanContainer {
|
|
|
432
483
|
false,
|
|
433
484
|
markReactive,
|
|
434
485
|
withSelector,
|
|
486
|
+
onBeanRecorded,
|
|
435
487
|
);
|
|
436
488
|
}
|
|
437
489
|
// throw new Error(`bean not found: ${beanFullName}`);
|
|
@@ -449,6 +501,7 @@ export class BeanContainer {
|
|
|
449
501
|
// default is true: same as inject prop
|
|
450
502
|
markReactive ?? beanOptions.markReactive ?? true,
|
|
451
503
|
withSelector,
|
|
504
|
+
onBeanRecorded,
|
|
452
505
|
);
|
|
453
506
|
}
|
|
454
507
|
|
|
@@ -504,6 +557,7 @@ export class BeanContainer {
|
|
|
504
557
|
aop: boolean | undefined,
|
|
505
558
|
markReactive: boolean | undefined,
|
|
506
559
|
withSelector?: boolean,
|
|
560
|
+
onBeanRecorded?: (beanInstance: T) => void,
|
|
507
561
|
): Promise<T> {
|
|
508
562
|
// prepare
|
|
509
563
|
const beanInstance = await this._prepareBeanInstance(
|
|
@@ -530,6 +584,7 @@ export class BeanContainer {
|
|
|
530
584
|
if (recordProp) {
|
|
531
585
|
this.__recordProp(recordProp, fullName, beanInstance, true);
|
|
532
586
|
}
|
|
587
|
+
onBeanRecorded?.(beanInstance);
|
|
533
588
|
}
|
|
534
589
|
// init
|
|
535
590
|
await this._initBeanInstance(beanFullName, beanInstance, args);
|
|
@@ -781,6 +836,7 @@ export class BeanContainer {
|
|
|
781
836
|
targetBeanFullName,
|
|
782
837
|
markReactive,
|
|
783
838
|
selectorInfo.withSelector,
|
|
839
|
+
undefined,
|
|
784
840
|
...selectorInfo.args,
|
|
785
841
|
);
|
|
786
842
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ComponentPublicInstance } from 'vue';
|
|
2
2
|
|
|
3
|
+
import type { ZovaContext } from '../../../core/context/context.ts';
|
|
3
4
|
import type { IErrorObject } from './errorObject.ts';
|
|
4
5
|
|
|
5
6
|
export const SymbolErrorInstanceInfo = Symbol('SymbolErrorInstanceInfo');
|
|
@@ -9,10 +10,18 @@ export interface IErrorInstanceInfo {
|
|
|
9
10
|
info?: string;
|
|
10
11
|
}
|
|
11
12
|
|
|
13
|
+
export interface IErrorHandlerLoad {
|
|
14
|
+
readonly kind: 'controller-load';
|
|
15
|
+
readonly ctx: ZovaContext;
|
|
16
|
+
readonly originalError: unknown;
|
|
17
|
+
disposition: 'fallback' | 'handled';
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
export interface IErrorHandlerEventData {
|
|
13
21
|
err: Error;
|
|
14
22
|
instance?: ComponentPublicInstance | null;
|
|
15
23
|
info?: string;
|
|
24
|
+
load?: IErrorHandlerLoad;
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
export type IErrorHandlerEventResult = Error | undefined;
|
|
@@ -85,8 +85,26 @@ export interface DefineModelOptions<T = any, G = T, S = T> {
|
|
|
85
85
|
set?: (v: S) => any;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
export type TypeComponentBoundaryRenderMode = 'block' | 'inline';
|
|
89
|
+
export type TypeComponentBoundaryRetry = () => Promise<void>;
|
|
90
|
+
|
|
91
|
+
export interface IComponentBoundaryLoadingOptions {
|
|
92
|
+
delay?: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface IComponentBoundaryOptions {
|
|
96
|
+
loading?: IComponentBoundaryLoadingOptions;
|
|
97
|
+
renderMode?: TypeComponentBoundaryRenderMode;
|
|
98
|
+
/**
|
|
99
|
+
* Declares that this Controller can safely construct a fresh load graph after a fallback error.
|
|
100
|
+
* It is disabled by default because Controller initialization may include non-idempotent work.
|
|
101
|
+
*/
|
|
102
|
+
retry?: boolean;
|
|
103
|
+
}
|
|
104
|
+
|
|
88
105
|
export type IComponentOptions = Parameters<typeof defineOptions>[0] & {
|
|
89
106
|
deepExtendDefault?: boolean;
|
|
107
|
+
boundary?: IComponentBoundaryOptions;
|
|
90
108
|
};
|
|
91
109
|
|
|
92
110
|
export type IEmit = () => void;
|
|
@@ -9,11 +9,12 @@ export function createZovaComponentPage<M, R, S>(
|
|
|
9
9
|
controller: Constructable<M>,
|
|
10
10
|
render?: Constructable<R>,
|
|
11
11
|
style?: Constructable<S>,
|
|
12
|
+
componentOptions?: IComponentOptions,
|
|
12
13
|
) {
|
|
13
14
|
return defineComponent(() => {
|
|
14
15
|
useControllerPage(controller, render, style);
|
|
15
16
|
return () => {};
|
|
16
|
-
});
|
|
17
|
+
}, prepareComponentOptions(componentOptions));
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export function prepareComponentOptions(componentOptions?: IComponentOptions) {
|