@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.
@@ -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 stages = Array.from(this);
3433
- return this.processStagesSequentially(stages, scope, 0);
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
- * Process stages one by one, ensuring each stage completes before starting the next
3462
+ * Async continuation processes remaining stages after the first async pivot.
3463
+ * Resumes from the current iterator position (this._index).
3445
3464
  */
3446
- processStagesSequentially(stages, scope, index) {
3447
- while (index < stages.length) {
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 _A_Scope = class _A_Scope {
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) || !![...this.allowedComponents].find((c) => A_CommonHelper.isInheritedFrom(c, 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) || !![...this.allowedEntities].find((e) => A_CommonHelper.isInheritedFrom(e, 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) || !![...this.allowedFragments].find((f) => A_CommonHelper.isInheritedFrom(f, 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) || !![...this.allowedErrors].find((e) => A_CommonHelper.isInheritedFrom(e, 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 || A_CommonHelper.isInheritedFrom(
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 Array.from(this.allowedComponents).find((c) => A_CommonHelper.isInheritedFrom(c, name));
4291
+ return A_Context.findDescendantIn(name, this.allowedComponents);
4240
4292
  case A_TypeGuards.isEntityConstructor(name):
4241
- return Array.from(this.allowedEntities).find((e) => A_CommonHelper.isInheritedFrom(e, name));
4293
+ return A_Context.findDescendantIn(name, this.allowedEntities);
4242
4294
  case A_TypeGuards.isFragmentConstructor(name):
4243
- return Array.from(this.allowedFragments).find((f) => A_CommonHelper.isInheritedFrom(f, name));
4295
+ return A_Context.findDescendantIn(name, this.allowedFragments);
4244
4296
  case A_TypeGuards.isErrorConstructor(name):
4245
- return Array.from(this.allowedErrors).find((e) => A_CommonHelper.isInheritedFrom(e, name));
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 protoComponent = Array.from(this.allowedComponents).find(
4272
- // it should go rthough prototyopes and check their names to be equal to the provided name
4273
- (c) => {
4274
- let current = c;
4275
- while (current) {
4276
- if (current.name === name || current.name === A_FormatterHelper.toPascalCase(name)) {
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 protoEntity = Array.from(this.allowedEntities).find(
4292
- (e) => A_CommonHelper.isInheritedFrom(e, name)
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 protoFragment = Array.from(this.allowedFragments).find(
4302
- (f) => A_CommonHelper.isInheritedFrom(f, name)
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 (A_CommonHelper.isInheritedFrom(ctor, param1)) {
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 (A_CommonHelper.isInheritedFrom(ctor, param1)) {
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 (A_CommonHelper.isInheritedFrom(entity.constructor, param1)) {
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 || A_CommonHelper.isInheritedFrom(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 component that is inherited from the required component
4550
- case (!fragmentInstancePresented && Array.from(this._allowedFragments).some((el) => A_CommonHelper.isInheritedFrom(el, fragment))): {
4551
- const found = Array.from(this._allowedFragments).find((el) => A_CommonHelper.isInheritedFrom(el, fragment));
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 (!this.allowedComponents.has(component) && Array.from(this.allowedComponents).some((el) => A_CommonHelper.isInheritedFrom(el, component))): {
4592
- const found = Array.from(this.allowedComponents).find((el) => A_CommonHelper.isInheritedFrom(el, component));
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 (A_CommonHelper.isInheritedFrom(ctor, param1)) {
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 (A_CommonHelper.isInheritedFrom(instance.constructor, param1)) {
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 (A_CommonHelper.isInheritedFrom(instance.constructor, param1)) {
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._featureExtensionsCache = /* @__PURE__ */ new Map();
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
- if (!instance._scopeStorage.has(component)) throw new A_ContextError(
5085
- A_ContextError.ComponentNotRegisteredError,
5086
- `Unable to deregister component. Component ${componentName} is not registered.`
5087
- );
5088
- instance._scopeStorage.delete(component);
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) => A_CommonHelper.isInheritedFrom(cmp, c) && c !== cmp);
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
- 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);
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) => A_CommonHelper.isInheritedFrom(cmp, c) && c !== cmp);
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._featureExtensionsCache.clear();
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
  /**