@adaas/a-concept 0.3.6 → 0.3.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/README.md +116 -78
- package/benchmarks/feature-chaining.bench.ts +465 -0
- package/benchmarks/feature-lifecycle.bench.ts +245 -0
- package/benchmarks/feature-optimize.bench.ts +205 -0
- package/benchmarks/feature-profiling.bench.ts +415 -0
- package/benchmarks/feature-template.bench.ts +211 -0
- package/benchmarks/helpers.ts +97 -0
- package/benchmarks/run-all.ts +58 -0
- package/benchmarks/scope-resolve.bench.ts +245 -0
- package/benchmarks/step-manager.bench.ts +146 -0
- package/dist/browser/index.d.mts +72 -3
- package/dist/browser/index.mjs +2 -2
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/index.cjs +244 -87
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.mts +72 -3
- package/dist/node/index.d.ts +72 -3
- package/dist/node/index.mjs +244 -87
- package/dist/node/index.mjs.map +1 -1
- package/package.json +11 -1
- package/src/lib/A-Context/A-Context.class.ts +155 -60
- package/src/lib/A-Entity/A-Entity.class.ts +3 -3
- package/src/lib/A-Feature/A-Feature.class.ts +46 -41
- package/src/lib/A-Feature/A-Feature.types.ts +6 -10
- package/src/lib/A-Meta/A-Meta.class.ts +18 -3
- package/src/lib/A-Scope/A-Scope.class.ts +98 -5
- package/tests/A-Feature.test.ts +101 -0
- package/tsconfig.json +1 -0
package/dist/node/index.mjs
CHANGED
|
@@ -1117,13 +1117,13 @@ var A_Entity = class {
|
|
|
1117
1117
|
* @param lifecycleMethod
|
|
1118
1118
|
* @param args
|
|
1119
1119
|
*/
|
|
1120
|
-
|
|
1120
|
+
call(feature, scope) {
|
|
1121
1121
|
const newFeature = new A_Feature({
|
|
1122
1122
|
name: feature,
|
|
1123
1123
|
component: this,
|
|
1124
1124
|
scope
|
|
1125
1125
|
});
|
|
1126
|
-
return
|
|
1126
|
+
return newFeature.process(scope);
|
|
1127
1127
|
}
|
|
1128
1128
|
// ====================================================================
|
|
1129
1129
|
// ================== Entity Base Methods =============================
|
|
@@ -1320,20 +1320,17 @@ var A_Meta = class _A_Meta {
|
|
|
1320
1320
|
size() {
|
|
1321
1321
|
return this.meta.size;
|
|
1322
1322
|
}
|
|
1323
|
-
/**
|
|
1324
|
-
* This method is needed to convert the key to a regular expression and cover cases like:
|
|
1325
|
-
*
|
|
1326
|
-
* simple * e.g. "a*" instead of "a.*"
|
|
1327
|
-
*
|
|
1328
|
-
* simple ? e.g. "a?" instead of "a."
|
|
1329
|
-
*
|
|
1330
|
-
* etc.
|
|
1331
|
-
*
|
|
1332
|
-
* @param key
|
|
1333
|
-
* @returns
|
|
1334
|
-
*/
|
|
1335
1323
|
convertToRegExp(key) {
|
|
1336
|
-
|
|
1324
|
+
if (key instanceof RegExp) return key;
|
|
1325
|
+
if (!this._regExpCache) {
|
|
1326
|
+
this._regExpCache = /* @__PURE__ */ new Map();
|
|
1327
|
+
}
|
|
1328
|
+
let cached = this._regExpCache.get(key);
|
|
1329
|
+
if (!cached) {
|
|
1330
|
+
cached = new RegExp(key);
|
|
1331
|
+
this._regExpCache.set(key, cached);
|
|
1332
|
+
}
|
|
1333
|
+
return cached;
|
|
1337
1334
|
}
|
|
1338
1335
|
/**
|
|
1339
1336
|
* Method to find values in the map by name.
|
|
@@ -3327,7 +3324,7 @@ var A_Feature = class _A_Feature {
|
|
|
3327
3324
|
if (!params || typeof params !== "object") {
|
|
3328
3325
|
throw new A_FeatureError(
|
|
3329
3326
|
A_FeatureError.FeatureInitializationError,
|
|
3330
|
-
`Invalid A-Feature initialization parameters of type: ${typeof params} with value: ${JSON.stringify(params)
|
|
3327
|
+
`Invalid A-Feature initialization parameters of type: ${typeof params} with value: ${JSON.stringify(params)?.slice(0, 100)}...`
|
|
3331
3328
|
);
|
|
3332
3329
|
}
|
|
3333
3330
|
}
|
|
@@ -3346,7 +3343,7 @@ var A_Feature = class _A_Feature {
|
|
|
3346
3343
|
default:
|
|
3347
3344
|
throw new A_FeatureError(
|
|
3348
3345
|
A_FeatureError.FeatureInitializationError,
|
|
3349
|
-
`Invalid A-Feature initialization parameters of type: ${typeof params} with value: ${JSON.stringify(params)
|
|
3346
|
+
`Invalid A-Feature initialization parameters of type: ${typeof params} with value: ${JSON.stringify(params)?.slice(0, 100)}...`
|
|
3350
3347
|
);
|
|
3351
3348
|
}
|
|
3352
3349
|
}
|
|
@@ -3359,13 +3356,13 @@ var A_Feature = class _A_Feature {
|
|
|
3359
3356
|
if (!params.template || !Array.isArray(params.template)) {
|
|
3360
3357
|
throw new A_FeatureError(
|
|
3361
3358
|
A_FeatureError.FeatureInitializationError,
|
|
3362
|
-
`Invalid A-Feature template provided of type: ${typeof params.template} with value: ${JSON.stringify(params.template)
|
|
3359
|
+
`Invalid A-Feature template provided of type: ${typeof params.template} with value: ${JSON.stringify(params.template)?.slice(0, 100)}...`
|
|
3363
3360
|
);
|
|
3364
3361
|
}
|
|
3365
3362
|
if (!params.component && (!params.scope || !(params.scope instanceof A_Scope))) {
|
|
3366
3363
|
throw new A_FeatureError(
|
|
3367
3364
|
A_FeatureError.FeatureInitializationError,
|
|
3368
|
-
`Invalid A-Feature scope provided of type: ${typeof params.scope} with value: ${JSON.stringify(params.scope)
|
|
3365
|
+
`Invalid A-Feature scope provided of type: ${typeof params.scope} with value: ${JSON.stringify(params.scope)?.slice(0, 100)}...`
|
|
3369
3366
|
);
|
|
3370
3367
|
}
|
|
3371
3368
|
this._name = params.name;
|
|
@@ -3397,7 +3394,7 @@ var A_Feature = class _A_Feature {
|
|
|
3397
3394
|
if (!params.component || !A_TypeGuards.isAllowedForFeatureDefinition(params.component)) {
|
|
3398
3395
|
throw new A_FeatureError(
|
|
3399
3396
|
A_FeatureError.FeatureInitializationError,
|
|
3400
|
-
`Invalid A-Feature component provided of type: ${typeof params.component} with value: ${JSON.stringify(params.component)
|
|
3397
|
+
`Invalid A-Feature component provided of type: ${typeof params.component} with value: ${JSON.stringify(params.component)?.slice(0, 100)}...`
|
|
3401
3398
|
);
|
|
3402
3399
|
}
|
|
3403
3400
|
this._name = params.name;
|
|
@@ -3447,41 +3444,42 @@ var A_Feature = class _A_Feature {
|
|
|
3447
3444
|
* Process stages one by one, ensuring each stage completes before starting the next
|
|
3448
3445
|
*/
|
|
3449
3446
|
processStagesSequentially(stages, scope, index) {
|
|
3450
|
-
|
|
3451
|
-
if (this.state === "INTERRUPTED" /* INTERRUPTED */)
|
|
3452
|
-
return;
|
|
3453
|
-
}
|
|
3454
|
-
if (index >= stages.length) {
|
|
3455
|
-
this.completed();
|
|
3456
|
-
return;
|
|
3457
|
-
}
|
|
3447
|
+
while (index < stages.length) {
|
|
3448
|
+
if (this.state === "INTERRUPTED" /* INTERRUPTED */) return;
|
|
3458
3449
|
const stage = stages[index];
|
|
3459
|
-
|
|
3450
|
+
let result;
|
|
3451
|
+
try {
|
|
3452
|
+
result = stage.process(scope);
|
|
3453
|
+
} catch (error) {
|
|
3454
|
+
throw this.createStageError(error, stage);
|
|
3455
|
+
}
|
|
3460
3456
|
if (A_TypeGuards.isPromiseInstance(result)) {
|
|
3461
3457
|
return result.then(() => {
|
|
3462
|
-
if (this.state === "INTERRUPTED" /* INTERRUPTED */)
|
|
3463
|
-
return;
|
|
3464
|
-
}
|
|
3458
|
+
if (this.state === "INTERRUPTED" /* INTERRUPTED */) return;
|
|
3465
3459
|
return this.processStagesSequentially(stages, scope, index + 1);
|
|
3466
3460
|
}).catch((error) => {
|
|
3467
|
-
throw this.
|
|
3468
|
-
title: A_FeatureError.FeatureProcessingError,
|
|
3469
|
-
description: `An error occurred while processing the A-Feature: ${this.name}. Failed at stage: ${stage.name}.`,
|
|
3470
|
-
stage,
|
|
3471
|
-
originalError: error
|
|
3472
|
-
}));
|
|
3461
|
+
throw this.createStageError(error, stage);
|
|
3473
3462
|
});
|
|
3474
|
-
} else {
|
|
3475
|
-
return this.processStagesSequentially(stages, scope, index + 1);
|
|
3476
3463
|
}
|
|
3477
|
-
|
|
3478
|
-
throw this.failed(new A_FeatureError({
|
|
3479
|
-
title: A_FeatureError.FeatureProcessingError,
|
|
3480
|
-
description: `An error occurred while processing the A-Feature: ${this.name}. Failed at stage: ${this.stage?.name || "N/A"}.`,
|
|
3481
|
-
stage: this.stage,
|
|
3482
|
-
originalError: error
|
|
3483
|
-
}));
|
|
3464
|
+
index++;
|
|
3484
3465
|
}
|
|
3466
|
+
if (this.state !== "INTERRUPTED" /* INTERRUPTED */) {
|
|
3467
|
+
this.completed();
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
createStageError(error, stage) {
|
|
3471
|
+
this.failed(new A_FeatureError({
|
|
3472
|
+
title: A_FeatureError.FeatureProcessingError,
|
|
3473
|
+
description: `An error occurred while processing the A-Feature: ${this.name}. Failed at stage: ${stage.name}.`,
|
|
3474
|
+
stage,
|
|
3475
|
+
originalError: error
|
|
3476
|
+
}));
|
|
3477
|
+
return new A_FeatureError({
|
|
3478
|
+
title: A_FeatureError.FeatureProcessingError,
|
|
3479
|
+
description: `An error occurred while processing the A-Feature: ${this.name}. Failed at stage: ${stage.name}.`,
|
|
3480
|
+
stage,
|
|
3481
|
+
originalError: error
|
|
3482
|
+
});
|
|
3485
3483
|
}
|
|
3486
3484
|
/**
|
|
3487
3485
|
* This method moves the feature to the next stage
|
|
@@ -3682,8 +3680,13 @@ var A_ComponentMeta = class extends A_Meta {
|
|
|
3682
3680
|
};
|
|
3683
3681
|
|
|
3684
3682
|
// src/lib/A-Scope/A-Scope.class.ts
|
|
3685
|
-
var
|
|
3683
|
+
var _A_Scope = class _A_Scope {
|
|
3686
3684
|
constructor(param1, param2) {
|
|
3685
|
+
/**
|
|
3686
|
+
* Unique numeric ID for this scope instance. Used as a cache key discriminator
|
|
3687
|
+
* to prevent collisions between scopes with the same name or version.
|
|
3688
|
+
*/
|
|
3689
|
+
this.uid = _A_Scope._nextUid++;
|
|
3687
3690
|
/**
|
|
3688
3691
|
* Internal meta storage using A_Meta for type-safe key-value operations.
|
|
3689
3692
|
* This stores all the scope's runtime data that can be accessed and modified
|
|
@@ -3691,6 +3694,23 @@ var A_Scope = class {
|
|
|
3691
3694
|
*/
|
|
3692
3695
|
this._meta = new A_Meta();
|
|
3693
3696
|
// ===========================================================================
|
|
3697
|
+
// --------------------Cache & Versioning--------------------------------------
|
|
3698
|
+
// ===========================================================================
|
|
3699
|
+
/**
|
|
3700
|
+
* Monotonically increasing version counter. Incremented on every mutation
|
|
3701
|
+
* (register, deregister, import, deimport, inherit, destroy) so that
|
|
3702
|
+
* external caches (e.g. A_Context feature-extension cache) can detect
|
|
3703
|
+
* staleness cheaply via numeric comparison.
|
|
3704
|
+
*/
|
|
3705
|
+
this._version = 0;
|
|
3706
|
+
/**
|
|
3707
|
+
* Cache for resolveConstructor results (both positive and negative).
|
|
3708
|
+
* Key = constructor name (string) or constructor reference toString.
|
|
3709
|
+
* Value = resolved constructor or `null` for negative results.
|
|
3710
|
+
* Invalidated by incrementing _version (cache is cleared on bump).
|
|
3711
|
+
*/
|
|
3712
|
+
this._resolveConstructorCache = /* @__PURE__ */ new Map();
|
|
3713
|
+
// ===========================================================================
|
|
3694
3714
|
// --------------------ALLowed Constructors--------------------------------
|
|
3695
3715
|
// ===========================================================================
|
|
3696
3716
|
/**
|
|
@@ -3775,6 +3795,13 @@ var A_Scope = class {
|
|
|
3775
3795
|
get allowedErrors() {
|
|
3776
3796
|
return this._allowedErrors;
|
|
3777
3797
|
}
|
|
3798
|
+
/**
|
|
3799
|
+
* Returns the current version of the scope. Each mutation increments the version,
|
|
3800
|
+
* allowing external caches to detect staleness via numeric comparison.
|
|
3801
|
+
*/
|
|
3802
|
+
get version() {
|
|
3803
|
+
return this._version;
|
|
3804
|
+
}
|
|
3778
3805
|
// ===========================================================================
|
|
3779
3806
|
// --------------------Readonly Registered Properties--------------------------
|
|
3780
3807
|
// ===========================================================================
|
|
@@ -3826,6 +3853,14 @@ var A_Scope = class {
|
|
|
3826
3853
|
get parent() {
|
|
3827
3854
|
return this._parent;
|
|
3828
3855
|
}
|
|
3856
|
+
/**
|
|
3857
|
+
* Increments the scope version and clears internal caches.
|
|
3858
|
+
* Must be called on every scope mutation (register, deregister, import, deimport, inherit, destroy).
|
|
3859
|
+
*/
|
|
3860
|
+
bumpVersion() {
|
|
3861
|
+
this._version++;
|
|
3862
|
+
this._resolveConstructorCache.clear();
|
|
3863
|
+
}
|
|
3829
3864
|
/**
|
|
3830
3865
|
* Generator to iterate through all parent scopes
|
|
3831
3866
|
*/
|
|
@@ -3959,6 +3994,7 @@ var A_Scope = class {
|
|
|
3959
3994
|
if (this.issuer()) {
|
|
3960
3995
|
A_Context.deallocate(this);
|
|
3961
3996
|
}
|
|
3997
|
+
this.bumpVersion();
|
|
3962
3998
|
}
|
|
3963
3999
|
/**
|
|
3964
4000
|
* Retrieves a value from the scope's meta.
|
|
@@ -4034,6 +4070,7 @@ var A_Scope = class {
|
|
|
4034
4070
|
`Circular inheritance detected: ${[...circularCheck, parent.name].join(" -> ")}`
|
|
4035
4071
|
);
|
|
4036
4072
|
this._parent = parent;
|
|
4073
|
+
this.bumpVersion();
|
|
4037
4074
|
return this;
|
|
4038
4075
|
}
|
|
4039
4076
|
/**
|
|
@@ -4055,6 +4092,7 @@ var A_Scope = class {
|
|
|
4055
4092
|
if (this._imports.has(scope))
|
|
4056
4093
|
return;
|
|
4057
4094
|
this._imports.add(scope);
|
|
4095
|
+
this.bumpVersion();
|
|
4058
4096
|
});
|
|
4059
4097
|
return this;
|
|
4060
4098
|
}
|
|
@@ -4067,8 +4105,10 @@ var A_Scope = class {
|
|
|
4067
4105
|
*/
|
|
4068
4106
|
deimport(...scopes) {
|
|
4069
4107
|
scopes.forEach((scope) => {
|
|
4070
|
-
if (this._imports.has(scope))
|
|
4108
|
+
if (this._imports.has(scope)) {
|
|
4071
4109
|
this._imports.delete(scope);
|
|
4110
|
+
this.bumpVersion();
|
|
4111
|
+
}
|
|
4072
4112
|
});
|
|
4073
4113
|
return this;
|
|
4074
4114
|
}
|
|
@@ -4209,6 +4249,20 @@ var A_Scope = class {
|
|
|
4209
4249
|
A_ScopeError.ResolutionError,
|
|
4210
4250
|
`Invalid constructor name provided: ${name}`
|
|
4211
4251
|
);
|
|
4252
|
+
const cacheKey = name;
|
|
4253
|
+
if (this._resolveConstructorCache.has(cacheKey)) {
|
|
4254
|
+
const cached = this._resolveConstructorCache.get(cacheKey);
|
|
4255
|
+
return cached === null ? void 0 : cached;
|
|
4256
|
+
}
|
|
4257
|
+
const resolved = this._resolveConstructorUncached(name);
|
|
4258
|
+
this._resolveConstructorCache.set(cacheKey, resolved ?? null);
|
|
4259
|
+
return resolved;
|
|
4260
|
+
}
|
|
4261
|
+
/**
|
|
4262
|
+
* Internal uncached implementation of resolveConstructor for string names.
|
|
4263
|
+
* Separated to allow the public method to wrap with caching.
|
|
4264
|
+
*/
|
|
4265
|
+
_resolveConstructorUncached(name) {
|
|
4212
4266
|
const component = Array.from(this.allowedComponents).find(
|
|
4213
4267
|
(c) => c.name === name || c.name === A_FormatterHelper.toPascalCase(name)
|
|
4214
4268
|
);
|
|
@@ -4556,6 +4610,7 @@ var A_Scope = class {
|
|
|
4556
4610
|
param1
|
|
4557
4611
|
);
|
|
4558
4612
|
A_Context.register(this, param1);
|
|
4613
|
+
this.bumpVersion();
|
|
4559
4614
|
break;
|
|
4560
4615
|
}
|
|
4561
4616
|
// 3) In case when it's a A-Entity instance
|
|
@@ -4564,6 +4619,7 @@ var A_Scope = class {
|
|
|
4564
4619
|
this.allowedEntities.add(param1.constructor);
|
|
4565
4620
|
this._entities.set(param1.aseid.toString(), param1);
|
|
4566
4621
|
A_Context.register(this, param1);
|
|
4622
|
+
this.bumpVersion();
|
|
4567
4623
|
break;
|
|
4568
4624
|
}
|
|
4569
4625
|
// 4) In case when it's a A-Fragment instance
|
|
@@ -4575,6 +4631,7 @@ var A_Scope = class {
|
|
|
4575
4631
|
param1
|
|
4576
4632
|
);
|
|
4577
4633
|
A_Context.register(this, param1);
|
|
4634
|
+
this.bumpVersion();
|
|
4578
4635
|
break;
|
|
4579
4636
|
}
|
|
4580
4637
|
// 5) In case when it's a A-Error instance
|
|
@@ -4586,6 +4643,7 @@ var A_Scope = class {
|
|
|
4586
4643
|
param1
|
|
4587
4644
|
);
|
|
4588
4645
|
A_Context.register(this, param1);
|
|
4646
|
+
this.bumpVersion();
|
|
4589
4647
|
break;
|
|
4590
4648
|
}
|
|
4591
4649
|
// ------------------------------------------
|
|
@@ -4593,26 +4651,34 @@ var A_Scope = class {
|
|
|
4593
4651
|
// ------------------------------------------
|
|
4594
4652
|
// 6) In case when it's a A-Component constructor
|
|
4595
4653
|
case A_TypeGuards.isComponentConstructor(param1): {
|
|
4596
|
-
if (!this.allowedComponents.has(param1))
|
|
4654
|
+
if (!this.allowedComponents.has(param1)) {
|
|
4597
4655
|
this.allowedComponents.add(param1);
|
|
4656
|
+
this.bumpVersion();
|
|
4657
|
+
}
|
|
4598
4658
|
break;
|
|
4599
4659
|
}
|
|
4600
4660
|
// 8) In case when it's a A-Fragment constructor
|
|
4601
4661
|
case A_TypeGuards.isFragmentConstructor(param1): {
|
|
4602
|
-
if (!this.allowedFragments.has(param1))
|
|
4662
|
+
if (!this.allowedFragments.has(param1)) {
|
|
4603
4663
|
this.allowedFragments.add(param1);
|
|
4664
|
+
this.bumpVersion();
|
|
4665
|
+
}
|
|
4604
4666
|
break;
|
|
4605
4667
|
}
|
|
4606
4668
|
// 9) In case when it's a A-Entity constructor
|
|
4607
4669
|
case A_TypeGuards.isEntityConstructor(param1): {
|
|
4608
|
-
if (!this.allowedEntities.has(param1))
|
|
4670
|
+
if (!this.allowedEntities.has(param1)) {
|
|
4609
4671
|
this.allowedEntities.add(param1);
|
|
4672
|
+
this.bumpVersion();
|
|
4673
|
+
}
|
|
4610
4674
|
break;
|
|
4611
4675
|
}
|
|
4612
4676
|
// 10) In case when it's a A-Error constructor
|
|
4613
4677
|
case A_TypeGuards.isErrorConstructor(param1): {
|
|
4614
|
-
if (!this.allowedErrors.has(param1))
|
|
4678
|
+
if (!this.allowedErrors.has(param1)) {
|
|
4615
4679
|
this.allowedErrors.add(param1);
|
|
4680
|
+
this.bumpVersion();
|
|
4681
|
+
}
|
|
4616
4682
|
break;
|
|
4617
4683
|
}
|
|
4618
4684
|
// ------------------------------------------
|
|
@@ -4652,6 +4718,7 @@ var A_Scope = class {
|
|
|
4652
4718
|
if (!hasComponent) {
|
|
4653
4719
|
this.allowedComponents.delete(ctor);
|
|
4654
4720
|
}
|
|
4721
|
+
this.bumpVersion();
|
|
4655
4722
|
break;
|
|
4656
4723
|
}
|
|
4657
4724
|
// 3) In case when it's a A-Entity instance
|
|
@@ -4663,6 +4730,7 @@ var A_Scope = class {
|
|
|
4663
4730
|
if (!hasEntity) {
|
|
4664
4731
|
this.allowedEntities.delete(ctor);
|
|
4665
4732
|
}
|
|
4733
|
+
this.bumpVersion();
|
|
4666
4734
|
break;
|
|
4667
4735
|
}
|
|
4668
4736
|
// 4) In case when it's a A-Fragment instance
|
|
@@ -4674,6 +4742,7 @@ var A_Scope = class {
|
|
|
4674
4742
|
if (!hasFragment) {
|
|
4675
4743
|
this.allowedFragments.delete(ctor);
|
|
4676
4744
|
}
|
|
4745
|
+
this.bumpVersion();
|
|
4677
4746
|
break;
|
|
4678
4747
|
}
|
|
4679
4748
|
// 5) In case when it's a A-Error instance
|
|
@@ -4685,6 +4754,7 @@ var A_Scope = class {
|
|
|
4685
4754
|
if (!hasError) {
|
|
4686
4755
|
this.allowedErrors.delete(ctor);
|
|
4687
4756
|
}
|
|
4757
|
+
this.bumpVersion();
|
|
4688
4758
|
break;
|
|
4689
4759
|
}
|
|
4690
4760
|
// ------------------------------------------
|
|
@@ -4693,6 +4763,7 @@ var A_Scope = class {
|
|
|
4693
4763
|
// 6) In case when it's a A-Component constructor
|
|
4694
4764
|
case A_TypeGuards.isComponentConstructor(param1): {
|
|
4695
4765
|
this.allowedComponents.delete(param1);
|
|
4766
|
+
this.bumpVersion();
|
|
4696
4767
|
break;
|
|
4697
4768
|
}
|
|
4698
4769
|
// 8) In case when it's a A-Fragment constructor
|
|
@@ -4704,6 +4775,7 @@ var A_Scope = class {
|
|
|
4704
4775
|
A_Context.deregister(instance);
|
|
4705
4776
|
}
|
|
4706
4777
|
});
|
|
4778
|
+
this.bumpVersion();
|
|
4707
4779
|
break;
|
|
4708
4780
|
}
|
|
4709
4781
|
// 9) In case when it's a A-Entity constructor
|
|
@@ -4715,6 +4787,7 @@ var A_Scope = class {
|
|
|
4715
4787
|
A_Context.deregister(instance);
|
|
4716
4788
|
}
|
|
4717
4789
|
});
|
|
4790
|
+
this.bumpVersion();
|
|
4718
4791
|
break;
|
|
4719
4792
|
}
|
|
4720
4793
|
// 10) In case when it's a A-Error constructor
|
|
@@ -4726,6 +4799,7 @@ var A_Scope = class {
|
|
|
4726
4799
|
A_Context.deregister(instance);
|
|
4727
4800
|
}
|
|
4728
4801
|
});
|
|
4802
|
+
this.bumpVersion();
|
|
4729
4803
|
break;
|
|
4730
4804
|
}
|
|
4731
4805
|
// ------------------------------------------
|
|
@@ -4846,6 +4920,11 @@ var A_Scope = class {
|
|
|
4846
4920
|
console.log(chain.join(" -> "));
|
|
4847
4921
|
}
|
|
4848
4922
|
};
|
|
4923
|
+
/**
|
|
4924
|
+
* Auto-incrementing counter for generating unique scope IDs.
|
|
4925
|
+
*/
|
|
4926
|
+
_A_Scope._nextUid = 0;
|
|
4927
|
+
var A_Scope = _A_Scope;
|
|
4849
4928
|
|
|
4850
4929
|
// src/lib/A-Scope/A-Scope.error.ts
|
|
4851
4930
|
var A_ScopeError = class extends A_Error {
|
|
@@ -4882,7 +4961,7 @@ A_ContextError.ComponentNotRegisteredError = "Component not registered in the co
|
|
|
4882
4961
|
A_ContextError.InvalidDeregisterParameterError = "Invalid parameter provided to deregister component";
|
|
4883
4962
|
|
|
4884
4963
|
// src/lib/A-Context/A-Context.class.ts
|
|
4885
|
-
var
|
|
4964
|
+
var _A_Context = class _A_Context {
|
|
4886
4965
|
/**
|
|
4887
4966
|
* Private constructor to enforce singleton pattern.
|
|
4888
4967
|
*
|
|
@@ -4909,6 +4988,18 @@ var A_Context = class _A_Context {
|
|
|
4909
4988
|
* Meta provides to store extra information about the class behavior and configuration.
|
|
4910
4989
|
*/
|
|
4911
4990
|
this._metaStorage = /* @__PURE__ */ new Map();
|
|
4991
|
+
/**
|
|
4992
|
+
* Monotonically increasing version counter for _metaStorage.
|
|
4993
|
+
* Incremented whenever a new entry is added to _metaStorage so that
|
|
4994
|
+
* caches depending on meta content can detect staleness.
|
|
4995
|
+
*/
|
|
4996
|
+
this._metaVersion = 0;
|
|
4997
|
+
/**
|
|
4998
|
+
* Cache for featureExtensions results.
|
|
4999
|
+
* Key format: `${featureName}::${componentConstructorName}::${scopeVersion}::${metaVersion}`
|
|
5000
|
+
* Automatically invalidated when scope version or meta version changes.
|
|
5001
|
+
*/
|
|
5002
|
+
this._featureExtensionsCache = /* @__PURE__ */ new Map();
|
|
4912
5003
|
this._globals = /* @__PURE__ */ new Map();
|
|
4913
5004
|
const name = String(A_CONCEPT_ENV.A_CONCEPT_ROOT_SCOPE) || "root";
|
|
4914
5005
|
this._root = new A_Scope({ name });
|
|
@@ -5112,6 +5203,7 @@ var A_Context = class _A_Context {
|
|
|
5112
5203
|
if (!inheritedMeta)
|
|
5113
5204
|
inheritedMeta = new metaType();
|
|
5114
5205
|
instance._metaStorage.set(property, inheritedMeta.clone());
|
|
5206
|
+
instance._metaVersion++;
|
|
5115
5207
|
}
|
|
5116
5208
|
return instance._metaStorage.get(property);
|
|
5117
5209
|
}
|
|
@@ -5120,6 +5212,7 @@ var A_Context = class _A_Context {
|
|
|
5120
5212
|
const existingMeta = _A_Context.meta(param1);
|
|
5121
5213
|
const constructor = typeof param1 === "function" ? param1 : param1.constructor;
|
|
5122
5214
|
instance._metaStorage.set(constructor, existingMeta ? meta.from(existingMeta) : meta);
|
|
5215
|
+
instance._metaVersion++;
|
|
5123
5216
|
}
|
|
5124
5217
|
/**
|
|
5125
5218
|
*
|
|
@@ -5175,11 +5268,10 @@ var A_Context = class _A_Context {
|
|
|
5175
5268
|
* @param name
|
|
5176
5269
|
*/
|
|
5177
5270
|
static featureTemplate(name, component, scope = this.scope(component)) {
|
|
5178
|
-
const componentName = A_CommonHelper.getComponentName(component);
|
|
5179
5271
|
if (!component) throw new A_ContextError(A_ContextError.InvalidFeatureTemplateParameterError, `Unable to get feature template. Component cannot be null or undefined.`);
|
|
5180
5272
|
if (!name) throw new A_ContextError(A_ContextError.InvalidFeatureTemplateParameterError, `Unable to get feature template. Feature name cannot be null or undefined.`);
|
|
5181
5273
|
if (!A_TypeGuards.isAllowedForFeatureDefinition(component))
|
|
5182
|
-
throw new A_ContextError(A_ContextError.InvalidFeatureTemplateParameterError, `Unable to get feature template. Component of type ${
|
|
5274
|
+
throw new A_ContextError(A_ContextError.InvalidFeatureTemplateParameterError, `Unable to get feature template. Component of type ${A_CommonHelper.getComponentName(component)} is not allowed for feature definition.`);
|
|
5183
5275
|
const steps = [
|
|
5184
5276
|
// 1) Get the base feature definition from the component
|
|
5185
5277
|
...this.featureDefinition(name, component),
|
|
@@ -5202,59 +5294,116 @@ var A_Context = class _A_Context {
|
|
|
5202
5294
|
*/
|
|
5203
5295
|
static featureExtensions(name, component, scope) {
|
|
5204
5296
|
const instance = this.getInstance();
|
|
5205
|
-
const componentName = A_CommonHelper.getComponentName(component);
|
|
5206
5297
|
if (!component) throw new A_ContextError(A_ContextError.InvalidFeatureExtensionParameterError, `Unable to get feature template. Component cannot be null or undefined.`);
|
|
5207
5298
|
if (!name) throw new A_ContextError(A_ContextError.InvalidFeatureExtensionParameterError, `Unable to get feature template. Feature name cannot be null or undefined.`);
|
|
5208
5299
|
if (!A_TypeGuards.isAllowedForFeatureDefinition(component))
|
|
5209
|
-
throw new A_ContextError(A_ContextError.InvalidFeatureExtensionParameterError, `Unable to get feature template. Component of type ${
|
|
5300
|
+
throw new A_ContextError(A_ContextError.InvalidFeatureExtensionParameterError, `Unable to get feature template. Component of type ${A_CommonHelper.getComponentName(component)} is not allowed for feature definition.`);
|
|
5301
|
+
const componentCtor = typeof component === "function" ? component : component.constructor;
|
|
5302
|
+
const effectiveScope = scope.parent || scope;
|
|
5303
|
+
const cacheKey = `${String(name)}::${componentCtor.name}::s${effectiveScope.uid}v${effectiveScope.version}::m${instance._metaVersion}`;
|
|
5304
|
+
const cached = instance._featureExtensionsCache.get(cacheKey);
|
|
5305
|
+
if (cached) {
|
|
5306
|
+
return cached;
|
|
5307
|
+
}
|
|
5210
5308
|
const callNames = A_CommonHelper.getClassInheritanceChain(component).filter((c) => c !== A_Component && c !== A_Container && c !== A_Entity).map((c) => `${c.name}.${name}`);
|
|
5211
5309
|
const steps = /* @__PURE__ */ new Map();
|
|
5212
5310
|
const allowedComponents = /* @__PURE__ */ new Set();
|
|
5311
|
+
const componentNameCache = /* @__PURE__ */ new Map();
|
|
5312
|
+
const dependencyCache = /* @__PURE__ */ new Map();
|
|
5313
|
+
const getNameCached = (cmp) => {
|
|
5314
|
+
let n = componentNameCache.get(cmp);
|
|
5315
|
+
if (n === void 0) {
|
|
5316
|
+
n = A_CommonHelper.getComponentName(cmp);
|
|
5317
|
+
componentNameCache.set(cmp, n);
|
|
5318
|
+
}
|
|
5319
|
+
return n;
|
|
5320
|
+
};
|
|
5321
|
+
const getDependencyCached = (cmp) => {
|
|
5322
|
+
let d = dependencyCache.get(cmp);
|
|
5323
|
+
if (!d) {
|
|
5324
|
+
d = new A_Dependency(cmp);
|
|
5325
|
+
dependencyCache.set(cmp, d);
|
|
5326
|
+
}
|
|
5327
|
+
return d;
|
|
5328
|
+
};
|
|
5329
|
+
const scopeFilteredMetas = [];
|
|
5330
|
+
for (const [cmp, meta] of instance._metaStorage) {
|
|
5331
|
+
if (scope.has(cmp) && (A_TypeGuards.isComponentMetaInstance(meta) || A_TypeGuards.isContainerMetaInstance(meta))) {
|
|
5332
|
+
scopeFilteredMetas.push([cmp, meta]);
|
|
5333
|
+
}
|
|
5334
|
+
}
|
|
5213
5335
|
for (const callName of callNames) {
|
|
5214
|
-
for (const [cmp, meta] of
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
}
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5336
|
+
for (const [cmp, meta] of scopeFilteredMetas) {
|
|
5337
|
+
allowedComponents.add(cmp);
|
|
5338
|
+
const extensions = meta.extensions(callName);
|
|
5339
|
+
for (let i = 0; i < extensions.length; i++) {
|
|
5340
|
+
const declaration = extensions[i];
|
|
5341
|
+
const inherited = Array.from(allowedComponents).reverse().find((c) => A_CommonHelper.isInheritedFrom(cmp, c) && c !== cmp);
|
|
5342
|
+
if (inherited) {
|
|
5343
|
+
steps.delete(`${getNameCached(inherited)}.${declaration.handler}`);
|
|
5344
|
+
}
|
|
5345
|
+
if (declaration.override) {
|
|
5346
|
+
const overrideRegexp = new RegExp(declaration.override);
|
|
5347
|
+
for (const [stepKey, step] of steps) {
|
|
5348
|
+
if (overrideRegexp.test(stepKey) || overrideRegexp.test(step.handler)) {
|
|
5349
|
+
steps.delete(stepKey);
|
|
5228
5350
|
}
|
|
5229
5351
|
}
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5352
|
+
}
|
|
5353
|
+
steps.set(`${getNameCached(cmp)}.${declaration.handler}`, {
|
|
5354
|
+
dependency: getDependencyCached(cmp),
|
|
5355
|
+
...declaration
|
|
5234
5356
|
});
|
|
5235
5357
|
}
|
|
5236
5358
|
}
|
|
5237
5359
|
}
|
|
5238
|
-
|
|
5360
|
+
const result = instance.filterToMostDerived(scope, Array.from(steps.values()));
|
|
5361
|
+
if (instance._featureExtensionsCache.size >= _A_Context.FEATURE_EXTENSIONS_CACHE_MAX_SIZE) {
|
|
5362
|
+
instance._featureExtensionsCache.clear();
|
|
5363
|
+
}
|
|
5364
|
+
instance._featureExtensionsCache.set(cacheKey, result);
|
|
5365
|
+
return result;
|
|
5239
5366
|
}
|
|
5240
5367
|
/**
|
|
5241
5368
|
* method helps to filter steps in a way that only the most derived classes are kept.
|
|
5242
5369
|
*
|
|
5370
|
+
* Optimized: Uses a pre-built constructor→class map and single-pass prototype chain
|
|
5371
|
+
* walk to eliminate parent classes in O(n·d) where d is inheritance depth,
|
|
5372
|
+
* instead of the previous O(n²) with isPrototypeOf checks.
|
|
5373
|
+
*
|
|
5243
5374
|
* @param scope
|
|
5244
5375
|
* @param items
|
|
5245
5376
|
* @returns
|
|
5246
5377
|
*/
|
|
5247
5378
|
filterToMostDerived(scope, items) {
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
}
|
|
5256
|
-
|
|
5257
|
-
}
|
|
5379
|
+
if (items.length <= 1) return items;
|
|
5380
|
+
const resolvedClasses = /* @__PURE__ */ new Map();
|
|
5381
|
+
const presentNames = /* @__PURE__ */ new Set();
|
|
5382
|
+
for (const item of items) {
|
|
5383
|
+
const depName = item.dependency.name;
|
|
5384
|
+
if (!resolvedClasses.has(depName)) {
|
|
5385
|
+
resolvedClasses.set(depName, scope.resolveConstructor(depName));
|
|
5386
|
+
}
|
|
5387
|
+
presentNames.add(depName);
|
|
5388
|
+
}
|
|
5389
|
+
const parentNames = /* @__PURE__ */ new Set();
|
|
5390
|
+
const ctorToName = /* @__PURE__ */ new Map();
|
|
5391
|
+
for (const [depName, ctor] of resolvedClasses) {
|
|
5392
|
+
if (ctor) ctorToName.set(ctor, depName);
|
|
5393
|
+
}
|
|
5394
|
+
for (const [depName, ctor] of resolvedClasses) {
|
|
5395
|
+
if (!ctor) continue;
|
|
5396
|
+
let ancestor = Object.getPrototypeOf(ctor.prototype);
|
|
5397
|
+
while (ancestor && ancestor !== Object.prototype) {
|
|
5398
|
+
const ancestorCtor = ancestor.constructor;
|
|
5399
|
+
const ancestorName = ctorToName.get(ancestorCtor);
|
|
5400
|
+
if (ancestorName && ancestorName !== depName && presentNames.has(ancestorName)) {
|
|
5401
|
+
parentNames.add(ancestorName);
|
|
5402
|
+
}
|
|
5403
|
+
ancestor = Object.getPrototypeOf(ancestor);
|
|
5404
|
+
}
|
|
5405
|
+
}
|
|
5406
|
+
return items.filter((item) => !parentNames.has(item.dependency.name));
|
|
5258
5407
|
}
|
|
5259
5408
|
/**
|
|
5260
5409
|
* This method returns the feature template definition without any extensions.
|
|
@@ -5369,6 +5518,8 @@ var A_Context = class _A_Context {
|
|
|
5369
5518
|
static reset() {
|
|
5370
5519
|
const instance = _A_Context.getInstance();
|
|
5371
5520
|
instance._registry = /* @__PURE__ */ new WeakMap();
|
|
5521
|
+
instance._featureExtensionsCache.clear();
|
|
5522
|
+
instance._metaVersion++;
|
|
5372
5523
|
const name = String(A_CONCEPT_ENV.A_CONCEPT_ROOT_SCOPE) || "root";
|
|
5373
5524
|
instance._root = new A_Scope({ name });
|
|
5374
5525
|
}
|
|
@@ -5412,6 +5563,12 @@ var A_Context = class _A_Context {
|
|
|
5412
5563
|
return A_TypeGuards.isContainerConstructor(param) || A_TypeGuards.isComponentConstructor(param) || A_TypeGuards.isEntityConstructor(param);
|
|
5413
5564
|
}
|
|
5414
5565
|
};
|
|
5566
|
+
/**
|
|
5567
|
+
* Maximum number of entries in the featureExtensions cache.
|
|
5568
|
+
* When exceeded, the entire cache is cleared to prevent unbounded growth.
|
|
5569
|
+
*/
|
|
5570
|
+
_A_Context.FEATURE_EXTENSIONS_CACHE_MAX_SIZE = 1024;
|
|
5571
|
+
var A_Context = _A_Context;
|
|
5415
5572
|
|
|
5416
5573
|
// src/lib/A-Abstraction/A-Abstraction.error.ts
|
|
5417
5574
|
var A_AbstractionError = class extends A_Error {
|