@adaas/a-concept 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,465 @@
1
+ /**
2
+ * ============================================================
3
+ * A_Feature Chaining Performance Benchmarks
4
+ * ============================================================
5
+ *
6
+ * Measures realistic end-to-end performance of feature chaining:
7
+ * - Entity creation + scope allocation
8
+ * - Scope registration overhead
9
+ * - Feature invocation through entity.call()
10
+ * - Feature chaining between components (chain())
11
+ * - Dependency injection overhead (@A_Inject)
12
+ * - Scaling with chain depth and component count
13
+ * - Full realistic pipeline: entity → scope → feature → chain → DI
14
+ */
15
+ import { A_Component } from "@adaas/a-concept/a-component";
16
+ import { A_Feature } from "@adaas/a-concept/a-feature";
17
+ import { A_Scope } from "@adaas/a-concept/a-scope";
18
+ import { A_Inject } from "@adaas/a-concept/a-inject";
19
+ import { A_Caller } from "@adaas/a-concept/a-caller";
20
+ import { A_Entity } from "@adaas/a-concept/a-entity";
21
+ import { A_Context } from "@adaas/a-concept/a-context";
22
+ import { createSuite, BenchResult, printSummary } from './helpers';
23
+
24
+
25
+ // ──────────────────────────────────────────────────────────────
26
+ // Fixture: Entities
27
+ // ──────────────────────────────────────────────────────────────
28
+
29
+ class BenchEntity extends A_Entity {
30
+ protected _scope!: A_Scope;
31
+
32
+ get scope(): A_Scope {
33
+ if (!this._scope) {
34
+ this._scope = A_Context.allocate(this, new A_Scope({ name: `${this.aseid.id}-scope` }));
35
+ }
36
+ return this._scope;
37
+ }
38
+
39
+ get targetComponent() {
40
+ return this.scope.resolve(TargetComponent)!;
41
+ }
42
+
43
+ invokeFeature() {
44
+ return this.call('entityFeature');
45
+ }
46
+ }
47
+
48
+
49
+ // ──────────────────────────────────────────────────────────────
50
+ // Fixture: Components — Simple feature (no chaining baseline)
51
+ // ──────────────────────────────────────────────────────────────
52
+
53
+ class SimpleComponent extends A_Component {
54
+ counter: number = 0;
55
+
56
+ @A_Feature.Define({ invoke: true })
57
+ @A_Feature.Extend({ name: 'simpleFeature' })
58
+ simpleMethod() {
59
+ this.counter++;
60
+ }
61
+ }
62
+
63
+
64
+ // ──────────────────────────────────────────────────────────────
65
+ // Fixture: Components — Single chain (A → B)
66
+ // ──────────────────────────────────────────────────────────────
67
+
68
+ class TargetComponent extends A_Component {
69
+ executed: boolean = false;
70
+
71
+ @A_Feature.Define({ invoke: true })
72
+ @A_Feature.Extend({ name: 'targetFeature' })
73
+ targetStep() {
74
+ this.executed = true;
75
+ }
76
+ }
77
+
78
+ class ChainingComponent extends A_Component {
79
+ @A_Feature.Define({ invoke: false })
80
+ @A_Feature.Extend({ name: 'chainedFeature' })
81
+ chainStep(
82
+ @A_Inject(A_Caller) caller: A_Component,
83
+ @A_Inject(A_Scope) scope: A_Scope,
84
+ @A_Inject(A_Feature) feature: A_Feature
85
+ ) {
86
+ const target = scope.resolve(TargetComponent)!;
87
+ feature.chain(target, 'targetFeature', scope);
88
+ }
89
+ }
90
+
91
+
92
+ // ──────────────────────────────────────────────────────────────
93
+ // Fixture: Components — Multi-chain (A → B → C)
94
+ // ──────────────────────────────────────────────────────────────
95
+
96
+ class FinalComponent extends A_Component {
97
+ @A_Feature.Define({ invoke: true })
98
+ @A_Feature.Extend({ name: 'finalFeature' })
99
+ finalStep() { }
100
+ }
101
+
102
+ class MiddleComponent extends A_Component {
103
+ @A_Feature.Define({ invoke: false })
104
+ @A_Feature.Extend({ name: 'middleFeature' })
105
+ middleStep(
106
+ @A_Inject(A_Scope) scope: A_Scope,
107
+ @A_Inject(A_Feature) feature: A_Feature
108
+ ) {
109
+ const final = scope.resolve(FinalComponent)!;
110
+ feature.chain(final, 'finalFeature', scope);
111
+ }
112
+ }
113
+
114
+ class EntryComponent extends A_Component {
115
+ @A_Feature.Define({ invoke: false })
116
+ @A_Feature.Extend({ name: 'entryFeature' })
117
+ entryStep(
118
+ @A_Inject(A_Scope) scope: A_Scope,
119
+ @A_Inject(A_Feature) feature: A_Feature
120
+ ) {
121
+ const middle = scope.resolve(MiddleComponent)!;
122
+ feature.chain(middle, 'middleFeature', scope);
123
+ }
124
+ }
125
+
126
+
127
+ // ──────────────────────────────────────────────────────────────
128
+ // Fixture: Components — Feature with multiple DI parameters
129
+ // ──────────────────────────────────────────────────────────────
130
+
131
+ class ServiceComponentA extends A_Component {
132
+ getValue() { return 42; }
133
+ }
134
+
135
+ class ServiceComponentB extends A_Component {
136
+ getLabel() { return 'bench'; }
137
+ }
138
+
139
+ class HeavyDIComponent extends A_Component {
140
+ @A_Feature.Define({ invoke: true })
141
+ @A_Feature.Extend({ name: 'heavyDIFeature' })
142
+ heavyStep(
143
+ @A_Inject(A_Caller) caller: A_Component,
144
+ @A_Inject(A_Scope) scope: A_Scope,
145
+ @A_Inject(A_Feature) feature: A_Feature,
146
+ @A_Inject(ServiceComponentA) svcA: ServiceComponentA,
147
+ @A_Inject(ServiceComponentB) svcB: ServiceComponentB,
148
+ ) {
149
+ svcA.getValue();
150
+ svcB.getLabel();
151
+ }
152
+ }
153
+
154
+
155
+ // ──────────────────────────────────────────────────────────────
156
+ // Fixture: Components — Multiple extensions converging + chain
157
+ // ──────────────────────────────────────────────────────────────
158
+
159
+ class ExtStepA extends A_Component {
160
+ @A_Feature.Extend({ name: 'convergentFeature' })
161
+ stepA() { }
162
+ }
163
+
164
+ class ExtStepB extends A_Component {
165
+ @A_Feature.Extend({ name: 'convergentFeature' })
166
+ stepB() { }
167
+ }
168
+
169
+ class ExtStepC extends A_Component {
170
+ @A_Feature.Extend({ name: 'convergentFeature' })
171
+ stepC() { }
172
+ }
173
+
174
+ class ConvergentComponent extends A_Component {
175
+ @A_Feature.Define({ invoke: false })
176
+ @A_Feature.Extend({ name: 'convergentFeature' })
177
+ convergentStep(
178
+ @A_Inject(A_Scope) scope: A_Scope,
179
+ @A_Inject(A_Feature) feature: A_Feature
180
+ ) {
181
+ const target = scope.resolve(TargetComponent)!;
182
+ feature.chain(target, 'targetFeature', scope);
183
+ }
184
+ }
185
+
186
+
187
+ // ──────────────────────────────────────────────────────────────
188
+ // Fixture: Entity-driven feature chaining
189
+ // ──────────────────────────────────────────────────────────────
190
+
191
+ class EntityFeatureComponent extends A_Component {
192
+ @A_Feature.Extend({
193
+ name: 'entityFeature',
194
+ scope: [BenchEntity]
195
+ })
196
+ entityStep(
197
+ @A_Inject(A_Caller) entity: BenchEntity,
198
+ @A_Inject(A_Scope) scope: A_Scope,
199
+ @A_Inject(A_Feature) feature: A_Feature
200
+ ) {
201
+ const target = entity.scope.resolve(TargetComponent);
202
+ if (target) {
203
+ feature.chain(target, 'targetFeature', scope);
204
+ }
205
+ }
206
+ }
207
+
208
+
209
+ // ──────────────────────────────────────────────────────────────
210
+ // Benchmark Suites
211
+ // ──────────────────────────────────────────────────────────────
212
+
213
+ export async function runFeatureChainingBenchmarks(): Promise<BenchResult[]> {
214
+ const allResults: BenchResult[] = [];
215
+
216
+ // ── Suite 1: Entity + Scope Allocation ──────────────────
217
+ const entityResults = await createSuite('Entity & Scope — Allocation', (suite) => {
218
+ suite
219
+ .add('new A_Entity()', () => {
220
+ new BenchEntity();
221
+ })
222
+ .add('new A_Scope (empty)', () => {
223
+ new A_Scope({ name: 'empty' });
224
+ })
225
+ .add('new A_Scope (3 components)', () => {
226
+ new A_Scope({
227
+ name: 'with-components',
228
+ components: [SimpleComponent, TargetComponent, ChainingComponent]
229
+ });
230
+ })
231
+ .add('new A_Scope (5 components)', () => {
232
+ new A_Scope({
233
+ name: 'with-5-components',
234
+ components: [SimpleComponent, TargetComponent, ChainingComponent, ServiceComponentA, ServiceComponentB]
235
+ });
236
+ })
237
+ .add('A_Context.allocate + deallocate', () => {
238
+ const entity = new BenchEntity();
239
+ A_Context.allocate(entity, new A_Scope({ name: 'alloc-bench' }));
240
+ A_Context.deallocate(entity);
241
+ });
242
+ });
243
+ allResults.push(...entityResults);
244
+
245
+ // ── Suite 2: Scope Registration & Resolution ────────────
246
+ const regResults = await createSuite('Scope — Registration & Resolution', (suite) => {
247
+ suite
248
+ .add('register entity into scope', () => {
249
+ const scope = new A_Scope({ name: 'reg-bench', components: [TargetComponent] });
250
+ const entity = new BenchEntity();
251
+ scope.register(entity);
252
+ })
253
+ .add('resolve component — flat scope', () => {
254
+ const scope = new A_Scope({
255
+ name: 'resolve-bench',
256
+ components: [SimpleComponent, TargetComponent, ChainingComponent]
257
+ });
258
+ scope.resolve(TargetComponent);
259
+ })
260
+ .add('resolve component — nested 2 levels', () => {
261
+ const parent = new A_Scope({ name: 'parent', components: [TargetComponent] });
262
+ const child = new A_Scope({ name: 'child', components: [SimpleComponent] });
263
+ child.inherit(parent);
264
+ child.resolve(TargetComponent);
265
+ })
266
+ .add('resolve component — nested 3 levels', () => {
267
+ const grandparent = new A_Scope({ name: 'gp', components: [TargetComponent] });
268
+ const parent = new A_Scope({ name: 'p', components: [ChainingComponent] });
269
+ const child = new A_Scope({ name: 'c', components: [SimpleComponent] });
270
+ parent.inherit(grandparent);
271
+ child.inherit(parent);
272
+ child.resolve(TargetComponent);
273
+ });
274
+ });
275
+ allResults.push(...regResults);
276
+
277
+ // ── Suite 3: Feature Call — Baseline (no chain) ─────────
278
+ const baselineResults = await createSuite('Feature Call — Baseline (no chain)', (suite) => {
279
+ const scope1 = new A_Scope({ name: 'base-1', components: [SimpleComponent] });
280
+ const comp1 = scope1.resolve(SimpleComponent)!;
281
+
282
+ const scope3 = new A_Scope({
283
+ name: 'base-3',
284
+ components: [SimpleComponent, TargetComponent, ChainingComponent]
285
+ });
286
+ const comp3 = scope3.resolve(SimpleComponent)!;
287
+
288
+ suite
289
+ .add('component.call (1 component in scope)', () => {
290
+ comp1.call('simpleFeature');
291
+ })
292
+ .add('component.call (3 components in scope)', () => {
293
+ comp3.call('simpleFeature');
294
+ });
295
+ });
296
+ allResults.push(...baselineResults);
297
+
298
+ // ── Suite 4: Feature Chaining — Single Chain (A → B) ────
299
+ const singleChainResults = await createSuite('Feature Chaining — Single (A → B)', (suite) => {
300
+ const scope = new A_Scope({
301
+ name: 'single-chain',
302
+ components: [ChainingComponent, TargetComponent]
303
+ });
304
+ const chaining = scope.resolve(ChainingComponent)!;
305
+
306
+ suite
307
+ .add('chain: A → B (resolve + chain + execute)', () => {
308
+ chaining.call('chainedFeature');
309
+ });
310
+ });
311
+ allResults.push(...singleChainResults);
312
+
313
+ // ── Suite 5: Feature Chaining — Double Chain (A → B → C)
314
+ const doubleChainResults = await createSuite('Feature Chaining — Double (A → B → C)', (suite) => {
315
+ const scope = new A_Scope({
316
+ name: 'double-chain',
317
+ components: [EntryComponent, MiddleComponent, FinalComponent]
318
+ });
319
+ const entry = scope.resolve(EntryComponent)!;
320
+
321
+ suite
322
+ .add('chain: A → B → C (2-hop)', () => {
323
+ entry.call('entryFeature');
324
+ });
325
+ });
326
+ allResults.push(...doubleChainResults);
327
+
328
+ // ── Suite 6: Dependency Injection Overhead ──────────────
329
+ const diResults = await createSuite('Dependency Injection — @A_Inject Cost', (suite) => {
330
+ // 0 DI params (baseline)
331
+ const scopeNoDI = new A_Scope({ name: 'no-di', components: [SimpleComponent] });
332
+ const compNoDI = scopeNoDI.resolve(SimpleComponent)!;
333
+
334
+ // 3 DI params (Caller, Scope, Feature) + chain
335
+ const scopeDI3 = new A_Scope({
336
+ name: 'di-3',
337
+ components: [ChainingComponent, TargetComponent]
338
+ });
339
+ const compDI3 = scopeDI3.resolve(ChainingComponent)!;
340
+
341
+ // 5 DI params (Caller, Scope, Feature, ServiceA, ServiceB)
342
+ const scopeDI5 = new A_Scope({
343
+ name: 'di-5',
344
+ components: [HeavyDIComponent, ServiceComponentA, ServiceComponentB]
345
+ });
346
+ const compDI5 = scopeDI5.resolve(HeavyDIComponent)!;
347
+
348
+ suite
349
+ .add('@A_Inject: 0 params (no DI)', () => {
350
+ compNoDI.call('simpleFeature');
351
+ })
352
+ .add('@A_Inject: 3 params (Caller+Scope+Feature)', () => {
353
+ compDI3.call('chainedFeature');
354
+ })
355
+ .add('@A_Inject: 5 params (Caller+Scope+Feature+2 svc)', () => {
356
+ compDI5.call('heavyDIFeature');
357
+ });
358
+ });
359
+ allResults.push(...diResults);
360
+
361
+ // ── Suite 7: Chain + Multiple Extensions ────────────────
362
+ const convergentResults = await createSuite('Chain + Extensions — Convergent Pipeline', (suite) => {
363
+ // Chain with 1 extension
364
+ const scope1 = new A_Scope({
365
+ name: 'conv-1',
366
+ components: [ConvergentComponent, TargetComponent, ExtStepA]
367
+ });
368
+ const conv1 = scope1.resolve(ConvergentComponent)!;
369
+
370
+ // Chain with 3 extensions
371
+ const scope3 = new A_Scope({
372
+ name: 'conv-3',
373
+ components: [ConvergentComponent, TargetComponent, ExtStepA, ExtStepB, ExtStepC]
374
+ });
375
+ const conv3 = scope3.resolve(ConvergentComponent)!;
376
+
377
+ suite
378
+ .add('chain + 1 extension step', () => {
379
+ conv1.call('convergentFeature');
380
+ })
381
+ .add('chain + 3 extension steps', () => {
382
+ conv3.call('convergentFeature');
383
+ });
384
+ });
385
+ allResults.push(...convergentResults);
386
+
387
+ // ── Suite 8: Entity-driven Full Pipeline ────────────────
388
+ const entityPipelineResults = await createSuite('Entity Pipeline — Full Realistic Flow', (suite) => {
389
+ // Warm entity (scope and components already allocated)
390
+ const rootScope = new A_Scope({
391
+ name: 'entity-root',
392
+ components: [EntityFeatureComponent, TargetComponent]
393
+ });
394
+ const warmEntity = new BenchEntity();
395
+ rootScope.register(warmEntity);
396
+
397
+ suite
398
+ .add('entity.call → DI → chain (warm)', () => {
399
+ warmEntity.invokeFeature();
400
+ })
401
+ .add('new entity + register + call + chain (cold)', () => {
402
+ const e = new BenchEntity();
403
+ const s = new A_Scope({
404
+ name: 'cold-scope',
405
+ components: [EntityFeatureComponent, TargetComponent]
406
+ });
407
+ s.register(e);
408
+ e.invokeFeature();
409
+ });
410
+ });
411
+ allResults.push(...entityPipelineResults);
412
+
413
+ // ── Suite 9: Scope Depth Impact on Chain Resolution ─────
414
+ const depthResults = await createSuite('Scope Depth — Impact on Chain Resolution', (suite) => {
415
+ // Flat: all in one scope
416
+ const flatScope = new A_Scope({
417
+ name: 'flat-all',
418
+ components: [ChainingComponent, TargetComponent]
419
+ });
420
+ const flatComp = flatScope.resolve(ChainingComponent)!;
421
+
422
+ // 2-level: target in parent
423
+ const parentScope2 = new A_Scope({ name: 'depth2-parent', components: [TargetComponent] });
424
+ const childScope2 = new A_Scope({ name: 'depth2-child', components: [ChainingComponent] });
425
+ childScope2.inherit(parentScope2);
426
+ const depth2Comp = childScope2.resolve(ChainingComponent)!;
427
+
428
+ // 3-level: target in grandparent
429
+ const gpScope = new A_Scope({ name: 'depth3-gp', components: [TargetComponent] });
430
+ const pScope = new A_Scope({ name: 'depth3-p', components: [] });
431
+ const cScope = new A_Scope({ name: 'depth3-c', components: [ChainingComponent] });
432
+ pScope.inherit(gpScope);
433
+ cScope.inherit(pScope);
434
+ const depth3Comp = cScope.resolve(ChainingComponent)!;
435
+
436
+ suite
437
+ .add('chain — flat scope (depth 0)', () => {
438
+ flatComp.call('chainedFeature');
439
+ })
440
+ .add('chain — nested scope (depth 2)', () => {
441
+ depth2Comp.call('chainedFeature');
442
+ })
443
+ .add('chain — nested scope (depth 3)', () => {
444
+ depth3Comp.call('chainedFeature');
445
+ });
446
+ });
447
+ allResults.push(...depthResults);
448
+
449
+ return allResults;
450
+ }
451
+
452
+
453
+ // ──────────────────────────────────────────────────────────────
454
+ // Standalone runner
455
+ // ──────────────────────────────────────────────────────────────
456
+ if (require.main === module) {
457
+ runFeatureChainingBenchmarks()
458
+ .then((results) => {
459
+ const summary = new Map<string, BenchResult[]>();
460
+ summary.set('FeatureChaining', results);
461
+ printSummary(summary);
462
+ console.log('\n✅ Feature chaining benchmarks completed.\n');
463
+ })
464
+ .catch(console.error);
465
+ }
@@ -0,0 +1,205 @@
1
+ /**
2
+ * ============================================================
3
+ * A_Feature Chaining Performance Benchmarks
4
+ * ============================================================
5
+ *
6
+ * Measures realistic end-to-end performance of feature chaining:
7
+ * - Entity creation + scope allocation
8
+ * - Scope registration overhead
9
+ * - Feature invocation through entity.call()
10
+ * - Feature chaining between components (chain())
11
+ * - Dependency injection overhead (@A_Inject)
12
+ * - Scaling with chain depth and component count
13
+ * - Full realistic pipeline: entity → scope → feature → chain → DI
14
+ */
15
+ import { A_Component } from "@adaas/a-concept/a-component";
16
+ import { A_Feature } from "@adaas/a-concept/a-feature";
17
+ import { A_Scope } from "@adaas/a-concept/a-scope";
18
+ import { A_Inject } from "@adaas/a-concept/a-inject";
19
+ import { A_Caller } from "@adaas/a-concept/a-caller";
20
+ import { A_Entity } from "@adaas/a-concept/a-entity";
21
+ import { A_Context } from "@adaas/a-concept/a-context";
22
+ import { createSuite, BenchResult, printSummary } from './helpers';
23
+
24
+
25
+
26
+ // ──────────────────────────────────────────────────────────────
27
+ // Fixture: Components — Multiple extensions converging + chain
28
+ // ──────────────────────────────────────────────────────────────
29
+
30
+ export class ExtStepA extends A_Component {
31
+ @A_Feature.Extend({ name: 'componentFeature', scope: [ExtStepA] })
32
+ stepA() {
33
+ }
34
+ }
35
+
36
+
37
+ // ──────────────────────────────────────────────────────────────
38
+ // Fixture: Entities
39
+ // ──────────────────────────────────────────────────────────────
40
+
41
+ export class BenchEntity extends A_Entity {
42
+
43
+ protected _scope!: A_Scope;
44
+
45
+ get scope(): A_Scope {
46
+ if (!this._scope) {
47
+ this._scope = A_Context.allocate(this, new A_Scope({ name: `${this.aseid.id}-scope` }));
48
+ }
49
+ return this._scope;
50
+ }
51
+
52
+ get targetComponent() {
53
+ return this.scope.resolve(ExtStepA)!;
54
+ }
55
+
56
+ entityFeature() {
57
+ return this.call('entityFeature', this.scope);
58
+ }
59
+ }
60
+
61
+ export class ExtStepB extends A_Component {
62
+ @A_Feature.Extend({ name: 'entityFeature', })
63
+ stepB() {
64
+ }
65
+ }
66
+
67
+ export class ExtStepC extends A_Component {
68
+ @A_Feature.Extend({ name: 'entityFeature', })
69
+ stepC() {
70
+ }
71
+ }
72
+
73
+ export class ChainingComponent extends A_Component {
74
+
75
+ @A_Feature.Extend({
76
+ name: 'entityFeature',
77
+ after: /.*/,
78
+ })
79
+ convergentStep(
80
+ @A_Inject(A_Caller) entity: BenchEntity,
81
+ @A_Inject(A_Scope) scope: A_Scope,
82
+ @A_Inject(A_Feature) feature: A_Feature
83
+ ) {
84
+ feature.chain(entity.targetComponent, 'componentFeature', scope);
85
+ }
86
+ }
87
+
88
+
89
+
90
+ // ──────────────────────────────────────────────────────────────
91
+ // Benchmark Suites
92
+ // ──────────────────────────────────────────────────────────────
93
+
94
+ export async function runFeatureChainingBenchmarks(): Promise<any> {
95
+ const allResults: BenchResult[] = [];
96
+
97
+
98
+
99
+ // ── Suite 3: Feature Call — Baseline (no chain) ─────────
100
+ const baselineResults = await createSuite('Feature Call — Baseline (no chain)', (suite) => {
101
+ const parentScope = new A_Scope({ name: 'parent-scope', components: [ExtStepA] });
102
+
103
+ const childScope = new A_Scope({
104
+ name: 'base-3',
105
+ components: [ChainingComponent, ExtStepB, ExtStepC]
106
+ }).inherit(parentScope);
107
+
108
+ const entity = new BenchEntity();
109
+
110
+ childScope.register(entity);
111
+
112
+ entity.scope.inherit(childScope);
113
+
114
+
115
+
116
+
117
+ suite
118
+ .add('new Feature instantiation (A_Context.featureTemplate)', () => {
119
+ const definition = A_Context.featureTemplate('entityFeature', entity);
120
+
121
+ })
122
+ .add('new Feature instantiation (new A_Feature)', () => {
123
+ const feature = new A_Feature({
124
+ name: 'entityFeature',
125
+ component: entity,
126
+ scope: entity.scope
127
+ });
128
+ })
129
+ .add('new Feature execution (direct)', () => {
130
+ const feature = new A_Feature({
131
+ name: 'entityFeature',
132
+ component: entity,
133
+ scope: entity.scope
134
+ });
135
+
136
+ for (const stage of feature) {
137
+ stage.process(entity.scope)
138
+ }
139
+ })
140
+ .add('new Feature execution (direct entity.call)', () => {
141
+
142
+ const res = entity.call('entityFeature', entity.scope);
143
+
144
+ if (res instanceof Promise)
145
+ throw new Error('Expected synchronous execution for baseline feature call');
146
+ })
147
+ .add('new Feature execution (wrapped entity.call)', () => {
148
+
149
+ const res = entity.entityFeature();
150
+
151
+ if (res instanceof Promise)
152
+ throw new Error('Expected synchronous execution for baseline feature call');
153
+
154
+ })
155
+ .add('[duplicated 1] new Feature execution (wrapped entity.call)', () => {
156
+
157
+ const res = entity.entityFeature();
158
+
159
+ if (res instanceof Promise)
160
+ throw new Error('Expected synchronous execution for baseline feature call');
161
+
162
+ })
163
+ .add('[duplicated 2] new Feature execution (wrapped entity.call)', () => {
164
+
165
+ const res = entity.entityFeature();
166
+
167
+ if (res instanceof Promise)
168
+ throw new Error('Expected synchronous execution for baseline feature call');
169
+
170
+ })
171
+ .add('[duplicated 3] new Feature execution (wrapped entity.call)', () => {
172
+
173
+ const res = entity.entityFeature();
174
+ if (res instanceof Promise)
175
+ throw new Error('Expected synchronous execution for baseline feature call');
176
+
177
+ })
178
+ .add('[duplicated 4] new Feature execution (wrapped entity.call)', () => {
179
+
180
+ const res = entity.entityFeature();
181
+
182
+ if (res instanceof Promise)
183
+ throw new Error('Expected synchronous execution for baseline feature call');
184
+
185
+ })
186
+ });
187
+ allResults.push(...baselineResults);
188
+
189
+ return allResults;
190
+ }
191
+
192
+
193
+ // ──────────────────────────────────────────────────────────────
194
+ // Standalone runner
195
+ // ──────────────────────────────────────────────────────────────
196
+ if (require.main === module) {
197
+ runFeatureChainingBenchmarks()
198
+ .then((results) => {
199
+ const summary = new Map<string, BenchResult[]>();
200
+ summary.set('FeatureChaining', results);
201
+ printSummary(summary);
202
+ console.log('\n✅ Feature chaining benchmarks completed.\n');
203
+ })
204
+ .catch(console.error);
205
+ }
@@ -1084,7 +1084,7 @@ declare class A_Entity<_ConstructorType extends A_TYPES__Entity_Init = A_TYPES__
1084
1084
  * @param lifecycleMethod
1085
1085
  * @param args
1086
1086
  */
1087
- call(feature: string, scope?: A_Scope): any;
1087
+ call(feature: string, scope?: A_Scope): Promise<any> | void;
1088
1088
  /**
1089
1089
  * The default method that can be called and extended to load entity data.
1090
1090
  */
@@ -2013,6 +2013,7 @@ declare class A_Feature<T extends A_TYPES__FeatureAvailableComponents = A_TYPES_
2013
2013
  * Process stages one by one, ensuring each stage completes before starting the next
2014
2014
  */
2015
2015
  private processStagesSequentially;
2016
+ private createStageError;
2016
2017
  /**
2017
2018
  * This method moves the feature to the next stage
2018
2019
  *