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