@eggjs/tegg-metadata 4.0.0-beta.6 → 4.0.0-beta.8
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/dist/index.d.ts +405 -21
- package/dist/index.js +1256 -24
- package/package.json +6 -7
- package/dist/errors.d.ts +0 -18
- package/dist/errors.js +0 -29
- package/dist/factory/EggPrototypeCreatorFactory.d.ts +0 -13
- package/dist/factory/EggPrototypeCreatorFactory.js +0 -95
- package/dist/factory/EggPrototypeFactory.d.ts +0 -13
- package/dist/factory/EggPrototypeFactory.js +0 -41
- package/dist/factory/LoadUnitFactory.d.ts +0 -16
- package/dist/factory/LoadUnitFactory.js +0 -58
- package/dist/factory/index.js +0 -5
- package/dist/impl/EggPrototypeBuilder.d.ts +0 -26
- package/dist/impl/EggPrototypeBuilder.js +0 -115
- package/dist/impl/EggPrototypeImpl.d.ts +0 -28
- package/dist/impl/EggPrototypeImpl.js +0 -52
- package/dist/impl/LoadUnitMultiInstanceProtoHook.d.ts +0 -11
- package/dist/impl/LoadUnitMultiInstanceProtoHook.js +0 -16
- package/dist/impl/ModuleLoadUnit.d.ts +0 -38
- package/dist/impl/ModuleLoadUnit.js +0 -211
- package/dist/impl/index.js +0 -6
- package/dist/model/AppGraph.d.ts +0 -42
- package/dist/model/AppGraph.js +0 -195
- package/dist/model/EggPrototype.d.ts +0 -7
- package/dist/model/EggPrototype.js +0 -7
- package/dist/model/LoadUnit.d.ts +0 -7
- package/dist/model/LoadUnit.js +0 -7
- package/dist/model/ModuleDescriptor.d.ts +0 -22
- package/dist/model/ModuleDescriptor.js +0 -33
- package/dist/model/ProtoDescriptor/AbstractProtoDescriptor.d.ts +0 -36
- package/dist/model/ProtoDescriptor/AbstractProtoDescriptor.js +0 -35
- package/dist/model/ProtoDescriptor/ClassProtoDescriptor.d.ts +0 -16
- package/dist/model/ProtoDescriptor/ClassProtoDescriptor.js +0 -27
- package/dist/model/ProtoDescriptor/index.js +0 -4
- package/dist/model/ProtoDescriptorHelper.d.ts +0 -30
- package/dist/model/ProtoDescriptorHelper.js +0 -113
- package/dist/model/graph/GlobalGraph.d.ts +0 -67
- package/dist/model/graph/GlobalGraph.js +0 -176
- package/dist/model/graph/GlobalModuleNode.d.ts +0 -29
- package/dist/model/graph/GlobalModuleNode.js +0 -42
- package/dist/model/graph/GlobalModuleNodeBuilder.d.ts +0 -17
- package/dist/model/graph/GlobalModuleNodeBuilder.js +0 -56
- package/dist/model/graph/ProtoNode.d.ts +0 -25
- package/dist/model/graph/ProtoNode.js +0 -43
- package/dist/model/graph/ProtoSelector.d.ts +0 -10
- package/dist/model/graph/ProtoSelector.js +0 -3
- package/dist/model/graph/index.js +0 -7
- package/dist/model/index.js +0 -15
- package/dist/util/ClassUtil.d.ts +0 -9
- package/dist/util/ClassUtil.js +0 -18
- package/dist/util/index.js +0 -3
package/dist/index.js
CHANGED
|
@@ -1,28 +1,1260 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import { EggPrototypeLifecycleUtil } from "./model/EggPrototype.js";
|
|
12
|
-
import { LoadUnitLifecycleUtil } from "./model/LoadUnit.js";
|
|
13
|
-
import { ModuleDescriptorDumper } from "./model/ModuleDescriptor.js";
|
|
14
|
-
import "./model/index.js";
|
|
15
|
-
import { EggPrototypeCreatorFactory } from "./factory/EggPrototypeCreatorFactory.js";
|
|
16
|
-
import { LoadUnitFactory } from "./factory/LoadUnitFactory.js";
|
|
17
|
-
import "./factory/index.js";
|
|
18
|
-
import { ClassUtil } from "./util/ClassUtil.js";
|
|
19
|
-
import "./util/index.js";
|
|
20
|
-
import { EggPrototypeImpl } from "./impl/EggPrototypeImpl.js";
|
|
21
|
-
import { EggPrototypeBuilder } from "./impl/EggPrototypeBuilder.js";
|
|
22
|
-
import { LoadUnitMultiInstanceProtoHook } from "./impl/LoadUnitMultiInstanceProtoHook.js";
|
|
23
|
-
import { ModuleGraph, ModuleLoadUnit } from "./impl/ModuleLoadUnit.js";
|
|
24
|
-
import "./impl/index.js";
|
|
1
|
+
import { Graph, GraphNode, MapUtil, ModuleConfigUtil } from "@eggjs/tegg-common-util";
|
|
2
|
+
import { AccessLevel, DEFAULT_PROTO_IMPL_TYPE, EggLoadUnitType, ErrorCodes, INIT_TYPE_TRY_ORDER, InitTypeQualifierAttribute, LoadUnitNameQualifierAttribute, MultiInstanceType, ObjectInitType, ProtoDescriptorType } from "@eggjs/tegg-types";
|
|
3
|
+
import { FrameworkBaseError, FrameworkErrorFormater } from "egg-errors";
|
|
4
|
+
import assert from "node:assert";
|
|
5
|
+
import util, { debuglog } from "node:util";
|
|
6
|
+
import { InitTypeQualifierAttribute as InitTypeQualifierAttribute$1, InjectType, LoadUnitNameQualifierAttribute as LoadUnitNameQualifierAttribute$1, MetadataUtil, PrototypeUtil, QualifierUtil } from "@eggjs/core-decorator";
|
|
7
|
+
import { IdenticalUtil, LifecycleUtil } from "@eggjs/tegg-lifecycle";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import fs from "node:fs/promises";
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
25
11
|
|
|
26
12
|
export * from "@eggjs/tegg-types/metadata"
|
|
27
13
|
|
|
14
|
+
//#region src/errors.ts
|
|
15
|
+
var TeggError = class extends FrameworkBaseError {
|
|
16
|
+
get module() {
|
|
17
|
+
return "TEGG";
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var EggPrototypeNotFound = class extends TeggError {
|
|
21
|
+
constructor(protoName, loadUnitId) {
|
|
22
|
+
const msg = loadUnitId ? `Object ${String(protoName)} not found in ${loadUnitId}` : `Object ${String(protoName)} not found`;
|
|
23
|
+
super(msg, ErrorCodes.EGG_PROTO_NOT_FOUND);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var MultiPrototypeFound = class extends TeggError {
|
|
27
|
+
constructor(name, qualifier, result) {
|
|
28
|
+
const msg = `multi proto found for name:${String(name)} and qualifiers ${JSON.stringify(qualifier)}${result ? `, result is ${result}` : ""}`;
|
|
29
|
+
super(msg, ErrorCodes.MULTI_PROTO_FOUND);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var IncompatibleProtoInject = class extends TeggError {
|
|
33
|
+
constructor(msg) {
|
|
34
|
+
super(msg, ErrorCodes.INCOMPATIBLE_PROTO_INJECT);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/factory/EggPrototypeFactory.ts
|
|
40
|
+
var EggPrototypeFactory = class EggPrototypeFactory {
|
|
41
|
+
static instance = new EggPrototypeFactory();
|
|
42
|
+
publicProtoMap = /* @__PURE__ */ new Map();
|
|
43
|
+
registerPrototype(proto, loadUnit) {
|
|
44
|
+
if (proto.accessLevel === AccessLevel.PUBLIC) MapUtil.getOrStore(this.publicProtoMap, proto.name, []).push(proto);
|
|
45
|
+
loadUnit.registerEggPrototype(proto);
|
|
46
|
+
}
|
|
47
|
+
deletePrototype(proto, loadUnit) {
|
|
48
|
+
if (proto.accessLevel === AccessLevel.PUBLIC) {
|
|
49
|
+
const protos = this.publicProtoMap.get(proto.name);
|
|
50
|
+
if (protos) {
|
|
51
|
+
const index = protos.indexOf(proto);
|
|
52
|
+
if (index !== -1) protos.splice(index, 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
loadUnit.deletePrototype(proto);
|
|
56
|
+
}
|
|
57
|
+
getPrototype(name, loadUnit, qualifiers) {
|
|
58
|
+
qualifiers = qualifiers || [];
|
|
59
|
+
const protos = this.doGetPrototype(name, qualifiers, loadUnit);
|
|
60
|
+
if (!protos.length) throw FrameworkErrorFormater.formatError(new EggPrototypeNotFound(name, loadUnit?.id));
|
|
61
|
+
if (protos.length === 1) return protos[0];
|
|
62
|
+
throw FrameworkErrorFormater.formatError(new MultiPrototypeFound(name, qualifiers));
|
|
63
|
+
}
|
|
64
|
+
doGetPrototype(name, qualifiers, loadUnit) {
|
|
65
|
+
if (loadUnit) {
|
|
66
|
+
const protos = loadUnit.getEggPrototype(name, qualifiers);
|
|
67
|
+
if (protos.length) return protos;
|
|
68
|
+
}
|
|
69
|
+
return this.publicProtoMap.get(name)?.filter((proto) => proto.verifyQualifiers(qualifiers)) || [];
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/model/ProtoDescriptor/AbstractProtoDescriptor.ts
|
|
75
|
+
var AbstractProtoDescriptor = class {
|
|
76
|
+
name;
|
|
77
|
+
accessLevel;
|
|
78
|
+
initType;
|
|
79
|
+
qualifiers;
|
|
80
|
+
injectObjects;
|
|
81
|
+
protoImplType;
|
|
82
|
+
defineModuleName;
|
|
83
|
+
defineUnitPath;
|
|
84
|
+
instanceModuleName;
|
|
85
|
+
instanceDefineUnitPath;
|
|
86
|
+
className;
|
|
87
|
+
properQualifiers;
|
|
88
|
+
type;
|
|
89
|
+
constructor(options) {
|
|
90
|
+
this.name = options.name;
|
|
91
|
+
this.accessLevel = options.accessLevel;
|
|
92
|
+
this.initType = options.initType;
|
|
93
|
+
this.qualifiers = options.qualifiers;
|
|
94
|
+
this.protoImplType = options.protoImplType;
|
|
95
|
+
this.injectObjects = options.injectObjects;
|
|
96
|
+
this.defineModuleName = options.defineModuleName;
|
|
97
|
+
this.defineUnitPath = options.defineUnitPath;
|
|
98
|
+
this.instanceModuleName = options.instanceModuleName;
|
|
99
|
+
this.instanceDefineUnitPath = options.instanceDefineUnitPath;
|
|
100
|
+
this.type = options.type;
|
|
101
|
+
this.properQualifiers = options.properQualifiers;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/model/ProtoDescriptor/ClassProtoDescriptor.ts
|
|
107
|
+
var ClassProtoDescriptor = class ClassProtoDescriptor extends AbstractProtoDescriptor {
|
|
108
|
+
clazz;
|
|
109
|
+
clazzName;
|
|
110
|
+
static isClassProtoDescriptor(descriptor) {
|
|
111
|
+
return descriptor.type === ProtoDescriptorType.CLASS;
|
|
112
|
+
}
|
|
113
|
+
constructor(options) {
|
|
114
|
+
super({
|
|
115
|
+
type: ProtoDescriptorType.CLASS,
|
|
116
|
+
...options
|
|
117
|
+
});
|
|
118
|
+
this.clazz = options.clazz;
|
|
119
|
+
this.className = this.clazz.name;
|
|
120
|
+
}
|
|
121
|
+
equal(protoDescriptor) {
|
|
122
|
+
if (!ClassProtoDescriptor.isClassProtoDescriptor(protoDescriptor)) return false;
|
|
123
|
+
return this.clazz === protoDescriptor.clazz && this.name === protoDescriptor.name && this.accessLevel === protoDescriptor.accessLevel && this.initType === protoDescriptor.initType && this.instanceModuleName === protoDescriptor.instanceModuleName && QualifierUtil.equalQualifiers(this.qualifiers, protoDescriptor.qualifiers);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/model/ProtoDescriptorHelper.ts
|
|
129
|
+
var ProtoDescriptorHelper = class ProtoDescriptorHelper {
|
|
130
|
+
static addDefaultQualifier(qualifiers, initType, loadUnitName) {
|
|
131
|
+
const defaultQualifiers = [{
|
|
132
|
+
attribute: InitTypeQualifierAttribute,
|
|
133
|
+
value: initType
|
|
134
|
+
}, {
|
|
135
|
+
attribute: LoadUnitNameQualifierAttribute,
|
|
136
|
+
value: loadUnitName
|
|
137
|
+
}];
|
|
138
|
+
const res = [...qualifiers];
|
|
139
|
+
for (const defaultQualifier of defaultQualifiers) if (!qualifiers.find((t) => t.attribute === defaultQualifier.attribute)) res.push(defaultQualifier);
|
|
140
|
+
return res;
|
|
141
|
+
}
|
|
142
|
+
static async createByMultiInstanceClazz(clazz, options) {
|
|
143
|
+
assert(PrototypeUtil.isEggMultiInstancePrototype(clazz), `clazz ${clazz.name} is not MultiInstancePrototype`);
|
|
144
|
+
const type = PrototypeUtil.getEggMultiInstancePrototypeType(clazz);
|
|
145
|
+
if (type === MultiInstanceType.DYNAMIC) return await ProtoDescriptorHelper.createByDynamicMultiInstanceClazz(clazz, options);
|
|
146
|
+
else if (type === MultiInstanceType.STATIC) {
|
|
147
|
+
if (options.defineModuleName === options.instanceModuleName) return ProtoDescriptorHelper.createByStaticMultiInstanceClazz(clazz, options);
|
|
148
|
+
}
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
static async createByDynamicMultiInstanceClazz(clazz, options) {
|
|
152
|
+
assert(PrototypeUtil.isEggMultiInstancePrototype(clazz), `clazz ${clazz.name} is not MultiInstancePrototype`);
|
|
153
|
+
const instanceProperty = await PrototypeUtil.getDynamicMultiInstanceProperty(clazz, {
|
|
154
|
+
moduleName: options.instanceModuleName,
|
|
155
|
+
unitPath: options.instanceDefineUnitPath
|
|
156
|
+
});
|
|
157
|
+
assert(instanceProperty, `not found PrototypeInfo for clazz ${clazz.name}`);
|
|
158
|
+
return ProtoDescriptorHelper.#createByMultiInstanceClazz(clazz, instanceProperty, options);
|
|
159
|
+
}
|
|
160
|
+
static createByStaticMultiInstanceClazz(clazz, options) {
|
|
161
|
+
assert(PrototypeUtil.isEggMultiInstancePrototype(clazz), `clazz ${clazz.name} is not MultiInstancePrototype`);
|
|
162
|
+
const instanceProperty = PrototypeUtil.getStaticMultiInstanceProperty(clazz);
|
|
163
|
+
assert(instanceProperty, `not found PrototypeInfo for clazz ${clazz.name}`);
|
|
164
|
+
return ProtoDescriptorHelper.#createByMultiInstanceClazz(clazz, instanceProperty, options);
|
|
165
|
+
}
|
|
166
|
+
static #createByMultiInstanceClazz(clazz, instanceProperty, options) {
|
|
167
|
+
const res = [];
|
|
168
|
+
for (const obj of instanceProperty.objects) {
|
|
169
|
+
let qualifiers = QualifierUtil.mergeQualifiers(QualifierUtil.getProtoQualifiers(clazz), obj.qualifiers);
|
|
170
|
+
qualifiers = ProtoDescriptorHelper.addDefaultQualifier(qualifiers, instanceProperty.initType, options.instanceModuleName);
|
|
171
|
+
const injectObjects = PrototypeUtil.getInjectObjects(clazz).map((t) => {
|
|
172
|
+
const qualifiers$1 = QualifierUtil.getProperQualifiers(clazz, t.refName);
|
|
173
|
+
const instanceQualifier = obj.properQualifiers?.[t.refName] ?? [];
|
|
174
|
+
return {
|
|
175
|
+
...t,
|
|
176
|
+
qualifiers: QualifierUtil.mergeQualifiers(qualifiers$1, instanceQualifier)
|
|
177
|
+
};
|
|
178
|
+
});
|
|
179
|
+
res.push(new ClassProtoDescriptor({
|
|
180
|
+
name: obj.name,
|
|
181
|
+
accessLevel: instanceProperty.accessLevel,
|
|
182
|
+
initType: instanceProperty.initType,
|
|
183
|
+
protoImplType: instanceProperty.protoImplType,
|
|
184
|
+
qualifiers,
|
|
185
|
+
injectObjects,
|
|
186
|
+
instanceModuleName: options.instanceModuleName,
|
|
187
|
+
instanceDefineUnitPath: options.instanceDefineUnitPath,
|
|
188
|
+
defineModuleName: options.defineModuleName,
|
|
189
|
+
defineUnitPath: options.defineUnitPath,
|
|
190
|
+
clazz,
|
|
191
|
+
properQualifiers: obj.properQualifiers || {}
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
return res;
|
|
195
|
+
}
|
|
196
|
+
static createByInstanceClazz(clazz, ctx) {
|
|
197
|
+
assert(PrototypeUtil.isEggPrototype(clazz), `clazz ${clazz.name} is not EggPrototype`);
|
|
198
|
+
assert(!PrototypeUtil.isEggMultiInstancePrototype(clazz), `clazz ${clazz.name} is not Prototype`);
|
|
199
|
+
const property = PrototypeUtil.getProperty(clazz);
|
|
200
|
+
assert(property, `not found PrototypeInfo for clazz ${clazz.name}`);
|
|
201
|
+
const protoQualifiers = ProtoDescriptorHelper.addDefaultQualifier(QualifierUtil.getProtoQualifiers(clazz), property.initType, ctx.moduleName);
|
|
202
|
+
const injectObjects = PrototypeUtil.getInjectObjects(clazz).map((t) => {
|
|
203
|
+
const qualifiers = QualifierUtil.getProperQualifiers(clazz, t.refName);
|
|
204
|
+
return {
|
|
205
|
+
...t,
|
|
206
|
+
qualifiers
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
return new ClassProtoDescriptor({
|
|
210
|
+
name: property.name,
|
|
211
|
+
protoImplType: property.protoImplType,
|
|
212
|
+
accessLevel: property.accessLevel,
|
|
213
|
+
initType: property.initType,
|
|
214
|
+
qualifiers: protoQualifiers,
|
|
215
|
+
injectObjects,
|
|
216
|
+
instanceDefineUnitPath: ctx.unitPath,
|
|
217
|
+
instanceModuleName: ctx.moduleName,
|
|
218
|
+
defineUnitPath: ctx.unitPath,
|
|
219
|
+
defineModuleName: ctx.moduleName,
|
|
220
|
+
clazz,
|
|
221
|
+
properQualifiers: {}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
static selectProto(proto, ctx) {
|
|
225
|
+
if (proto.name !== ctx.name) return false;
|
|
226
|
+
if (proto.accessLevel !== AccessLevel.PUBLIC && proto.instanceModuleName !== ctx.moduleName) return false;
|
|
227
|
+
if (!QualifierUtil.matchQualifiers(proto.qualifiers, ctx.qualifiers)) return false;
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/model/graph/ProtoNode.ts
|
|
234
|
+
var ProtoDependencyMeta = class {
|
|
235
|
+
injectObj;
|
|
236
|
+
constructor({ injectObj }) {
|
|
237
|
+
this.injectObj = injectObj;
|
|
238
|
+
}
|
|
239
|
+
equal(meta) {
|
|
240
|
+
return this.injectObj === meta.injectObj;
|
|
241
|
+
}
|
|
242
|
+
toString() {
|
|
243
|
+
return `inject ${String(this.injectObj)}`;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
var ProtoNode = class ProtoNode {
|
|
247
|
+
id;
|
|
248
|
+
proto;
|
|
249
|
+
constructor(proto) {
|
|
250
|
+
this.id = ProtoNode.createProtoId(proto);
|
|
251
|
+
this.proto = proto;
|
|
252
|
+
}
|
|
253
|
+
toString() {
|
|
254
|
+
return `${String(this.proto.name)}@${this.proto.instanceDefineUnitPath}`;
|
|
255
|
+
}
|
|
256
|
+
selectProto(ctx) {
|
|
257
|
+
return ProtoDescriptorHelper.selectProto(this.proto, ctx);
|
|
258
|
+
}
|
|
259
|
+
static createProtoId(proto) {
|
|
260
|
+
return [
|
|
261
|
+
proto.name,
|
|
262
|
+
proto.instanceModuleName,
|
|
263
|
+
proto.initType,
|
|
264
|
+
...proto.qualifiers.map((t) => String(t.attribute) + String(t.value))
|
|
265
|
+
].join("@");
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/model/graph/GlobalModuleNode.ts
|
|
271
|
+
var ModuleDependencyMeta = class {
|
|
272
|
+
obj;
|
|
273
|
+
injectObj;
|
|
274
|
+
constructor(obj, injectObj) {
|
|
275
|
+
this.obj = obj;
|
|
276
|
+
this.injectObj = injectObj;
|
|
277
|
+
}
|
|
278
|
+
equal(meta) {
|
|
279
|
+
return this.obj.equal(meta.obj) && this.injectObj === meta.injectObj;
|
|
280
|
+
}
|
|
281
|
+
toString() {
|
|
282
|
+
return `Object ${String(this.obj.name)} inject ${String(this.injectObj)}`;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
var GlobalModuleNode = class {
|
|
286
|
+
id;
|
|
287
|
+
name;
|
|
288
|
+
unitPath;
|
|
289
|
+
optional;
|
|
290
|
+
protos;
|
|
291
|
+
constructor(options) {
|
|
292
|
+
this.id = options.unitPath;
|
|
293
|
+
this.name = options.name;
|
|
294
|
+
this.unitPath = options.unitPath;
|
|
295
|
+
this.optional = options.optional;
|
|
296
|
+
this.protos = [];
|
|
297
|
+
}
|
|
298
|
+
addProto(proto) {
|
|
299
|
+
this.protos.push(new GraphNode(new ProtoNode(proto)));
|
|
300
|
+
}
|
|
301
|
+
toString() {
|
|
302
|
+
return `${this.name}@${this.unitPath}`;
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region src/model/graph/GlobalModuleNodeBuilder.ts
|
|
308
|
+
var GlobalModuleNodeBuilder = class GlobalModuleNodeBuilder {
|
|
309
|
+
name;
|
|
310
|
+
unitPath;
|
|
311
|
+
optional;
|
|
312
|
+
protos;
|
|
313
|
+
constructor(options) {
|
|
314
|
+
this.name = options.name;
|
|
315
|
+
this.unitPath = options.unitPath;
|
|
316
|
+
this.optional = options.optional;
|
|
317
|
+
this.protos = [];
|
|
318
|
+
}
|
|
319
|
+
addClazz(clazz) {
|
|
320
|
+
const proto = ProtoDescriptorHelper.createByInstanceClazz(clazz, {
|
|
321
|
+
moduleName: this.name,
|
|
322
|
+
unitPath: this.unitPath
|
|
323
|
+
});
|
|
324
|
+
this.protos.push(proto);
|
|
325
|
+
return this;
|
|
326
|
+
}
|
|
327
|
+
async addMultiInstanceClazz(clazz, defineModuleName, defineUnitPath) {
|
|
328
|
+
const protos = await ProtoDescriptorHelper.createByMultiInstanceClazz(clazz, {
|
|
329
|
+
defineModuleName,
|
|
330
|
+
defineUnitPath,
|
|
331
|
+
instanceModuleName: this.name,
|
|
332
|
+
instanceDefineUnitPath: this.unitPath
|
|
333
|
+
});
|
|
334
|
+
this.protos.push(...protos);
|
|
335
|
+
return this;
|
|
336
|
+
}
|
|
337
|
+
build() {
|
|
338
|
+
const node = new GlobalModuleNode({
|
|
339
|
+
name: this.name,
|
|
340
|
+
unitPath: this.unitPath,
|
|
341
|
+
optional: this.optional
|
|
342
|
+
});
|
|
343
|
+
for (const proto of this.protos) node.addProto(proto);
|
|
344
|
+
return node;
|
|
345
|
+
}
|
|
346
|
+
static create(unitPath, optional = false) {
|
|
347
|
+
const name = ModuleConfigUtil.readModuleNameSync(unitPath);
|
|
348
|
+
return new GlobalModuleNodeBuilder({
|
|
349
|
+
name,
|
|
350
|
+
unitPath,
|
|
351
|
+
optional
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/model/graph/GlobalGraph.ts
|
|
358
|
+
const debug$2 = debuglog("tegg/core/metadata/model/graph/GlobalGraph");
|
|
359
|
+
/**
|
|
360
|
+
* Sort all prototypes and modules in app.
|
|
361
|
+
* - 1. LoaderFactory.loadApp: get ModuleDescriptors
|
|
362
|
+
* - 2. GlobalGraph.create: create global graph instance
|
|
363
|
+
* - 3. graph.build:
|
|
364
|
+
* - check duplicated prototypes exits
|
|
365
|
+
* - check inject object exists (only in strict mode,
|
|
366
|
+
* can register proto in hooks now, in next major version,
|
|
367
|
+
* should use load to create dynamic ProtoDescriptor and delete
|
|
368
|
+
* strict false options
|
|
369
|
+
* )
|
|
370
|
+
* - 4. graph.sort: build moduleConfigList and moduleProtoDescriptorMap
|
|
371
|
+
*/
|
|
372
|
+
var GlobalGraph = class GlobalGraph {
|
|
373
|
+
/**
|
|
374
|
+
* Vertex: ModuleNode, collect prototypes in module
|
|
375
|
+
* Edge: ModuleDependencyMeta, prototype and it's inject object
|
|
376
|
+
* @private
|
|
377
|
+
*/
|
|
378
|
+
moduleGraph;
|
|
379
|
+
/**
|
|
380
|
+
* Vertex: ProtoNode, collect all prototypes in app
|
|
381
|
+
* Edge: ProtoDependencyMeta, inject object
|
|
382
|
+
* @private
|
|
383
|
+
*/
|
|
384
|
+
protoGraph;
|
|
385
|
+
/**
|
|
386
|
+
* The order of the moduleConfigList is the order in which they are instantiated
|
|
387
|
+
*/
|
|
388
|
+
moduleConfigList;
|
|
389
|
+
/**
|
|
390
|
+
* key: module name
|
|
391
|
+
* value: ProtoDescriptor in module, the order is the order in which they are instantiated
|
|
392
|
+
*/
|
|
393
|
+
moduleProtoDescriptorMap;
|
|
394
|
+
strict;
|
|
395
|
+
buildHooks;
|
|
396
|
+
/**
|
|
397
|
+
* The global instance used in ModuleLoadUnit
|
|
398
|
+
*/
|
|
399
|
+
static instance;
|
|
400
|
+
constructor(options) {
|
|
401
|
+
this.moduleGraph = new Graph();
|
|
402
|
+
this.protoGraph = new Graph();
|
|
403
|
+
this.strict = options?.strict ?? false;
|
|
404
|
+
this.moduleProtoDescriptorMap = /* @__PURE__ */ new Map();
|
|
405
|
+
this.buildHooks = [];
|
|
406
|
+
}
|
|
407
|
+
registerBuildHook(hook) {
|
|
408
|
+
this.buildHooks.push(hook);
|
|
409
|
+
}
|
|
410
|
+
addModuleNode(moduleNode) {
|
|
411
|
+
if (!this.moduleGraph.addVertex(new GraphNode(moduleNode))) throw new Error(`duplicate module: ${moduleNode}`);
|
|
412
|
+
for (const protoNode of moduleNode.protos) if (!this.protoGraph.addVertex(protoNode)) throw new Error(`duplicate proto: ${protoNode.val}`);
|
|
413
|
+
}
|
|
414
|
+
build() {
|
|
415
|
+
for (const moduleNode of this.moduleGraph.nodes.values()) for (const protoNode of moduleNode.val.protos) for (const injectObj of protoNode.val.proto.injectObjects) this.buildInjectEdge(moduleNode, protoNode, injectObj);
|
|
416
|
+
for (const buildHook of this.buildHooks) buildHook(this);
|
|
417
|
+
}
|
|
418
|
+
buildInjectEdge(moduleNode, protoNode, injectObj) {
|
|
419
|
+
const injectProto = this.findDependencyProtoNode(protoNode.val.proto, injectObj);
|
|
420
|
+
if (!injectProto) {
|
|
421
|
+
if (!this.strict) return;
|
|
422
|
+
throw FrameworkErrorFormater.formatError(new EggPrototypeNotFound(injectObj.objName, protoNode.val.proto.instanceModuleName));
|
|
423
|
+
}
|
|
424
|
+
this.addInject(moduleNode, protoNode, injectProto, injectObj.objName);
|
|
425
|
+
}
|
|
426
|
+
addInject(moduleNode, protoNode, injectNode, injectName) {
|
|
427
|
+
this.protoGraph.addEdge(protoNode, injectNode, new ProtoDependencyMeta({ injectObj: injectName }));
|
|
428
|
+
const injectModule = this.findModuleNode(injectNode.val.proto.instanceModuleName);
|
|
429
|
+
if (!injectModule) {
|
|
430
|
+
if (!this.strict) return;
|
|
431
|
+
throw new Error(`not found module ${injectNode.val.proto.instanceModuleName}`);
|
|
432
|
+
}
|
|
433
|
+
if (moduleNode.val.id !== injectModule.val.id) this.moduleGraph.addEdge(moduleNode, injectModule, new ModuleDependencyMeta(protoNode.val.proto, injectName));
|
|
434
|
+
}
|
|
435
|
+
findInjectProto(proto, injectObject) {
|
|
436
|
+
return this.protoGraph.findToNode(ProtoNode.createProtoId(proto), new ProtoDependencyMeta({ injectObj: injectObject.objName }))?.val.proto;
|
|
437
|
+
}
|
|
438
|
+
#findDependencyProtoWithDefaultQualifiers(proto, injectObject, qualifiers) {
|
|
439
|
+
const result = [];
|
|
440
|
+
for (const node of this.protoGraph.nodes.values()) if (node.val.selectProto({
|
|
441
|
+
name: injectObject.objName,
|
|
442
|
+
qualifiers: QualifierUtil.mergeQualifiers(injectObject.qualifiers, qualifiers),
|
|
443
|
+
moduleName: proto.instanceModuleName
|
|
444
|
+
})) result.push(node);
|
|
445
|
+
return result;
|
|
446
|
+
}
|
|
447
|
+
findDependencyProtoNode(proto, injectObject) {
|
|
448
|
+
const protos = this.#findDependencyProtoWithDefaultQualifiers(proto, injectObject, []);
|
|
449
|
+
if (protos.length === 0) return;
|
|
450
|
+
if (protos.length === 1) return protos[0];
|
|
451
|
+
const protoWithContext = this.#findDependencyProtoWithDefaultQualifiers(proto, injectObject, [{
|
|
452
|
+
attribute: InitTypeQualifierAttribute,
|
|
453
|
+
value: ObjectInitType.CONTEXT
|
|
454
|
+
}]);
|
|
455
|
+
if (protoWithContext.length === 1) return protoWithContext[0];
|
|
456
|
+
const protoWithSelfInitType = this.#findDependencyProtoWithDefaultQualifiers(proto, injectObject, [{
|
|
457
|
+
attribute: InitTypeQualifierAttribute,
|
|
458
|
+
value: proto.initType
|
|
459
|
+
}]);
|
|
460
|
+
if (protoWithSelfInitType.length === 1) return protoWithSelfInitType[0];
|
|
461
|
+
if (!injectObject.qualifiers.find((t) => t.attribute === LoadUnitNameQualifierAttribute)) return this.findDependencyProtoNode(proto, {
|
|
462
|
+
...injectObject,
|
|
463
|
+
qualifiers: QualifierUtil.mergeQualifiers(injectObject.qualifiers, [{
|
|
464
|
+
attribute: LoadUnitNameQualifierAttribute,
|
|
465
|
+
value: proto.instanceModuleName
|
|
466
|
+
}])
|
|
467
|
+
});
|
|
468
|
+
throw FrameworkErrorFormater.formatError(new MultiPrototypeFound(injectObject.objName, injectObject.qualifiers));
|
|
469
|
+
}
|
|
470
|
+
findModuleNode(moduleName) {
|
|
471
|
+
for (const node of this.moduleGraph.nodes.values()) if (node.val.name === moduleName) return node;
|
|
472
|
+
}
|
|
473
|
+
#sortModule() {
|
|
474
|
+
const loopPath = this.moduleGraph.loopPath();
|
|
475
|
+
if (loopPath) throw new Error("module has recursive deps: " + loopPath);
|
|
476
|
+
debug$2("sortModule, loopPath: %o", loopPath);
|
|
477
|
+
this.moduleConfigList = this.moduleGraph.sort().filter((t) => {
|
|
478
|
+
return t.val.optional !== true || t.fromNodeMap.size > 0;
|
|
479
|
+
}).map((t) => {
|
|
480
|
+
return {
|
|
481
|
+
name: t.val.name,
|
|
482
|
+
path: t.val.unitPath,
|
|
483
|
+
optional: t.val.optional
|
|
484
|
+
};
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
#sortClazz() {
|
|
488
|
+
const loopPath = this.protoGraph.loopPath();
|
|
489
|
+
if (loopPath) throw new Error("proto has recursive deps: " + loopPath);
|
|
490
|
+
debug$2("sortClazz, loopPath: %o", loopPath);
|
|
491
|
+
for (const proto of this.protoGraph.sort()) {
|
|
492
|
+
const instanceModuleName = proto.val.proto.instanceModuleName;
|
|
493
|
+
let moduleProtoList = this.moduleProtoDescriptorMap.get(instanceModuleName);
|
|
494
|
+
if (!moduleProtoList) {
|
|
495
|
+
moduleProtoList = [];
|
|
496
|
+
this.moduleProtoDescriptorMap.set(instanceModuleName, moduleProtoList);
|
|
497
|
+
}
|
|
498
|
+
moduleProtoList.push(proto.val.proto);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
sort() {
|
|
502
|
+
this.#sortModule();
|
|
503
|
+
this.#sortClazz();
|
|
504
|
+
}
|
|
505
|
+
static async create(moduleDescriptors, options) {
|
|
506
|
+
const graph = new GlobalGraph(options);
|
|
507
|
+
for (const moduleDescriptor of moduleDescriptors) {
|
|
508
|
+
const moduleNodeBuilder = new GlobalModuleNodeBuilder({
|
|
509
|
+
name: moduleDescriptor.name,
|
|
510
|
+
unitPath: moduleDescriptor.unitPath,
|
|
511
|
+
optional: moduleDescriptor.optional ?? false
|
|
512
|
+
});
|
|
513
|
+
for (const clazz of moduleDescriptor.clazzList) moduleNodeBuilder.addClazz(clazz);
|
|
514
|
+
for (const clazz of moduleDescriptor.multiInstanceClazzList) await moduleNodeBuilder.addMultiInstanceClazz(clazz, moduleDescriptor.name, moduleDescriptor.unitPath);
|
|
515
|
+
graph.addModuleNode(moduleNodeBuilder.build());
|
|
516
|
+
}
|
|
517
|
+
return graph;
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
//#endregion
|
|
522
|
+
//#region src/model/AppGraph.ts
|
|
523
|
+
function verifyQualifier(clazzQualifiers, qualifier) {
|
|
524
|
+
return clazzQualifiers.find((t) => t.attribute === qualifier.attribute)?.value === qualifier.value;
|
|
525
|
+
}
|
|
526
|
+
function verifyQualifiers(clazzQualifiers, qualifiers) {
|
|
527
|
+
for (const qualifier of qualifiers) if (!verifyQualifier(clazzQualifiers, qualifier)) return false;
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
var ClazzMap = class {
|
|
531
|
+
clazzMap;
|
|
532
|
+
graph;
|
|
533
|
+
constructor(graph) {
|
|
534
|
+
this.graph = graph;
|
|
535
|
+
}
|
|
536
|
+
async build() {
|
|
537
|
+
const graph = this.graph;
|
|
538
|
+
/**
|
|
539
|
+
* 1. iterate all module get all MultiInstanceClazz
|
|
540
|
+
* 2. iterate MultiInstanceClazz and all module get object meta
|
|
541
|
+
* 3. iterate object meta and build clazz map
|
|
542
|
+
*/
|
|
543
|
+
const clazzMap = {};
|
|
544
|
+
for (const ownerNode of graph.nodes.values()) for (const clazz of ownerNode.val.getClazzList()) {
|
|
545
|
+
const qualifiers = QualifierUtil.getProtoQualifiers(clazz);
|
|
546
|
+
if (PrototypeUtil.isEggMultiInstancePrototype(clazz)) for (const instanceNode of graph.nodes.values()) {
|
|
547
|
+
const property = await PrototypeUtil.getMultiInstanceProperty(clazz, {
|
|
548
|
+
unitPath: instanceNode.val.moduleConfig.path,
|
|
549
|
+
moduleName: instanceNode.val.moduleConfig.name
|
|
550
|
+
});
|
|
551
|
+
assert(property, `multi instance property not found for ${clazz.name}`);
|
|
552
|
+
for (const info of property.objects) {
|
|
553
|
+
const instanceQualifiers = [...qualifiers, ...info.qualifiers];
|
|
554
|
+
clazzMap[info.name] = clazzMap[info.name] || [];
|
|
555
|
+
clazzMap[info.name].push({
|
|
556
|
+
name: info.name,
|
|
557
|
+
accessLevel: await PrototypeUtil.getAccessLevel(clazz, {
|
|
558
|
+
unitPath: instanceNode.val.moduleConfig.path,
|
|
559
|
+
moduleName: instanceNode.val.moduleConfig.name
|
|
560
|
+
}),
|
|
561
|
+
qualifiers: instanceQualifiers,
|
|
562
|
+
properQualifiers: info.properQualifiers || {},
|
|
563
|
+
instanceModule: instanceNode,
|
|
564
|
+
ownerModule: ownerNode
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
const property = PrototypeUtil.getProperty(clazz);
|
|
570
|
+
assert(property, `property not found for ${clazz.name}`);
|
|
571
|
+
clazzMap[property.name] = clazzMap[property.name] || [];
|
|
572
|
+
clazzMap[property.name].push({
|
|
573
|
+
name: property.name,
|
|
574
|
+
accessLevel: await PrototypeUtil.getAccessLevel(clazz, {
|
|
575
|
+
unitPath: ownerNode.val.moduleConfig.path,
|
|
576
|
+
moduleName: ownerNode.val.moduleConfig.name
|
|
577
|
+
}),
|
|
578
|
+
qualifiers,
|
|
579
|
+
properQualifiers: {},
|
|
580
|
+
ownerModule: ownerNode,
|
|
581
|
+
instanceModule: ownerNode
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
this.clazzMap = clazzMap;
|
|
586
|
+
}
|
|
587
|
+
findDependencyModule(objName, properQualifiers, intoModule) {
|
|
588
|
+
const result = /* @__PURE__ */ new Set();
|
|
589
|
+
const objInfo = this.clazzMap[objName];
|
|
590
|
+
if (!objInfo) return [];
|
|
591
|
+
let mayObjs = objInfo.filter((obj) => {
|
|
592
|
+
if (obj.instanceModule !== intoModule && obj.accessLevel === AccessLevel.PRIVATE) return false;
|
|
593
|
+
return verifyQualifiers(obj.qualifiers, properQualifiers);
|
|
594
|
+
});
|
|
595
|
+
if (mayObjs.length > 1) {
|
|
596
|
+
const initTypeQualifiers = INIT_TYPE_TRY_ORDER.map((type) => ({
|
|
597
|
+
attribute: InitTypeQualifierAttribute,
|
|
598
|
+
value: type
|
|
599
|
+
}));
|
|
600
|
+
for (const initTypeQualifier of initTypeQualifiers) {
|
|
601
|
+
const mayInitTypeObjs = mayObjs.filter((obj) => {
|
|
602
|
+
return verifyQualifiers(obj.qualifiers, [...properQualifiers, initTypeQualifier]);
|
|
603
|
+
});
|
|
604
|
+
if (mayInitTypeObjs.length > 0) mayObjs = mayInitTypeObjs;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
if (mayObjs.length > 1) {
|
|
608
|
+
const moduleNameQualifiers = {
|
|
609
|
+
attribute: LoadUnitNameQualifierAttribute,
|
|
610
|
+
value: intoModule.val.name
|
|
611
|
+
};
|
|
612
|
+
const mayLoadUnitNameObjs = mayObjs.filter((obj) => {
|
|
613
|
+
return verifyQualifiers(obj.qualifiers, [...properQualifiers, moduleNameQualifiers]);
|
|
614
|
+
});
|
|
615
|
+
if (mayLoadUnitNameObjs.length > 0) mayObjs = mayLoadUnitNameObjs;
|
|
616
|
+
}
|
|
617
|
+
if (mayObjs.length > 1) {
|
|
618
|
+
const message = util.format("multi class found for %s@%o in module %j", objName, properQualifiers, mayObjs.map((t) => {
|
|
619
|
+
return t.instanceModule.val.moduleConfig.path;
|
|
620
|
+
}));
|
|
621
|
+
throw new Error(message);
|
|
622
|
+
}
|
|
623
|
+
for (const obj of mayObjs) result.add(obj.instanceModule);
|
|
624
|
+
return Array.from(result);
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
var ModuleNode = class {
|
|
628
|
+
id;
|
|
629
|
+
name;
|
|
630
|
+
moduleConfig;
|
|
631
|
+
clazzList;
|
|
632
|
+
constructor(moduleConfig) {
|
|
633
|
+
this.moduleConfig = moduleConfig;
|
|
634
|
+
this.id = moduleConfig.path;
|
|
635
|
+
this.name = ModuleConfigUtil.readModuleNameSync(moduleConfig.path);
|
|
636
|
+
this.clazzList = [];
|
|
637
|
+
}
|
|
638
|
+
async addClazz(clazz) {
|
|
639
|
+
if (!this.clazzList.includes(clazz)) this.clazzList.push(clazz);
|
|
640
|
+
if (!PrototypeUtil.isEggMultiInstancePrototype(clazz)) {
|
|
641
|
+
const initTypeQualifierAttributeValue = await PrototypeUtil.getInitType(clazz, {
|
|
642
|
+
unitPath: this.moduleConfig.path,
|
|
643
|
+
moduleName: this.moduleConfig.name
|
|
644
|
+
});
|
|
645
|
+
const defaultQualifier = [{
|
|
646
|
+
attribute: InitTypeQualifierAttribute,
|
|
647
|
+
value: initTypeQualifierAttributeValue
|
|
648
|
+
}, {
|
|
649
|
+
attribute: LoadUnitNameQualifierAttribute,
|
|
650
|
+
value: this.name
|
|
651
|
+
}];
|
|
652
|
+
for (const qualifier of defaultQualifier) QualifierUtil.addProtoQualifier(clazz, qualifier.attribute, qualifier.value);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
toString() {
|
|
656
|
+
return `${this.name}@${this.moduleConfig.path}`;
|
|
657
|
+
}
|
|
658
|
+
getClazzList() {
|
|
659
|
+
return this.clazzList;
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
var AppGraph = class {
|
|
663
|
+
graph;
|
|
664
|
+
clazzMap;
|
|
665
|
+
moduleConfigList;
|
|
666
|
+
constructor() {
|
|
667
|
+
this.graph = new Graph();
|
|
668
|
+
}
|
|
669
|
+
addNode(moduleNode) {
|
|
670
|
+
if (!this.graph.addVertex(new GraphNode(moduleNode))) throw new Error(`duplicate module: ${moduleNode}`);
|
|
671
|
+
}
|
|
672
|
+
getClazzList() {
|
|
673
|
+
const clazzSet = /* @__PURE__ */ new Set();
|
|
674
|
+
for (const node of this.graph.nodes.values()) for (const clazz of node.val.getClazzList()) clazzSet.add(clazz);
|
|
675
|
+
return Array.from(clazzSet);
|
|
676
|
+
}
|
|
677
|
+
async build() {
|
|
678
|
+
this.clazzMap = new ClazzMap(this.graph);
|
|
679
|
+
await this.clazzMap.build();
|
|
680
|
+
for (const node of this.graph.nodes.values()) for (const clazz of node.val.getClazzList()) {
|
|
681
|
+
const injectObjects = PrototypeUtil.getInjectObjects(clazz);
|
|
682
|
+
for (const injectObject of injectObjects) if (PrototypeUtil.isEggMultiInstancePrototype(clazz)) for (const instanceNode of this.graph.nodes.values()) {
|
|
683
|
+
const property = await PrototypeUtil.getMultiInstanceProperty(clazz, {
|
|
684
|
+
unitPath: instanceNode.val.moduleConfig.path,
|
|
685
|
+
moduleName: instanceNode.val.moduleConfig.name
|
|
686
|
+
});
|
|
687
|
+
for (const info of property?.objects || []) {
|
|
688
|
+
const properQualifiers = [...QualifierUtil.getProperQualifiers(clazz, injectObject.refName), ...info.properQualifiers?.[injectObject.refName] ?? []];
|
|
689
|
+
const dependencyModules = this.clazzMap.findDependencyModule(injectObject.objName, properQualifiers, node);
|
|
690
|
+
for (const moduleNode of dependencyModules) if (instanceNode !== moduleNode) this.graph.addEdge(instanceNode, moduleNode);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
const properQualifiers = [...QualifierUtil.getProperQualifiers(clazz, injectObject.refName)];
|
|
695
|
+
const dependencyModules = this.clazzMap.findDependencyModule(injectObject.objName, properQualifiers, node);
|
|
696
|
+
for (const moduleNode of dependencyModules) if (node !== moduleNode) this.graph.addEdge(node, moduleNode);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
sort() {
|
|
701
|
+
const loopPath = this.graph.loopPath();
|
|
702
|
+
if (loopPath) throw new Error("module has recursive deps: " + loopPath);
|
|
703
|
+
this.moduleConfigList = this.graph.sort().filter((t) => {
|
|
704
|
+
return t.val.moduleConfig.optional !== true || t.fromNodeMap.size > 0;
|
|
705
|
+
}).map((t) => t.val.moduleConfig);
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
|
|
709
|
+
//#endregion
|
|
710
|
+
//#region src/model/EggPrototype.ts
|
|
711
|
+
const EggPrototypeLifecycleUtil = new LifecycleUtil();
|
|
712
|
+
|
|
713
|
+
//#endregion
|
|
714
|
+
//#region src/model/LoadUnit.ts
|
|
715
|
+
const LoadUnitLifecycleUtil = new LifecycleUtil();
|
|
716
|
+
|
|
717
|
+
//#endregion
|
|
718
|
+
//#region src/model/ModuleDescriptor.ts
|
|
719
|
+
const DUMP_PATH = process.env.MODULE_DUMP_PATH;
|
|
720
|
+
var ModuleDescriptorDumper = class ModuleDescriptorDumper {
|
|
721
|
+
static stringifyDescriptor(moduleDescriptor) {
|
|
722
|
+
return `{"name": "${moduleDescriptor.name}","unitPath": "${moduleDescriptor.unitPath}",` + (typeof moduleDescriptor.optional !== "undefined" ? `"optional": ${moduleDescriptor.optional},` : "") + `"clazzList": [${moduleDescriptor.clazzList.map((t) => {
|
|
723
|
+
return ModuleDescriptorDumper.stringifyClazz(t, moduleDescriptor);
|
|
724
|
+
}).join(",")}],"multiInstanceClazzList": [${moduleDescriptor.multiInstanceClazzList.map((t) => {
|
|
725
|
+
return ModuleDescriptorDumper.stringifyClazz(t, moduleDescriptor);
|
|
726
|
+
}).join(",")}],"protos": [${moduleDescriptor.protos.map((t) => {
|
|
727
|
+
return JSON.stringify(t);
|
|
728
|
+
}).join(",")}]}`;
|
|
729
|
+
}
|
|
730
|
+
static stringifyClazz(clazz, moduleDescriptor) {
|
|
731
|
+
return `{"name": "${clazz.name}",` + (PrototypeUtil.getFilePath(clazz) ? `"filePath": "${path.relative(moduleDescriptor.unitPath, PrototypeUtil.getFilePath(clazz))}"` : "") + "}";
|
|
732
|
+
}
|
|
733
|
+
static dumpPath(desc, options) {
|
|
734
|
+
const dumpDir = DUMP_PATH ?? options?.dumpDir ?? desc.unitPath;
|
|
735
|
+
return path.join(dumpDir, ".egg", `${desc.name}_module_desc.json`);
|
|
736
|
+
}
|
|
737
|
+
static async dump(desc, options) {
|
|
738
|
+
const dumpPath = ModuleDescriptorDumper.dumpPath(desc, options);
|
|
739
|
+
await fs.mkdir(path.dirname(dumpPath), { recursive: true });
|
|
740
|
+
await fs.writeFile(dumpPath, ModuleDescriptorDumper.stringifyDescriptor(desc));
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
//#endregion
|
|
745
|
+
//#region src/factory/EggPrototypeCreatorFactory.ts
|
|
746
|
+
const debug$1 = debuglog("tegg/core/metadata/factory/EggPrototypeCreatorFactory");
|
|
747
|
+
var EggPrototypeCreatorFactory = class {
|
|
748
|
+
static creatorMap = /* @__PURE__ */ new Map();
|
|
749
|
+
static registerPrototypeCreator(type, creator) {
|
|
750
|
+
this.creatorMap.set(type, creator);
|
|
751
|
+
}
|
|
752
|
+
static getPrototypeCreator(type) {
|
|
753
|
+
return this.creatorMap.get(type);
|
|
754
|
+
}
|
|
755
|
+
static async createProto(clazz, loadUnit) {
|
|
756
|
+
let properties = [];
|
|
757
|
+
const initTypeQualifierAttributeValue = await PrototypeUtil.getInitType(clazz, {
|
|
758
|
+
unitPath: loadUnit.unitPath,
|
|
759
|
+
moduleName: loadUnit.name
|
|
760
|
+
});
|
|
761
|
+
const defaultQualifier = [{
|
|
762
|
+
attribute: InitTypeQualifierAttribute$1,
|
|
763
|
+
value: initTypeQualifierAttributeValue
|
|
764
|
+
}, {
|
|
765
|
+
attribute: LoadUnitNameQualifierAttribute$1,
|
|
766
|
+
value: loadUnit.name
|
|
767
|
+
}];
|
|
768
|
+
if (PrototypeUtil.isEggMultiInstancePrototype(clazz)) {
|
|
769
|
+
const multiInstanceProtoInfo = await PrototypeUtil.getMultiInstanceProperty(clazz, {
|
|
770
|
+
unitPath: loadUnit.unitPath,
|
|
771
|
+
moduleName: loadUnit.name
|
|
772
|
+
});
|
|
773
|
+
assert(multiInstanceProtoInfo, `multiInstanceProtoInfo is undefined, clazz: ${clazz.name}, unitPath: ${loadUnit.unitPath}, moduleName: ${loadUnit.name}`);
|
|
774
|
+
for (const obj of multiInstanceProtoInfo.objects) {
|
|
775
|
+
defaultQualifier.forEach((qualifier) => {
|
|
776
|
+
if (!obj.qualifiers.find((t) => t.attribute === qualifier.attribute)) obj.qualifiers.push(qualifier);
|
|
777
|
+
});
|
|
778
|
+
properties.push({
|
|
779
|
+
name: obj.name,
|
|
780
|
+
protoImplType: multiInstanceProtoInfo.protoImplType,
|
|
781
|
+
initType: multiInstanceProtoInfo.initType,
|
|
782
|
+
accessLevel: multiInstanceProtoInfo.accessLevel,
|
|
783
|
+
qualifiers: obj.qualifiers,
|
|
784
|
+
properQualifiers: obj.properQualifiers,
|
|
785
|
+
className: multiInstanceProtoInfo.className
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
} else {
|
|
789
|
+
const property = PrototypeUtil.getProperty(clazz);
|
|
790
|
+
if (!property.qualifiers) property.qualifiers = [];
|
|
791
|
+
defaultQualifier.forEach((qualifier) => {
|
|
792
|
+
if (!property.qualifiers.find((t) => t.attribute === qualifier.attribute)) property.qualifiers.push(qualifier);
|
|
793
|
+
});
|
|
794
|
+
properties = [property];
|
|
795
|
+
}
|
|
796
|
+
const protos = [];
|
|
797
|
+
for (const property of properties) {
|
|
798
|
+
const creator = this.getPrototypeCreator(property.protoImplType);
|
|
799
|
+
if (!creator) throw new Error(`not found proto creator for type: ${property.protoImplType}`);
|
|
800
|
+
const ctx = {
|
|
801
|
+
clazz,
|
|
802
|
+
loadUnit,
|
|
803
|
+
prototypeInfo: property
|
|
804
|
+
};
|
|
805
|
+
const proto = creator(ctx);
|
|
806
|
+
await EggPrototypeLifecycleUtil.objectPreCreate(ctx, proto);
|
|
807
|
+
if (proto.init) await proto.init(ctx);
|
|
808
|
+
await EggPrototypeLifecycleUtil.objectPostCreate(ctx, proto);
|
|
809
|
+
PrototypeUtil.setClazzProto(clazz, proto);
|
|
810
|
+
protos.push(proto);
|
|
811
|
+
}
|
|
812
|
+
if (debug$1.enabled && loadUnit.name === "egg-app") debug$1("createProto, get protos:%o, from clazz:%o, from loadUnit:%o:%o:%o", protos.map((t) => t.name), clazz.name, loadUnit.type, loadUnit.name, loadUnit.unitPath);
|
|
813
|
+
return protos;
|
|
814
|
+
}
|
|
815
|
+
static async createProtoByDescriptor(protoDescriptor, loadUnit) {
|
|
816
|
+
const creator = this.getPrototypeCreator(protoDescriptor.protoImplType);
|
|
817
|
+
if (!creator) throw new Error(`not found proto creator for type: ${protoDescriptor.protoImplType}`);
|
|
818
|
+
const ctx = {
|
|
819
|
+
clazz: protoDescriptor.clazz,
|
|
820
|
+
loadUnit,
|
|
821
|
+
prototypeInfo: protoDescriptor
|
|
822
|
+
};
|
|
823
|
+
const proto = creator(ctx);
|
|
824
|
+
await EggPrototypeLifecycleUtil.objectPreCreate(ctx, proto);
|
|
825
|
+
if (proto.init) await proto.init(ctx);
|
|
826
|
+
await EggPrototypeLifecycleUtil.objectPostCreate(ctx, proto);
|
|
827
|
+
PrototypeUtil.setClazzProto(protoDescriptor.clazz, proto);
|
|
828
|
+
return proto;
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
|
|
832
|
+
//#endregion
|
|
833
|
+
//#region src/factory/LoadUnitFactory.ts
|
|
834
|
+
var LoadUnitFactory = class LoadUnitFactory {
|
|
835
|
+
static loadUnitCreatorMap = /* @__PURE__ */ new Map();
|
|
836
|
+
static loadUnitMap = /* @__PURE__ */ new Map();
|
|
837
|
+
static loadUnitIdMap = /* @__PURE__ */ new Map();
|
|
838
|
+
static async getLoanUnit(ctx, type) {
|
|
839
|
+
const creator = LoadUnitFactory.loadUnitCreatorMap.get(type);
|
|
840
|
+
if (!creator) throw new Error(`not find creator for load unit type ${type}`);
|
|
841
|
+
return await creator(ctx);
|
|
842
|
+
}
|
|
843
|
+
static async createLoadUnit(unitPath, type, loader) {
|
|
844
|
+
if (LoadUnitFactory.loadUnitMap.has(unitPath)) return LoadUnitFactory.loadUnitMap.get(unitPath).loadUnit;
|
|
845
|
+
const ctx = {
|
|
846
|
+
unitPath,
|
|
847
|
+
loader
|
|
848
|
+
};
|
|
849
|
+
const loadUnit = await LoadUnitFactory.getLoanUnit(ctx, type);
|
|
850
|
+
await LoadUnitLifecycleUtil.objectPreCreate(ctx, loadUnit);
|
|
851
|
+
if (loadUnit.init) await loadUnit.init(ctx);
|
|
852
|
+
await LoadUnitLifecycleUtil.objectPostCreate(ctx, loadUnit);
|
|
853
|
+
LoadUnitFactory.loadUnitMap.set(unitPath, {
|
|
854
|
+
loadUnit,
|
|
855
|
+
ctx
|
|
856
|
+
});
|
|
857
|
+
LoadUnitFactory.loadUnitIdMap.set(loadUnit.id, loadUnit);
|
|
858
|
+
return loadUnit;
|
|
859
|
+
}
|
|
860
|
+
static async createPreloadLoadUnit(unitPath, type, loader) {
|
|
861
|
+
const ctx = {
|
|
862
|
+
unitPath,
|
|
863
|
+
loader
|
|
864
|
+
};
|
|
865
|
+
return await LoadUnitFactory.getLoanUnit(ctx, type);
|
|
866
|
+
}
|
|
867
|
+
static async destroyLoadUnit(loadUnit) {
|
|
868
|
+
const { ctx } = LoadUnitFactory.loadUnitMap.get(loadUnit.unitPath);
|
|
869
|
+
try {
|
|
870
|
+
await LoadUnitLifecycleUtil.objectPreDestroy(ctx, loadUnit);
|
|
871
|
+
if (loadUnit.destroy) await loadUnit.destroy(ctx);
|
|
872
|
+
} finally {
|
|
873
|
+
LoadUnitFactory.loadUnitMap.delete(loadUnit.unitPath);
|
|
874
|
+
LoadUnitFactory.loadUnitIdMap.delete(loadUnit.id);
|
|
875
|
+
LoadUnitLifecycleUtil.clearObjectLifecycle(loadUnit);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
static getLoadUnitById(id$1) {
|
|
879
|
+
return LoadUnitFactory.loadUnitIdMap.get(id$1);
|
|
880
|
+
}
|
|
881
|
+
static registerLoadUnitCreator(type, creator) {
|
|
882
|
+
LoadUnitFactory.loadUnitCreatorMap.set(type, creator);
|
|
883
|
+
}
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
//#endregion
|
|
887
|
+
//#region src/util/ClassUtil.ts
|
|
888
|
+
var ClassUtil = class {
|
|
889
|
+
static classDescription(clazz) {
|
|
890
|
+
const filePath = PrototypeUtil.getFilePath(clazz);
|
|
891
|
+
const name = this.className(clazz);
|
|
892
|
+
let desc = `class:${String(name)}`;
|
|
893
|
+
if (filePath) desc += `@${filePath}`;
|
|
894
|
+
return desc;
|
|
895
|
+
}
|
|
896
|
+
static className(clazz) {
|
|
897
|
+
return PrototypeUtil.getProperty(clazz)?.name || clazz.name;
|
|
898
|
+
}
|
|
899
|
+
};
|
|
900
|
+
|
|
901
|
+
//#endregion
|
|
902
|
+
//#region src/impl/EggPrototypeImpl.ts
|
|
903
|
+
var EggPrototypeImpl = class {
|
|
904
|
+
clazz;
|
|
905
|
+
qualifiers;
|
|
906
|
+
filepath;
|
|
907
|
+
id;
|
|
908
|
+
name;
|
|
909
|
+
initType;
|
|
910
|
+
accessLevel;
|
|
911
|
+
injectObjects;
|
|
912
|
+
injectType;
|
|
913
|
+
loadUnitId;
|
|
914
|
+
className;
|
|
915
|
+
multiInstanceConstructorIndex;
|
|
916
|
+
multiInstanceConstructorAttributes;
|
|
917
|
+
constructor(id$1, name, clazz, filepath, initType, accessLevel, injectObjectMap, loadUnitId, qualifiers, className, injectType, multiInstanceConstructorIndex, multiInstanceConstructorAttributes) {
|
|
918
|
+
this.id = id$1;
|
|
919
|
+
this.clazz = clazz;
|
|
920
|
+
this.name = name;
|
|
921
|
+
this.filepath = filepath;
|
|
922
|
+
this.initType = initType;
|
|
923
|
+
this.accessLevel = accessLevel;
|
|
924
|
+
this.injectObjects = injectObjectMap;
|
|
925
|
+
this.loadUnitId = loadUnitId;
|
|
926
|
+
this.qualifiers = qualifiers;
|
|
927
|
+
this.className = className;
|
|
928
|
+
this.injectType = injectType || InjectType.PROPERTY;
|
|
929
|
+
this.multiInstanceConstructorIndex = multiInstanceConstructorIndex;
|
|
930
|
+
this.multiInstanceConstructorAttributes = multiInstanceConstructorAttributes;
|
|
931
|
+
}
|
|
932
|
+
verifyQualifiers(qualifiers) {
|
|
933
|
+
for (const qualifier of qualifiers) if (!this.verifyQualifier(qualifier)) return false;
|
|
934
|
+
return true;
|
|
935
|
+
}
|
|
936
|
+
verifyQualifier(qualifier) {
|
|
937
|
+
return this.qualifiers.find((t) => t.attribute === qualifier.attribute)?.value === qualifier.value;
|
|
938
|
+
}
|
|
939
|
+
getQualifier(attribute) {
|
|
940
|
+
return this.qualifiers.find((t) => t.attribute === attribute)?.value;
|
|
941
|
+
}
|
|
942
|
+
constructEggObject(...args) {
|
|
943
|
+
return Reflect.construct(this.clazz, args);
|
|
944
|
+
}
|
|
945
|
+
getMetaData(metadataKey) {
|
|
946
|
+
return MetadataUtil.getMetaData(metadataKey, this.clazz);
|
|
947
|
+
}
|
|
948
|
+
};
|
|
949
|
+
|
|
950
|
+
//#endregion
|
|
951
|
+
//#region src/impl/EggPrototypeBuilder.ts
|
|
952
|
+
var EggPrototypeBuilder = class EggPrototypeBuilder {
|
|
953
|
+
clazz;
|
|
954
|
+
name;
|
|
955
|
+
initType;
|
|
956
|
+
accessLevel;
|
|
957
|
+
filepath;
|
|
958
|
+
injectType;
|
|
959
|
+
injectObjects = [];
|
|
960
|
+
loadUnit;
|
|
961
|
+
qualifiers = [];
|
|
962
|
+
properQualifiers = {};
|
|
963
|
+
className;
|
|
964
|
+
multiInstanceConstructorIndex;
|
|
965
|
+
multiInstanceConstructorAttributes;
|
|
966
|
+
static create(ctx) {
|
|
967
|
+
const { clazz, loadUnit } = ctx;
|
|
968
|
+
const filepath = PrototypeUtil.getFilePath(clazz);
|
|
969
|
+
assert(filepath, "not find filepath");
|
|
970
|
+
const builder = new EggPrototypeBuilder();
|
|
971
|
+
builder.clazz = clazz;
|
|
972
|
+
builder.name = ctx.prototypeInfo.name;
|
|
973
|
+
builder.className = ctx.prototypeInfo.className;
|
|
974
|
+
builder.initType = ctx.prototypeInfo.initType;
|
|
975
|
+
builder.accessLevel = ctx.prototypeInfo.accessLevel;
|
|
976
|
+
builder.filepath = filepath;
|
|
977
|
+
builder.injectType = PrototypeUtil.getInjectType(clazz);
|
|
978
|
+
builder.injectObjects = PrototypeUtil.getInjectObjects(clazz) || [];
|
|
979
|
+
builder.loadUnit = loadUnit;
|
|
980
|
+
builder.qualifiers = QualifierUtil.mergeQualifiers(QualifierUtil.getProtoQualifiers(clazz), ctx.prototypeInfo.qualifiers ?? []);
|
|
981
|
+
builder.properQualifiers = ctx.prototypeInfo.properQualifiers ?? {};
|
|
982
|
+
builder.multiInstanceConstructorIndex = PrototypeUtil.getMultiInstanceConstructorIndex(clazz);
|
|
983
|
+
builder.multiInstanceConstructorAttributes = PrototypeUtil.getMultiInstanceConstructorAttributes(clazz);
|
|
984
|
+
return builder.build();
|
|
985
|
+
}
|
|
986
|
+
tryFindDefaultPrototype(injectObject) {
|
|
987
|
+
const propertyQualifiers = QualifierUtil.getProperQualifiers(this.clazz, injectObject.refName);
|
|
988
|
+
const multiInstancePropertyQualifiers = this.properQualifiers[injectObject.refName] ?? [];
|
|
989
|
+
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, QualifierUtil.mergeQualifiers(propertyQualifiers, multiInstancePropertyQualifiers));
|
|
990
|
+
}
|
|
991
|
+
tryFindContextPrototype(injectObject) {
|
|
992
|
+
const propertyQualifiers = QualifierUtil.getProperQualifiers(this.clazz, injectObject.refName);
|
|
993
|
+
const multiInstancePropertyQualifiers = this.properQualifiers[injectObject.refName] ?? [];
|
|
994
|
+
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, QualifierUtil.mergeQualifiers(propertyQualifiers, multiInstancePropertyQualifiers, [{
|
|
995
|
+
attribute: InitTypeQualifierAttribute,
|
|
996
|
+
value: ObjectInitType.CONTEXT
|
|
997
|
+
}]));
|
|
998
|
+
}
|
|
999
|
+
tryFindSelfInitTypePrototype(injectObject) {
|
|
1000
|
+
const propertyQualifiers = QualifierUtil.getProperQualifiers(this.clazz, injectObject.refName);
|
|
1001
|
+
const multiInstancePropertyQualifiers = this.properQualifiers[injectObject.refName] ?? [];
|
|
1002
|
+
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, QualifierUtil.mergeQualifiers(propertyQualifiers, multiInstancePropertyQualifiers, [{
|
|
1003
|
+
attribute: InitTypeQualifierAttribute,
|
|
1004
|
+
value: this.initType
|
|
1005
|
+
}]));
|
|
1006
|
+
}
|
|
1007
|
+
findInjectObjectPrototype(injectObject) {
|
|
1008
|
+
const propertyQualifiers = QualifierUtil.getProperQualifiers(this.clazz, injectObject.refName);
|
|
1009
|
+
try {
|
|
1010
|
+
return this.tryFindDefaultPrototype(injectObject);
|
|
1011
|
+
} catch (e) {
|
|
1012
|
+
if (!(e instanceof MultiPrototypeFound && !propertyQualifiers.find((t) => t.attribute === InitTypeQualifierAttribute))) throw e;
|
|
1013
|
+
}
|
|
1014
|
+
try {
|
|
1015
|
+
return this.tryFindContextPrototype(injectObject);
|
|
1016
|
+
} catch (e) {
|
|
1017
|
+
if (!(e instanceof EggPrototypeNotFound)) throw e;
|
|
1018
|
+
}
|
|
1019
|
+
return this.tryFindSelfInitTypePrototype(injectObject);
|
|
1020
|
+
}
|
|
1021
|
+
build() {
|
|
1022
|
+
const injectObjectProtos = [];
|
|
1023
|
+
for (const injectObject of this.injectObjects) {
|
|
1024
|
+
const propertyQualifiers = QualifierUtil.getProperQualifiers(this.clazz, injectObject.refName);
|
|
1025
|
+
try {
|
|
1026
|
+
const proto = this.findInjectObjectPrototype(injectObject);
|
|
1027
|
+
let injectObjectProto;
|
|
1028
|
+
if (this.injectType === InjectType.PROPERTY) injectObjectProto = {
|
|
1029
|
+
refName: injectObject.refName,
|
|
1030
|
+
objName: injectObject.objName,
|
|
1031
|
+
qualifiers: propertyQualifiers,
|
|
1032
|
+
proto
|
|
1033
|
+
};
|
|
1034
|
+
else injectObjectProto = {
|
|
1035
|
+
refIndex: injectObject.refIndex,
|
|
1036
|
+
refName: injectObject.refName,
|
|
1037
|
+
objName: injectObject.objName,
|
|
1038
|
+
qualifiers: propertyQualifiers,
|
|
1039
|
+
proto
|
|
1040
|
+
};
|
|
1041
|
+
if (injectObject.optional) injectObject.optional = true;
|
|
1042
|
+
injectObjectProtos.push(injectObjectProto);
|
|
1043
|
+
} catch (e) {
|
|
1044
|
+
if (e instanceof EggPrototypeNotFound && injectObject.optional) continue;
|
|
1045
|
+
throw e;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
const id$1 = IdenticalUtil.createProtoId(this.loadUnit.id, this.name);
|
|
1049
|
+
return new EggPrototypeImpl(id$1, this.name, this.clazz, this.filepath, this.initType, this.accessLevel, injectObjectProtos, this.loadUnit.id, this.qualifiers, this.className, this.injectType, this.multiInstanceConstructorIndex, this.multiInstanceConstructorAttributes);
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
EggPrototypeCreatorFactory.registerPrototypeCreator(DEFAULT_PROTO_IMPL_TYPE, EggPrototypeBuilder.create);
|
|
1053
|
+
|
|
1054
|
+
//#endregion
|
|
1055
|
+
//#region src/impl/LoadUnitMultiInstanceProtoHook.ts
|
|
1056
|
+
var LoadUnitMultiInstanceProtoHook = class {
|
|
1057
|
+
static multiInstanceClazzSet = /* @__PURE__ */ new Set();
|
|
1058
|
+
static setAllClassList(clazzList) {
|
|
1059
|
+
for (const clazz of clazzList) if (PrototypeUtil.isEggMultiInstancePrototype(clazz)) this.multiInstanceClazzSet.add(clazz);
|
|
1060
|
+
}
|
|
1061
|
+
static clear() {
|
|
1062
|
+
this.multiInstanceClazzSet.clear();
|
|
1063
|
+
}
|
|
1064
|
+
async preCreate() {}
|
|
1065
|
+
};
|
|
1066
|
+
|
|
1067
|
+
//#endregion
|
|
1068
|
+
//#region src/impl/ModuleLoadUnit.ts
|
|
1069
|
+
const debug = debuglog("tegg/core/metadata/impl/ModuleLoadUnit");
|
|
1070
|
+
let id = 0;
|
|
1071
|
+
var ProtoNode$1 = class {
|
|
1072
|
+
clazz;
|
|
1073
|
+
name;
|
|
1074
|
+
id;
|
|
1075
|
+
qualifiers;
|
|
1076
|
+
initType;
|
|
1077
|
+
PrototypeUtil;
|
|
1078
|
+
constructor(clazz, objName, initType, qualifiers) {
|
|
1079
|
+
this.name = objName;
|
|
1080
|
+
this.id = "" + id++;
|
|
1081
|
+
this.clazz = clazz;
|
|
1082
|
+
this.qualifiers = qualifiers;
|
|
1083
|
+
this.initType = initType;
|
|
1084
|
+
}
|
|
1085
|
+
verifyQualifiers(qualifiers) {
|
|
1086
|
+
for (const qualifier of qualifiers) if (!this.verifyQualifier(qualifier)) return false;
|
|
1087
|
+
return true;
|
|
1088
|
+
}
|
|
1089
|
+
verifyQualifier(qualifier) {
|
|
1090
|
+
return this.qualifiers.find((t) => t.attribute === qualifier.attribute)?.value === qualifier.value;
|
|
1091
|
+
}
|
|
1092
|
+
toString() {
|
|
1093
|
+
return `${this.clazz.name}@${this.PrototypeUtil.getFilePath(this.clazz)}`;
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
var ModuleGraph = class {
|
|
1097
|
+
graph;
|
|
1098
|
+
clazzList;
|
|
1099
|
+
unitPath;
|
|
1100
|
+
name;
|
|
1101
|
+
constructor(clazzList, unitPath, name) {
|
|
1102
|
+
this.clazzList = clazzList;
|
|
1103
|
+
this.graph = new Graph();
|
|
1104
|
+
this.unitPath = unitPath;
|
|
1105
|
+
this.name = name;
|
|
1106
|
+
debug("ModuleGraph constructor on moduleName: %o, unitPath: %o, clazzList size: %o", this.name, this.unitPath, this.clazzList.length);
|
|
1107
|
+
}
|
|
1108
|
+
findInjectNode(objName, qualifiers, parentInitTye) {
|
|
1109
|
+
let nodes = Array.from(this.graph.nodes.values()).filter((t) => t.val.name === objName).filter((t) => t.val.verifyQualifiers(qualifiers));
|
|
1110
|
+
if (nodes.length === 0) return;
|
|
1111
|
+
if (nodes.length === 1) return nodes[0];
|
|
1112
|
+
const initTypeQualifier = {
|
|
1113
|
+
attribute: InitTypeQualifierAttribute,
|
|
1114
|
+
value: parentInitTye
|
|
1115
|
+
};
|
|
1116
|
+
nodes = nodes.filter((t) => t.val.verifyQualifiers([initTypeQualifier]));
|
|
1117
|
+
if (nodes.length === 1) return nodes[0];
|
|
1118
|
+
const temp = /* @__PURE__ */ new Map();
|
|
1119
|
+
for (const node of nodes) temp.set(node.val.clazz, node);
|
|
1120
|
+
nodes = Array.from(temp.values());
|
|
1121
|
+
if (nodes.length === 1) return nodes[0];
|
|
1122
|
+
const result = nodes.map((node) => node.val.toString());
|
|
1123
|
+
throw FrameworkErrorFormater.formatError(new MultiPrototypeFound(String(objName), qualifiers, JSON.stringify(result)));
|
|
1124
|
+
}
|
|
1125
|
+
async build() {
|
|
1126
|
+
const protoGraphNodes = [];
|
|
1127
|
+
for (const clazz of this.clazzList) if (PrototypeUtil.isEggMultiInstancePrototype(clazz)) {
|
|
1128
|
+
const properties = await PrototypeUtil.getMultiInstanceProperty(clazz, {
|
|
1129
|
+
unitPath: this.unitPath,
|
|
1130
|
+
moduleName: this.name
|
|
1131
|
+
});
|
|
1132
|
+
if (properties) {
|
|
1133
|
+
const qualifiers = QualifierUtil.getProtoQualifiers(clazz);
|
|
1134
|
+
for (const obj of properties.objects || []) {
|
|
1135
|
+
const instanceQualifiers = [...qualifiers, ...obj.qualifiers];
|
|
1136
|
+
protoGraphNodes.push(new GraphNode(new ProtoNode$1(clazz, obj.name, properties.initType, instanceQualifiers)));
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
} else {
|
|
1140
|
+
const qualifiers = QualifierUtil.getProtoQualifiers(clazz);
|
|
1141
|
+
const property = PrototypeUtil.getProperty(clazz);
|
|
1142
|
+
if (property) protoGraphNodes.push(new GraphNode(new ProtoNode$1(clazz, property.name, property.initType, qualifiers)));
|
|
1143
|
+
}
|
|
1144
|
+
for (const node of protoGraphNodes) if (!this.graph.addVertex(node)) throw new Error(`duplicate proto: ${node.val.id}`);
|
|
1145
|
+
for (const node of protoGraphNodes) if (PrototypeUtil.isEggMultiInstancePrototype(node.val.clazz)) {
|
|
1146
|
+
const property = await PrototypeUtil.getMultiInstanceProperty(node.val.clazz, {
|
|
1147
|
+
moduleName: this.name,
|
|
1148
|
+
unitPath: this.unitPath
|
|
1149
|
+
});
|
|
1150
|
+
for (const objectInfo of property?.objects || []) {
|
|
1151
|
+
const injectObjects = PrototypeUtil.getInjectObjects(node.val.clazz);
|
|
1152
|
+
for (const injectObject of injectObjects) {
|
|
1153
|
+
const qualifiers = [...QualifierUtil.getProperQualifiers(node.val.clazz, injectObject.refName), ...objectInfo.properQualifiers?.[injectObject.refName] ?? []];
|
|
1154
|
+
const injectNode = this.findInjectNode(injectObject.objName, qualifiers, node.val.initType);
|
|
1155
|
+
if (injectNode) this.graph.addEdge(node, injectNode);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
} else {
|
|
1159
|
+
const injectObjects = PrototypeUtil.getInjectObjects(node.val.clazz);
|
|
1160
|
+
for (const injectObject of injectObjects) {
|
|
1161
|
+
const qualifiers = QualifierUtil.getProperQualifiers(node.val.clazz, injectObject.refName);
|
|
1162
|
+
const injectNode = this.findInjectNode(injectObject.objName, qualifiers, node.val.initType);
|
|
1163
|
+
if (injectNode) this.graph.addEdge(node, injectNode);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
sort() {
|
|
1168
|
+
const loopPath = this.graph.loopPath();
|
|
1169
|
+
if (loopPath) throw new Error("proto has recursive deps: " + loopPath);
|
|
1170
|
+
const clazzSet = /* @__PURE__ */ new Set();
|
|
1171
|
+
for (const clazz of this.graph.sort()) clazzSet.add(clazz.val.clazz);
|
|
1172
|
+
this.clazzList = Array.from(clazzSet);
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
var ModuleLoadUnit = class ModuleLoadUnit {
|
|
1176
|
+
protoMap = /* @__PURE__ */ new Map();
|
|
1177
|
+
protos;
|
|
1178
|
+
clazzList;
|
|
1179
|
+
id;
|
|
1180
|
+
name;
|
|
1181
|
+
unitPath;
|
|
1182
|
+
type = EggLoadUnitType.MODULE;
|
|
1183
|
+
get globalGraph() {
|
|
1184
|
+
return GlobalGraph.instance;
|
|
1185
|
+
}
|
|
1186
|
+
constructor(name, unitPath) {
|
|
1187
|
+
this.id = IdenticalUtil.createLoadUnitId(name);
|
|
1188
|
+
this.name = name;
|
|
1189
|
+
this.unitPath = unitPath;
|
|
1190
|
+
debug("ModuleLoadUnit constructor on moduleName: %o, unitPath: %o, id: %o", this.name, this.unitPath, this.id);
|
|
1191
|
+
}
|
|
1192
|
+
doLoadClazz() {
|
|
1193
|
+
const protos = this.globalGraph.moduleProtoDescriptorMap.get(this.name);
|
|
1194
|
+
if (protos) {
|
|
1195
|
+
this.protos = protos.filter((t) => ClassProtoDescriptor.isClassProtoDescriptor(t));
|
|
1196
|
+
this.clazzList = this.protos.map((t) => t.clazz);
|
|
1197
|
+
} else {
|
|
1198
|
+
this.protos = [];
|
|
1199
|
+
this.clazzList = [];
|
|
1200
|
+
}
|
|
1201
|
+
debug("doLoadClazz on moduleName: %o, protos size: %o, clazzList size: %o", this.name, this.protos.length, this.clazzList.length);
|
|
1202
|
+
}
|
|
1203
|
+
loadClazz() {
|
|
1204
|
+
if (!this.clazzList) this.doLoadClazz();
|
|
1205
|
+
}
|
|
1206
|
+
async preLoad() {
|
|
1207
|
+
this.loadClazz();
|
|
1208
|
+
for (const protoClass of this.clazzList) {
|
|
1209
|
+
const fnName = LifecycleUtil.getStaticLifecycleHook("preLoad", protoClass);
|
|
1210
|
+
if (fnName) {
|
|
1211
|
+
const lifecycleHook = Reflect.get(protoClass, fnName);
|
|
1212
|
+
if (typeof lifecycleHook === "function") await lifecycleHook();
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
async init() {
|
|
1217
|
+
this.loadClazz();
|
|
1218
|
+
for (const protoDescriptor of this.protos) {
|
|
1219
|
+
const proto = await EggPrototypeCreatorFactory.createProtoByDescriptor(protoDescriptor, this);
|
|
1220
|
+
EggPrototypeFactory.instance.registerPrototype(proto, this);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
containPrototype(proto) {
|
|
1224
|
+
return !!this.protoMap.get(proto.name)?.find((t) => t === proto);
|
|
1225
|
+
}
|
|
1226
|
+
getEggPrototype(name, qualifiers) {
|
|
1227
|
+
return this.protoMap.get(name)?.filter((proto) => proto.verifyQualifiers(qualifiers)) || [];
|
|
1228
|
+
}
|
|
1229
|
+
registerEggPrototype(proto) {
|
|
1230
|
+
MapUtil.getOrStore(this.protoMap, proto.name, []).push(proto);
|
|
1231
|
+
}
|
|
1232
|
+
deletePrototype(proto) {
|
|
1233
|
+
const protos = this.protoMap.get(proto.name);
|
|
1234
|
+
if (protos) {
|
|
1235
|
+
const index = protos.indexOf(proto);
|
|
1236
|
+
if (index !== -1) protos.splice(index, 1);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
async destroy() {
|
|
1240
|
+
for (const namedProtoMap of this.protoMap.values()) for (const proto of namedProtoMap.slice()) EggPrototypeFactory.instance.deletePrototype(proto, this);
|
|
1241
|
+
this.protoMap.clear();
|
|
1242
|
+
}
|
|
1243
|
+
iterateEggPrototype() {
|
|
1244
|
+
return Array.from(this.protoMap.values()).reduce((p, c) => {
|
|
1245
|
+
p = p.concat(c);
|
|
1246
|
+
return p;
|
|
1247
|
+
}, []).values();
|
|
1248
|
+
}
|
|
1249
|
+
static createModule(ctx) {
|
|
1250
|
+
const pkgPath = path.join(ctx.unitPath, "package.json");
|
|
1251
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
1252
|
+
assert(pkg.eggModule, `module config not found in package ${pkgPath}`);
|
|
1253
|
+
const { name } = pkg.eggModule;
|
|
1254
|
+
return new ModuleLoadUnit(name, ctx.unitPath);
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
LoadUnitFactory.registerLoadUnitCreator(EggLoadUnitType.MODULE, ModuleLoadUnit.createModule);
|
|
1258
|
+
|
|
1259
|
+
//#endregion
|
|
28
1260
|
export { AbstractProtoDescriptor, AppGraph, ClassProtoDescriptor, ClassUtil, ClazzMap, EggPrototypeBuilder, EggPrototypeCreatorFactory, EggPrototypeFactory, EggPrototypeImpl, EggPrototypeLifecycleUtil, EggPrototypeNotFound, GlobalGraph, GlobalModuleNode, GlobalModuleNodeBuilder, IncompatibleProtoInject, LoadUnitFactory, LoadUnitLifecycleUtil, LoadUnitMultiInstanceProtoHook, ModuleDependencyMeta, ModuleDescriptorDumper, ModuleGraph, ModuleLoadUnit, ModuleNode, MultiPrototypeFound, ProtoDependencyMeta, ProtoDescriptorHelper, ProtoNode, TeggError };
|