@adaas/a-concept 0.3.8 → 0.3.9
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/benchmarks/feature-optimize.bench.ts +129 -54
- package/dist/browser/index.d.mts +62 -12
- package/dist/browser/index.mjs +2 -2
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/index.cjs +301 -102
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.mts +62 -12
- package/dist/node/index.d.ts +62 -12
- package/dist/node/index.mjs +301 -102
- package/dist/node/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/lib/A-Context/A-Context.class.ts +214 -41
- package/src/lib/A-Feature/A-Feature.class.ts +34 -31
- package/src/lib/A-Scope/A-Scope.class.ts +143 -72
- package/tests/A-Meta.test.ts +46 -2
- package/tests/A-Scope.test.ts +188 -0
- package/tsconfig.json +1 -0
package/dist/node/index.cjs
CHANGED
|
@@ -3431,8 +3431,26 @@ var A_Feature = class _A_Feature {
|
|
|
3431
3431
|
if (this.isProcessed)
|
|
3432
3432
|
return;
|
|
3433
3433
|
this._state = "PROCESSING" /* PROCESSING */;
|
|
3434
|
-
const
|
|
3435
|
-
|
|
3434
|
+
for (const stage of this) {
|
|
3435
|
+
if (this.state === "INTERRUPTED" /* INTERRUPTED */) return;
|
|
3436
|
+
let result;
|
|
3437
|
+
try {
|
|
3438
|
+
result = stage.process(scope);
|
|
3439
|
+
} catch (error) {
|
|
3440
|
+
throw this.createStageError(error, stage);
|
|
3441
|
+
}
|
|
3442
|
+
if (A_TypeGuards.isPromiseInstance(result)) {
|
|
3443
|
+
return result.then(() => {
|
|
3444
|
+
if (this.state === "INTERRUPTED" /* INTERRUPTED */) return;
|
|
3445
|
+
return this.processRemainingStagesAsync(scope);
|
|
3446
|
+
}).catch((error) => {
|
|
3447
|
+
throw this.createStageError(error, stage);
|
|
3448
|
+
});
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
if (this.state !== "INTERRUPTED" /* INTERRUPTED */) {
|
|
3452
|
+
this.completed();
|
|
3453
|
+
}
|
|
3436
3454
|
} catch (error) {
|
|
3437
3455
|
throw this.failed(new A_FeatureError({
|
|
3438
3456
|
title: A_FeatureError.FeatureProcessingError,
|
|
@@ -3443,27 +3461,18 @@ var A_Feature = class _A_Feature {
|
|
|
3443
3461
|
}
|
|
3444
3462
|
}
|
|
3445
3463
|
/**
|
|
3446
|
-
*
|
|
3464
|
+
* Async continuation — processes remaining stages after the first async pivot.
|
|
3465
|
+
* Resumes from the current iterator position (this._index).
|
|
3447
3466
|
*/
|
|
3448
|
-
|
|
3449
|
-
|
|
3467
|
+
async processRemainingStagesAsync(scope) {
|
|
3468
|
+
for (const stage of this) {
|
|
3450
3469
|
if (this.state === "INTERRUPTED" /* INTERRUPTED */) return;
|
|
3451
|
-
const stage = stages[index];
|
|
3452
|
-
let result;
|
|
3453
3470
|
try {
|
|
3454
|
-
result = stage.process(scope);
|
|
3471
|
+
const result = stage.process(scope);
|
|
3472
|
+
if (A_TypeGuards.isPromiseInstance(result)) await result;
|
|
3455
3473
|
} catch (error) {
|
|
3456
3474
|
throw this.createStageError(error, stage);
|
|
3457
3475
|
}
|
|
3458
|
-
if (A_TypeGuards.isPromiseInstance(result)) {
|
|
3459
|
-
return result.then(() => {
|
|
3460
|
-
if (this.state === "INTERRUPTED" /* INTERRUPTED */) return;
|
|
3461
|
-
return this.processStagesSequentially(stages, scope, index + 1);
|
|
3462
|
-
}).catch((error) => {
|
|
3463
|
-
throw this.createStageError(error, stage);
|
|
3464
|
-
});
|
|
3465
|
-
}
|
|
3466
|
-
index++;
|
|
3467
3476
|
}
|
|
3468
3477
|
if (this.state !== "INTERRUPTED" /* INTERRUPTED */) {
|
|
3469
3478
|
this.completed();
|
|
@@ -3682,13 +3691,8 @@ var A_ComponentMeta = class extends A_Meta {
|
|
|
3682
3691
|
};
|
|
3683
3692
|
|
|
3684
3693
|
// src/lib/A-Scope/A-Scope.class.ts
|
|
3685
|
-
var
|
|
3694
|
+
var A_Scope = class {
|
|
3686
3695
|
constructor(param1, param2) {
|
|
3687
|
-
/**
|
|
3688
|
-
* Unique numeric ID for this scope instance. Used as a cache key discriminator
|
|
3689
|
-
* to prevent collisions between scopes with the same name or version.
|
|
3690
|
-
*/
|
|
3691
|
-
this.uid = _A_Scope._nextUid++;
|
|
3692
3696
|
/**
|
|
3693
3697
|
* Internal meta storage using A_Meta for type-safe key-value operations.
|
|
3694
3698
|
* This stores all the scope's runtime data that can be accessed and modified
|
|
@@ -3712,6 +3716,7 @@ var _A_Scope = class _A_Scope {
|
|
|
3712
3716
|
* Invalidated by incrementing _version (cache is cleared on bump).
|
|
3713
3717
|
*/
|
|
3714
3718
|
this._resolveConstructorCache = /* @__PURE__ */ new Map();
|
|
3719
|
+
this._cachedFingerprintVersion = -1;
|
|
3715
3720
|
// ===========================================================================
|
|
3716
3721
|
// --------------------ALLowed Constructors--------------------------------
|
|
3717
3722
|
// ===========================================================================
|
|
@@ -3804,6 +3809,20 @@ var _A_Scope = class _A_Scope {
|
|
|
3804
3809
|
get version() {
|
|
3805
3810
|
return this._version;
|
|
3806
3811
|
}
|
|
3812
|
+
/**
|
|
3813
|
+
* Returns a content-addressable fingerprint of the scope.
|
|
3814
|
+
* Two scopes with identical content (components, entities, fragments, errors, imports, parent)
|
|
3815
|
+
* will produce the same fingerprint. Dynamically recomputed when scope content changes.
|
|
3816
|
+
*/
|
|
3817
|
+
get fingerprint() {
|
|
3818
|
+
const aggregateVersion = this.aggregateVersion(/* @__PURE__ */ new Set());
|
|
3819
|
+
if (this._cachedFingerprint !== void 0 && this._cachedFingerprintVersion === aggregateVersion) {
|
|
3820
|
+
return this._cachedFingerprint;
|
|
3821
|
+
}
|
|
3822
|
+
this._cachedFingerprint = this.computeFingerprint(/* @__PURE__ */ new Set());
|
|
3823
|
+
this._cachedFingerprintVersion = aggregateVersion;
|
|
3824
|
+
return this._cachedFingerprint;
|
|
3825
|
+
}
|
|
3807
3826
|
// ===========================================================================
|
|
3808
3827
|
// --------------------Readonly Registered Properties--------------------------
|
|
3809
3828
|
// ===========================================================================
|
|
@@ -3862,6 +3881,45 @@ var _A_Scope = class _A_Scope {
|
|
|
3862
3881
|
bumpVersion() {
|
|
3863
3882
|
this._version++;
|
|
3864
3883
|
this._resolveConstructorCache.clear();
|
|
3884
|
+
this._cachedFingerprint = void 0;
|
|
3885
|
+
}
|
|
3886
|
+
/**
|
|
3887
|
+
* Computes the aggregate version of this scope and all reachable scopes (parent + imports).
|
|
3888
|
+
* Used to detect when any transitive dependency has changed, so the fingerprint cache can be invalidated.
|
|
3889
|
+
*/
|
|
3890
|
+
aggregateVersion(visited) {
|
|
3891
|
+
if (visited.has(this)) return 0;
|
|
3892
|
+
visited.add(this);
|
|
3893
|
+
let v = this._version;
|
|
3894
|
+
if (this._parent) v += this._parent.aggregateVersion(visited);
|
|
3895
|
+
for (const imp of this._imports) v += imp.aggregateVersion(visited);
|
|
3896
|
+
return v;
|
|
3897
|
+
}
|
|
3898
|
+
/**
|
|
3899
|
+
* Computes a deterministic content-addressable fingerprint string.
|
|
3900
|
+
* Includes components, entities, fragments, errors, parent, and imports.
|
|
3901
|
+
*/
|
|
3902
|
+
computeFingerprint(visited) {
|
|
3903
|
+
if (visited.has(this)) return "~circular~";
|
|
3904
|
+
visited.add(this);
|
|
3905
|
+
const parts = [];
|
|
3906
|
+
parts.push("P:" + (this._parent ? this._parent.computeFingerprint(visited) : "-"));
|
|
3907
|
+
const allowedComponentNames = Array.from(this._allowedComponents).map((c) => A_CommonHelper.getComponentName(c.name)).sort();
|
|
3908
|
+
parts.push("AC:" + allowedComponentNames.join(","));
|
|
3909
|
+
const allowedEntityNames = Array.from(this._allowedEntities).map((e) => A_CommonHelper.getComponentName(e.name)).sort();
|
|
3910
|
+
parts.push("AE:" + allowedEntityNames.join(","));
|
|
3911
|
+
const allowedFragmentNames = Array.from(this._allowedFragments).map((f) => A_CommonHelper.getComponentName(f.name)).sort();
|
|
3912
|
+
parts.push("AF:" + allowedFragmentNames.join(","));
|
|
3913
|
+
const allowedErrorNames = Array.from(this._allowedErrors).map((e) => A_CommonHelper.getComponentName(e.name)).sort();
|
|
3914
|
+
parts.push("AR:" + allowedErrorNames.join(","));
|
|
3915
|
+
const importFingerprints = Array.from(this._imports).map((s) => s.computeFingerprint(visited)).sort();
|
|
3916
|
+
parts.push("I:" + importFingerprints.join(","));
|
|
3917
|
+
const raw = parts.join("|");
|
|
3918
|
+
let hash = 5381;
|
|
3919
|
+
for (let i = 0; i < raw.length; i++) {
|
|
3920
|
+
hash = (hash << 5) + hash + raw.charCodeAt(i) | 0;
|
|
3921
|
+
}
|
|
3922
|
+
return (hash >>> 0).toString(16);
|
|
3865
3923
|
}
|
|
3866
3924
|
/**
|
|
3867
3925
|
* Generator to iterate through all parent scopes
|
|
@@ -3993,9 +4051,6 @@ var _A_Scope = class _A_Scope {
|
|
|
3993
4051
|
this._fragments.clear();
|
|
3994
4052
|
this._entities.clear();
|
|
3995
4053
|
this._imports.clear();
|
|
3996
|
-
if (this.issuer()) {
|
|
3997
|
-
A_Context.deallocate(this);
|
|
3998
|
-
}
|
|
3999
4054
|
this.bumpVersion();
|
|
4000
4055
|
}
|
|
4001
4056
|
/**
|
|
@@ -4144,29 +4199,26 @@ var _A_Scope = class _A_Scope {
|
|
|
4144
4199
|
}
|
|
4145
4200
|
// 3) Check if it's a Component
|
|
4146
4201
|
case A_TypeGuards.isComponentConstructor(ctor): {
|
|
4147
|
-
found = this.isAllowedComponent(ctor) || !!
|
|
4202
|
+
found = this.isAllowedComponent(ctor) || !!A_Context.findDescendantIn(ctor, this.allowedComponents);
|
|
4148
4203
|
break;
|
|
4149
4204
|
}
|
|
4150
4205
|
// 4) Check if it's an Entity
|
|
4151
4206
|
case A_TypeGuards.isEntityConstructor(ctor): {
|
|
4152
|
-
found = this.isAllowedEntity(ctor) || !!
|
|
4207
|
+
found = this.isAllowedEntity(ctor) || !!A_Context.findDescendantIn(ctor, this.allowedEntities);
|
|
4153
4208
|
break;
|
|
4154
4209
|
}
|
|
4155
4210
|
// 5) Check if it's a Fragment
|
|
4156
4211
|
case A_TypeGuards.isFragmentConstructor(ctor): {
|
|
4157
|
-
found = this.isAllowedFragment(ctor) || !!
|
|
4212
|
+
found = this.isAllowedFragment(ctor) || !!A_Context.findDescendantIn(ctor, this.allowedFragments);
|
|
4158
4213
|
break;
|
|
4159
4214
|
}
|
|
4160
4215
|
// 6) Check if it's an Error
|
|
4161
4216
|
case A_TypeGuards.isErrorConstructor(ctor): {
|
|
4162
|
-
found = this.isAllowedError(ctor) || !!
|
|
4217
|
+
found = this.isAllowedError(ctor) || !!A_Context.findDescendantIn(ctor, this.allowedErrors);
|
|
4163
4218
|
break;
|
|
4164
4219
|
}
|
|
4165
4220
|
// 7) Check scope issuer
|
|
4166
|
-
case (this.issuer() && (this.issuer().constructor === ctor ||
|
|
4167
|
-
this.issuer().constructor,
|
|
4168
|
-
ctor
|
|
4169
|
-
))): {
|
|
4221
|
+
case (this.issuer() && (this.issuer().constructor === ctor || A_Context.isIndexedInheritedFrom(this.issuer().constructor, ctor))): {
|
|
4170
4222
|
found = true;
|
|
4171
4223
|
break;
|
|
4172
4224
|
}
|
|
@@ -4238,13 +4290,13 @@ var _A_Scope = class _A_Scope {
|
|
|
4238
4290
|
resolveConstructor(name) {
|
|
4239
4291
|
switch (true) {
|
|
4240
4292
|
case A_TypeGuards.isComponentConstructor(name):
|
|
4241
|
-
return
|
|
4293
|
+
return A_Context.findDescendantIn(name, this.allowedComponents);
|
|
4242
4294
|
case A_TypeGuards.isEntityConstructor(name):
|
|
4243
|
-
return
|
|
4295
|
+
return A_Context.findDescendantIn(name, this.allowedEntities);
|
|
4244
4296
|
case A_TypeGuards.isFragmentConstructor(name):
|
|
4245
|
-
return
|
|
4297
|
+
return A_Context.findDescendantIn(name, this.allowedFragments);
|
|
4246
4298
|
case A_TypeGuards.isErrorConstructor(name):
|
|
4247
|
-
return
|
|
4299
|
+
return A_Context.findDescendantIn(name, this.allowedErrors);
|
|
4248
4300
|
}
|
|
4249
4301
|
if (!A_TypeGuards.isString(name))
|
|
4250
4302
|
throw new A_ScopeError(
|
|
@@ -4270,19 +4322,15 @@ var _A_Scope = class _A_Scope {
|
|
|
4270
4322
|
);
|
|
4271
4323
|
if (component) return component;
|
|
4272
4324
|
else {
|
|
4273
|
-
const
|
|
4274
|
-
|
|
4275
|
-
(c)
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
return true;
|
|
4280
|
-
}
|
|
4281
|
-
current = Object.getPrototypeOf(current);
|
|
4282
|
-
}
|
|
4283
|
-
return false;
|
|
4325
|
+
const pascalName = A_FormatterHelper.toPascalCase(name);
|
|
4326
|
+
const protoComponent = Array.from(this.allowedComponents).find((c) => {
|
|
4327
|
+
const ancestors = A_Context.getAncestors(c);
|
|
4328
|
+
if (!ancestors) return false;
|
|
4329
|
+
for (const ancestor of ancestors) {
|
|
4330
|
+
if (ancestor.name === name || ancestor.name === pascalName) return true;
|
|
4284
4331
|
}
|
|
4285
|
-
|
|
4332
|
+
return false;
|
|
4333
|
+
});
|
|
4286
4334
|
if (protoComponent) return protoComponent;
|
|
4287
4335
|
}
|
|
4288
4336
|
const entity = Array.from(this.allowedEntities).find(
|
|
@@ -4290,9 +4338,15 @@ var _A_Scope = class _A_Scope {
|
|
|
4290
4338
|
);
|
|
4291
4339
|
if (entity) return entity;
|
|
4292
4340
|
else {
|
|
4293
|
-
const
|
|
4294
|
-
|
|
4295
|
-
|
|
4341
|
+
const pascalName = A_FormatterHelper.toPascalCase(name);
|
|
4342
|
+
const protoEntity = Array.from(this.allowedEntities).find((e) => {
|
|
4343
|
+
const ancestors = A_Context.getAncestors(e);
|
|
4344
|
+
if (!ancestors) return false;
|
|
4345
|
+
for (const ancestor of ancestors) {
|
|
4346
|
+
if (ancestor.name === name || ancestor.name === pascalName) return true;
|
|
4347
|
+
}
|
|
4348
|
+
return false;
|
|
4349
|
+
});
|
|
4296
4350
|
if (protoEntity) return protoEntity;
|
|
4297
4351
|
}
|
|
4298
4352
|
const fragment = Array.from(this.allowedFragments).find(
|
|
@@ -4300,9 +4354,15 @@ var _A_Scope = class _A_Scope {
|
|
|
4300
4354
|
);
|
|
4301
4355
|
if (fragment) return fragment;
|
|
4302
4356
|
else {
|
|
4303
|
-
const
|
|
4304
|
-
|
|
4305
|
-
|
|
4357
|
+
const pascalName = A_FormatterHelper.toPascalCase(name);
|
|
4358
|
+
const protoFragment = Array.from(this.allowedFragments).find((f) => {
|
|
4359
|
+
const ancestors = A_Context.getAncestors(f);
|
|
4360
|
+
if (!ancestors) return false;
|
|
4361
|
+
for (const ancestor of ancestors) {
|
|
4362
|
+
if (ancestor.name === name || ancestor.name === pascalName) return true;
|
|
4363
|
+
}
|
|
4364
|
+
return false;
|
|
4365
|
+
});
|
|
4306
4366
|
if (protoFragment) return protoFragment;
|
|
4307
4367
|
}
|
|
4308
4368
|
for (const importedScope of this._imports) {
|
|
@@ -4340,7 +4400,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4340
4400
|
// 1) if a parameter is a component constructor
|
|
4341
4401
|
case A_TypeGuards.isComponentConstructor(param1): {
|
|
4342
4402
|
this.allowedComponents.forEach((ctor) => {
|
|
4343
|
-
if (
|
|
4403
|
+
if (A_Context.isIndexedInheritedFrom(ctor, param1)) {
|
|
4344
4404
|
const instance = this.resolveOnce(ctor);
|
|
4345
4405
|
if (instance) results.push(instance);
|
|
4346
4406
|
}
|
|
@@ -4350,7 +4410,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4350
4410
|
// 2) if a parameter is a fragment constructor
|
|
4351
4411
|
case A_TypeGuards.isFragmentConstructor(param1): {
|
|
4352
4412
|
this.allowedFragments.forEach((ctor) => {
|
|
4353
|
-
if (
|
|
4413
|
+
if (A_Context.isIndexedInheritedFrom(ctor, param1)) {
|
|
4354
4414
|
const instance = this.resolveOnce(ctor);
|
|
4355
4415
|
if (instance) results.push(instance);
|
|
4356
4416
|
}
|
|
@@ -4359,7 +4419,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4359
4419
|
}
|
|
4360
4420
|
case A_TypeGuards.isEntityConstructor(param1): {
|
|
4361
4421
|
this.entities.forEach((entity) => {
|
|
4362
|
-
if (
|
|
4422
|
+
if (A_Context.isIndexedInheritedFrom(entity.constructor, param1)) {
|
|
4363
4423
|
results.push(entity);
|
|
4364
4424
|
}
|
|
4365
4425
|
});
|
|
@@ -4505,7 +4565,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4505
4565
|
*/
|
|
4506
4566
|
resolveIssuer(ctor) {
|
|
4507
4567
|
const issuer = this.issuer();
|
|
4508
|
-
if (issuer && (issuer.constructor === ctor ||
|
|
4568
|
+
if (issuer && (issuer.constructor === ctor || A_Context.isIndexedInheritedFrom(issuer?.constructor, ctor))) {
|
|
4509
4569
|
return issuer;
|
|
4510
4570
|
}
|
|
4511
4571
|
return void 0;
|
|
@@ -4548,9 +4608,10 @@ var _A_Scope = class _A_Scope {
|
|
|
4548
4608
|
switch (true) {
|
|
4549
4609
|
case (fragmentInstancePresented && this._fragments.has(fragment)):
|
|
4550
4610
|
return fragmentInstancePresented;
|
|
4551
|
-
// 3) In case when there's a
|
|
4552
|
-
case
|
|
4553
|
-
const found =
|
|
4611
|
+
// 3) In case when there's a fragment that is inherited from the required fragment
|
|
4612
|
+
case !fragmentInstancePresented: {
|
|
4613
|
+
const found = A_Context.findDescendantIn(fragment, this._allowedFragments);
|
|
4614
|
+
if (!found) return void 0;
|
|
4554
4615
|
return this.resolveFragment(found);
|
|
4555
4616
|
}
|
|
4556
4617
|
default:
|
|
@@ -4590,8 +4651,9 @@ var _A_Scope = class _A_Scope {
|
|
|
4590
4651
|
return this._components.get(component);
|
|
4591
4652
|
}
|
|
4592
4653
|
// 3) In case when there's a component that is inherited from the required component
|
|
4593
|
-
case
|
|
4594
|
-
const found =
|
|
4654
|
+
case !this.allowedComponents.has(component): {
|
|
4655
|
+
const found = A_Context.findDescendantIn(component, this.allowedComponents);
|
|
4656
|
+
if (!found) return void 0;
|
|
4595
4657
|
return this.resolveComponent(found);
|
|
4596
4658
|
}
|
|
4597
4659
|
default:
|
|
@@ -4611,6 +4673,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4611
4673
|
param1.constructor,
|
|
4612
4674
|
param1
|
|
4613
4675
|
);
|
|
4676
|
+
A_Context.indexConstructor(param1.constructor);
|
|
4614
4677
|
A_Context.register(this, param1);
|
|
4615
4678
|
this.bumpVersion();
|
|
4616
4679
|
break;
|
|
@@ -4620,6 +4683,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4620
4683
|
if (!this.allowedEntities.has(param1.constructor))
|
|
4621
4684
|
this.allowedEntities.add(param1.constructor);
|
|
4622
4685
|
this._entities.set(param1.aseid.toString(), param1);
|
|
4686
|
+
A_Context.indexConstructor(param1.constructor);
|
|
4623
4687
|
A_Context.register(this, param1);
|
|
4624
4688
|
this.bumpVersion();
|
|
4625
4689
|
break;
|
|
@@ -4632,6 +4696,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4632
4696
|
param1.constructor,
|
|
4633
4697
|
param1
|
|
4634
4698
|
);
|
|
4699
|
+
A_Context.indexConstructor(param1.constructor);
|
|
4635
4700
|
A_Context.register(this, param1);
|
|
4636
4701
|
this.bumpVersion();
|
|
4637
4702
|
break;
|
|
@@ -4644,6 +4709,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4644
4709
|
param1.code,
|
|
4645
4710
|
param1
|
|
4646
4711
|
);
|
|
4712
|
+
A_Context.indexConstructor(param1.constructor);
|
|
4647
4713
|
A_Context.register(this, param1);
|
|
4648
4714
|
this.bumpVersion();
|
|
4649
4715
|
break;
|
|
@@ -4655,6 +4721,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4655
4721
|
case A_TypeGuards.isComponentConstructor(param1): {
|
|
4656
4722
|
if (!this.allowedComponents.has(param1)) {
|
|
4657
4723
|
this.allowedComponents.add(param1);
|
|
4724
|
+
A_Context.indexConstructor(param1);
|
|
4658
4725
|
this.bumpVersion();
|
|
4659
4726
|
}
|
|
4660
4727
|
break;
|
|
@@ -4663,6 +4730,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4663
4730
|
case A_TypeGuards.isFragmentConstructor(param1): {
|
|
4664
4731
|
if (!this.allowedFragments.has(param1)) {
|
|
4665
4732
|
this.allowedFragments.add(param1);
|
|
4733
|
+
A_Context.indexConstructor(param1);
|
|
4666
4734
|
this.bumpVersion();
|
|
4667
4735
|
}
|
|
4668
4736
|
break;
|
|
@@ -4671,6 +4739,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4671
4739
|
case A_TypeGuards.isEntityConstructor(param1): {
|
|
4672
4740
|
if (!this.allowedEntities.has(param1)) {
|
|
4673
4741
|
this.allowedEntities.add(param1);
|
|
4742
|
+
A_Context.indexConstructor(param1);
|
|
4674
4743
|
this.bumpVersion();
|
|
4675
4744
|
}
|
|
4676
4745
|
break;
|
|
@@ -4679,6 +4748,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4679
4748
|
case A_TypeGuards.isErrorConstructor(param1): {
|
|
4680
4749
|
if (!this.allowedErrors.has(param1)) {
|
|
4681
4750
|
this.allowedErrors.add(param1);
|
|
4751
|
+
A_Context.indexConstructor(param1);
|
|
4682
4752
|
this.bumpVersion();
|
|
4683
4753
|
}
|
|
4684
4754
|
break;
|
|
@@ -4772,7 +4842,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4772
4842
|
case A_TypeGuards.isFragmentConstructor(param1): {
|
|
4773
4843
|
this.allowedFragments.delete(param1);
|
|
4774
4844
|
Array.from(this._fragments.entries()).forEach(([ctor, instance]) => {
|
|
4775
|
-
if (
|
|
4845
|
+
if (A_Context.isIndexedInheritedFrom(ctor, param1)) {
|
|
4776
4846
|
this._fragments.delete(ctor);
|
|
4777
4847
|
A_Context.deregister(instance);
|
|
4778
4848
|
}
|
|
@@ -4784,7 +4854,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4784
4854
|
case A_TypeGuards.isEntityConstructor(param1): {
|
|
4785
4855
|
this.allowedEntities.delete(param1);
|
|
4786
4856
|
Array.from(this._entities.entries()).forEach(([aseid, instance]) => {
|
|
4787
|
-
if (
|
|
4857
|
+
if (A_Context.isIndexedInheritedFrom(instance.constructor, param1)) {
|
|
4788
4858
|
this._entities.delete(aseid);
|
|
4789
4859
|
A_Context.deregister(instance);
|
|
4790
4860
|
}
|
|
@@ -4796,7 +4866,7 @@ var _A_Scope = class _A_Scope {
|
|
|
4796
4866
|
case A_TypeGuards.isErrorConstructor(param1): {
|
|
4797
4867
|
this.allowedErrors.delete(param1);
|
|
4798
4868
|
Array.from(this._errors.entries()).forEach(([code, instance]) => {
|
|
4799
|
-
if (
|
|
4869
|
+
if (A_Context.isIndexedInheritedFrom(instance.constructor, param1)) {
|
|
4800
4870
|
this._errors.delete(code);
|
|
4801
4871
|
A_Context.deregister(instance);
|
|
4802
4872
|
}
|
|
@@ -4922,11 +4992,6 @@ var _A_Scope = class _A_Scope {
|
|
|
4922
4992
|
console.log(chain.join(" -> "));
|
|
4923
4993
|
}
|
|
4924
4994
|
};
|
|
4925
|
-
/**
|
|
4926
|
-
* Auto-incrementing counter for generating unique scope IDs.
|
|
4927
|
-
*/
|
|
4928
|
-
_A_Scope._nextUid = 0;
|
|
4929
|
-
var A_Scope = _A_Scope;
|
|
4930
4995
|
|
|
4931
4996
|
// src/lib/A-Scope/A-Scope.error.ts
|
|
4932
4997
|
var A_ScopeError = class extends A_Error {
|
|
@@ -5001,7 +5066,20 @@ var _A_Context = class _A_Context {
|
|
|
5001
5066
|
* Key format: `${featureName}::${componentConstructorName}::${scopeVersion}::${metaVersion}`
|
|
5002
5067
|
* Automatically invalidated when scope version or meta version changes.
|
|
5003
5068
|
*/
|
|
5004
|
-
this.
|
|
5069
|
+
this._featureCache = /* @__PURE__ */ new Map();
|
|
5070
|
+
// ====================================================================================================
|
|
5071
|
+
// ================================ INHERITANCE INDEX ==================================================
|
|
5072
|
+
// ====================================================================================================
|
|
5073
|
+
/**
|
|
5074
|
+
* For each indexed constructor, stores the set of all its ancestor constructors
|
|
5075
|
+
* (walking up the prototype chain). Enables O(1) isInheritedFrom checks.
|
|
5076
|
+
*/
|
|
5077
|
+
this._ancestors = /* @__PURE__ */ new Map();
|
|
5078
|
+
/**
|
|
5079
|
+
* For each constructor, stores the set of all known descendant constructors.
|
|
5080
|
+
* Enables O(1) "find a descendant in a Set" lookups.
|
|
5081
|
+
*/
|
|
5082
|
+
this._descendants = /* @__PURE__ */ new Map();
|
|
5005
5083
|
this._globals = /* @__PURE__ */ new Map();
|
|
5006
5084
|
const name = String(A_CONCEPT_ENV.A_CONCEPT_ROOT_SCOPE) || "root";
|
|
5007
5085
|
this._root = new A_Scope({ name });
|
|
@@ -5077,17 +5155,18 @@ var _A_Context = class _A_Context {
|
|
|
5077
5155
|
* @param component - Component to deregister from the context.
|
|
5078
5156
|
*/
|
|
5079
5157
|
static deregister(component) {
|
|
5080
|
-
const componentName = A_CommonHelper.getComponentName(component);
|
|
5081
|
-
const instance = this.getInstance();
|
|
5082
5158
|
if (!component) throw new A_ContextError(
|
|
5083
5159
|
A_ContextError.InvalidDeregisterParameterError,
|
|
5084
5160
|
`Unable to deregister component. Component cannot be null or undefined.`
|
|
5085
5161
|
);
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5162
|
+
const instance = this.getInstance();
|
|
5163
|
+
if (!instance._scopeStorage.delete(component)) {
|
|
5164
|
+
const componentName = A_CommonHelper.getComponentName(component);
|
|
5165
|
+
throw new A_ContextError(
|
|
5166
|
+
A_ContextError.ComponentNotRegisteredError,
|
|
5167
|
+
`Unable to deregister component. Component ${componentName} is not registered.`
|
|
5168
|
+
);
|
|
5169
|
+
}
|
|
5091
5170
|
}
|
|
5092
5171
|
static allocate(component, importing) {
|
|
5093
5172
|
const componentName = A_CommonHelper.getComponentName(component);
|
|
@@ -5206,6 +5285,7 @@ var _A_Context = class _A_Context {
|
|
|
5206
5285
|
inheritedMeta = new metaType();
|
|
5207
5286
|
instance._metaStorage.set(property, inheritedMeta.clone());
|
|
5208
5287
|
instance._metaVersion++;
|
|
5288
|
+
this.indexConstructor(property);
|
|
5209
5289
|
}
|
|
5210
5290
|
return instance._metaStorage.get(property);
|
|
5211
5291
|
}
|
|
@@ -5274,12 +5354,22 @@ var _A_Context = class _A_Context {
|
|
|
5274
5354
|
if (!name) throw new A_ContextError(A_ContextError.InvalidFeatureTemplateParameterError, `Unable to get feature template. Feature name cannot be null or undefined.`);
|
|
5275
5355
|
if (!A_TypeGuards.isAllowedForFeatureDefinition(component))
|
|
5276
5356
|
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.`);
|
|
5357
|
+
const instance = this.getInstance();
|
|
5358
|
+
const cacheKey = `${String(name)}::${A_CommonHelper.getComponentName(component)}::s${scope.fingerprint}::m${instance._metaVersion}`;
|
|
5359
|
+
const cached = instance._featureCache.get(cacheKey);
|
|
5360
|
+
if (cached) {
|
|
5361
|
+
return cached;
|
|
5362
|
+
}
|
|
5277
5363
|
const steps = [
|
|
5278
5364
|
// 1) Get the base feature definition from the component
|
|
5279
5365
|
...this.featureDefinition(name, component),
|
|
5280
5366
|
// 2) Get all extensions for the feature from other components in the scope
|
|
5281
5367
|
...this.featureExtensions(name, component, scope)
|
|
5282
5368
|
];
|
|
5369
|
+
if (instance._featureCache.size >= _A_Context.FEATURE_EXTENSIONS_CACHE_MAX_SIZE) {
|
|
5370
|
+
instance._featureCache.clear();
|
|
5371
|
+
}
|
|
5372
|
+
instance._featureCache.set(cacheKey, steps);
|
|
5283
5373
|
return steps;
|
|
5284
5374
|
}
|
|
5285
5375
|
// ----------------------------------------------------------------------------------------------------------
|
|
@@ -5300,13 +5390,6 @@ var _A_Context = class _A_Context {
|
|
|
5300
5390
|
if (!name) throw new A_ContextError(A_ContextError.InvalidFeatureExtensionParameterError, `Unable to get feature template. Feature name cannot be null or undefined.`);
|
|
5301
5391
|
if (!A_TypeGuards.isAllowedForFeatureDefinition(component))
|
|
5302
5392
|
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.`);
|
|
5303
|
-
const componentCtor = typeof component === "function" ? component : component.constructor;
|
|
5304
|
-
const effectiveScope = scope.parent || scope;
|
|
5305
|
-
const cacheKey = `${String(name)}::${componentCtor.name}::s${effectiveScope.uid}v${effectiveScope.version}::m${instance._metaVersion}`;
|
|
5306
|
-
const cached = instance._featureExtensionsCache.get(cacheKey);
|
|
5307
|
-
if (cached) {
|
|
5308
|
-
return cached;
|
|
5309
|
-
}
|
|
5310
5393
|
const callNames = A_CommonHelper.getClassInheritanceChain(component).filter((c) => c !== A_Component && c !== A_Container && c !== A_Entity).map((c) => `${c.name}.${name}`);
|
|
5311
5394
|
const steps = /* @__PURE__ */ new Map();
|
|
5312
5395
|
const allowedComponents = /* @__PURE__ */ new Set();
|
|
@@ -5340,7 +5423,7 @@ var _A_Context = class _A_Context {
|
|
|
5340
5423
|
const extensions = meta.extensions(callName);
|
|
5341
5424
|
for (let i = 0; i < extensions.length; i++) {
|
|
5342
5425
|
const declaration = extensions[i];
|
|
5343
|
-
const inherited = Array.from(allowedComponents).reverse().find((c) =>
|
|
5426
|
+
const inherited = Array.from(allowedComponents).reverse().find((c) => _A_Context.isIndexedInheritedFrom(cmp, c) && c !== cmp);
|
|
5344
5427
|
if (inherited) {
|
|
5345
5428
|
steps.delete(`${getNameCached(inherited)}.${declaration.handler}`);
|
|
5346
5429
|
}
|
|
@@ -5360,10 +5443,6 @@ var _A_Context = class _A_Context {
|
|
|
5360
5443
|
}
|
|
5361
5444
|
}
|
|
5362
5445
|
const result = instance.filterToMostDerived(scope, Array.from(steps.values()));
|
|
5363
|
-
if (instance._featureExtensionsCache.size >= _A_Context.FEATURE_EXTENSIONS_CACHE_MAX_SIZE) {
|
|
5364
|
-
instance._featureExtensionsCache.clear();
|
|
5365
|
-
}
|
|
5366
|
-
instance._featureExtensionsCache.set(cacheKey, result);
|
|
5367
5446
|
return result;
|
|
5368
5447
|
}
|
|
5369
5448
|
/**
|
|
@@ -5395,14 +5474,14 @@ var _A_Context = class _A_Context {
|
|
|
5395
5474
|
}
|
|
5396
5475
|
for (const [depName, ctor] of resolvedClasses) {
|
|
5397
5476
|
if (!ctor) continue;
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
const
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5477
|
+
const ancestors = _A_Context.getAncestors(ctor);
|
|
5478
|
+
if (ancestors) {
|
|
5479
|
+
for (const ancestor of ancestors) {
|
|
5480
|
+
const ancestorName = ctorToName.get(ancestor);
|
|
5481
|
+
if (ancestorName && ancestorName !== depName && presentNames.has(ancestorName)) {
|
|
5482
|
+
parentNames.add(ancestorName);
|
|
5483
|
+
}
|
|
5404
5484
|
}
|
|
5405
|
-
ancestor = Object.getPrototypeOf(ancestor);
|
|
5406
5485
|
}
|
|
5407
5486
|
}
|
|
5408
5487
|
return items.filter((item) => !parentNames.has(item.dependency.name));
|
|
@@ -5501,7 +5580,7 @@ var _A_Context = class _A_Context {
|
|
|
5501
5580
|
if (scope.has(cmp) && (A_TypeGuards.isComponentMetaInstance(meta) || A_TypeGuards.isContainerMetaInstance(meta))) {
|
|
5502
5581
|
allowedComponents.add(cmp);
|
|
5503
5582
|
meta.abstractions(abstraction).forEach((declaration) => {
|
|
5504
|
-
const inherited = Array.from(allowedComponents).reverse().find((c) =>
|
|
5583
|
+
const inherited = Array.from(allowedComponents).reverse().find((c) => _A_Context.isIndexedInheritedFrom(cmp, c) && c !== cmp);
|
|
5505
5584
|
if (inherited) {
|
|
5506
5585
|
steps.delete(`${A_CommonHelper.getComponentName(inherited)}.${declaration.handler}`);
|
|
5507
5586
|
}
|
|
@@ -5520,12 +5599,132 @@ var _A_Context = class _A_Context {
|
|
|
5520
5599
|
static reset() {
|
|
5521
5600
|
const instance = _A_Context.getInstance();
|
|
5522
5601
|
instance._registry = /* @__PURE__ */ new WeakMap();
|
|
5523
|
-
instance.
|
|
5602
|
+
instance._featureCache.clear();
|
|
5603
|
+
instance._ancestors.clear();
|
|
5604
|
+
instance._descendants.clear();
|
|
5524
5605
|
instance._metaVersion++;
|
|
5525
5606
|
const name = String(A_CONCEPT_ENV.A_CONCEPT_ROOT_SCOPE) || "root";
|
|
5526
5607
|
instance._root = new A_Scope({ name });
|
|
5527
5608
|
}
|
|
5528
5609
|
// ====================================================================================================================
|
|
5610
|
+
// ====================================== INHERITANCE INDEX ============================================================
|
|
5611
|
+
// ====================================================================================================================
|
|
5612
|
+
/**
|
|
5613
|
+
* Index a constructor's full prototype chain into the inheritance graph.
|
|
5614
|
+
* Safe to call multiple times for the same constructor — it's a no-op if already indexed.
|
|
5615
|
+
*
|
|
5616
|
+
* After indexing, `A_Context.isIndexedInheritedFrom(child, parent)` becomes O(1).
|
|
5617
|
+
*/
|
|
5618
|
+
static indexConstructor(ctor) {
|
|
5619
|
+
const instance = this.getInstance();
|
|
5620
|
+
if (instance._ancestors.has(ctor)) return;
|
|
5621
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
5622
|
+
let current = Object.getPrototypeOf(ctor);
|
|
5623
|
+
while (current && current !== Function.prototype && current !== Object) {
|
|
5624
|
+
ancestors.add(current);
|
|
5625
|
+
let desc = instance._descendants.get(current);
|
|
5626
|
+
if (!desc) {
|
|
5627
|
+
desc = /* @__PURE__ */ new Set();
|
|
5628
|
+
instance._descendants.set(current, desc);
|
|
5629
|
+
}
|
|
5630
|
+
desc.add(ctor);
|
|
5631
|
+
const existingAncestors = instance._ancestors.get(current);
|
|
5632
|
+
if (existingAncestors) {
|
|
5633
|
+
for (const a of existingAncestors) {
|
|
5634
|
+
ancestors.add(a);
|
|
5635
|
+
let desc2 = instance._descendants.get(a);
|
|
5636
|
+
if (!desc2) {
|
|
5637
|
+
desc2 = /* @__PURE__ */ new Set();
|
|
5638
|
+
instance._descendants.set(a, desc2);
|
|
5639
|
+
}
|
|
5640
|
+
desc2.add(ctor);
|
|
5641
|
+
}
|
|
5642
|
+
break;
|
|
5643
|
+
}
|
|
5644
|
+
current = Object.getPrototypeOf(current);
|
|
5645
|
+
}
|
|
5646
|
+
instance._ancestors.set(ctor, ancestors);
|
|
5647
|
+
if (!instance._descendants.has(ctor)) {
|
|
5648
|
+
instance._descendants.set(ctor, /* @__PURE__ */ new Set());
|
|
5649
|
+
}
|
|
5650
|
+
}
|
|
5651
|
+
/**
|
|
5652
|
+
* O(1) check whether `child` inherits from `parent` using the pre-built index.
|
|
5653
|
+
* Falls back to prototype chain walking if either is not yet indexed.
|
|
5654
|
+
*
|
|
5655
|
+
* [!] Handles the same-class case: returns true if child === parent.
|
|
5656
|
+
*/
|
|
5657
|
+
static isIndexedInheritedFrom(child, parent) {
|
|
5658
|
+
if (child === parent) return true;
|
|
5659
|
+
const instance = this.getInstance();
|
|
5660
|
+
const ancestors = instance._ancestors.get(child);
|
|
5661
|
+
if (ancestors) return ancestors.has(parent);
|
|
5662
|
+
return A_CommonHelper.isInheritedFrom(child, parent);
|
|
5663
|
+
}
|
|
5664
|
+
/**
|
|
5665
|
+
* Find the first constructor in `candidates` that is a descendant of (or equal to) `parent`.
|
|
5666
|
+
* Returns undefined if none found.
|
|
5667
|
+
*
|
|
5668
|
+
* Uses the optimal strategy based on set sizes:
|
|
5669
|
+
* - If candidates is small, iterates candidates and checks ancestry (O(c))
|
|
5670
|
+
* - If descendants is small, iterates descendants and checks membership (O(d))
|
|
5671
|
+
*/
|
|
5672
|
+
static findDescendantIn(parent, candidates) {
|
|
5673
|
+
const candidateSize = candidates instanceof Set ? candidates.size : candidates.length;
|
|
5674
|
+
if (candidates instanceof Set) {
|
|
5675
|
+
if (candidates.has(parent)) return parent;
|
|
5676
|
+
} else {
|
|
5677
|
+
if (candidates.includes(parent)) return parent;
|
|
5678
|
+
}
|
|
5679
|
+
const instance = this.getInstance();
|
|
5680
|
+
const descendants = instance._descendants.get(parent);
|
|
5681
|
+
const descendantSize = descendants ? descendants.size : 0;
|
|
5682
|
+
if (descendantSize === 0) {
|
|
5683
|
+
if (candidates instanceof Set) {
|
|
5684
|
+
for (const c of candidates) {
|
|
5685
|
+
const ancestors = instance._ancestors.get(c);
|
|
5686
|
+
if (ancestors && ancestors.has(parent)) return c;
|
|
5687
|
+
}
|
|
5688
|
+
} else {
|
|
5689
|
+
for (const c of candidates) {
|
|
5690
|
+
const ancestors = instance._ancestors.get(c);
|
|
5691
|
+
if (ancestors && ancestors.has(parent)) return c;
|
|
5692
|
+
}
|
|
5693
|
+
}
|
|
5694
|
+
return void 0;
|
|
5695
|
+
}
|
|
5696
|
+
if (candidateSize <= descendantSize) {
|
|
5697
|
+
if (candidates instanceof Set) {
|
|
5698
|
+
for (const c of candidates) {
|
|
5699
|
+
if (c === parent) return c;
|
|
5700
|
+
const ancestors = instance._ancestors.get(c);
|
|
5701
|
+
if (ancestors && ancestors.has(parent)) return c;
|
|
5702
|
+
}
|
|
5703
|
+
} else {
|
|
5704
|
+
for (const c of candidates) {
|
|
5705
|
+
if (c === parent) return c;
|
|
5706
|
+
const ancestors = instance._ancestors.get(c);
|
|
5707
|
+
if (ancestors && ancestors.has(parent)) return c;
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
} else {
|
|
5711
|
+
for (const desc of descendants) {
|
|
5712
|
+
if (candidates instanceof Set) {
|
|
5713
|
+
if (candidates.has(desc)) return desc;
|
|
5714
|
+
} else {
|
|
5715
|
+
if (candidates.includes(desc)) return desc;
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5718
|
+
}
|
|
5719
|
+
return void 0;
|
|
5720
|
+
}
|
|
5721
|
+
/**
|
|
5722
|
+
* Returns the set of indexed ancestors for a constructor, or undefined if not indexed.
|
|
5723
|
+
*/
|
|
5724
|
+
static getAncestors(ctor) {
|
|
5725
|
+
return this.getInstance()._ancestors.get(ctor);
|
|
5726
|
+
}
|
|
5727
|
+
// ====================================================================================================================
|
|
5529
5728
|
// ====================================== HELPERS & GUARDS ============================================================
|
|
5530
5729
|
// ====================================================================================================================
|
|
5531
5730
|
/**
|