lanka 2.0.0 → 2.1.0

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.
Files changed (66) hide show
  1. package/dist/{LankaSharedStoreLocator-jsz_gnUm.d.ts → ALankaLocator-BUCCz0Q5.d.ts} +1 -47
  2. package/dist/{ILankaScenarioVM-DpKFL3iE.d.ts → ILankaScenario-DQd9ZfUw.d.ts} +1 -30
  3. package/dist/{ILankaScenarioMetadata-Dj4GCqmX.d.ts → ILankaScenarioMetadata-BsDp0Bzm.d.ts} +1 -1
  4. package/dist/ILankaScenarioVM-DKwjbIRq.d.ts +30 -0
  5. package/dist/{LankaScenarioLocator-Dki2Es3O.d.ts → LankaScenarioVMRegistry-DySAOaj2.d.ts} +4 -37
  6. package/dist/_extend/index.d.ts +64 -7
  7. package/dist/_extend/index.js +59 -9
  8. package/dist/_extend/index.js.map +1 -1
  9. package/dist/_internal/index.d.ts +13 -8
  10. package/dist/{activeRuntime-BO-qY0yY.d.ts → activeRuntime-ByucLPhj.d.ts} +7 -3
  11. package/dist/bootstrap/index.d.ts +15 -10
  12. package/dist/bootstrap/index.js +10 -4
  13. package/dist/chunk-24MUFFHF.js +43 -0
  14. package/dist/chunk-24MUFFHF.js.map +1 -0
  15. package/dist/chunk-3R2NO47A.js +35 -0
  16. package/dist/chunk-3R2NO47A.js.map +1 -0
  17. package/dist/{chunk-UMPSR4US.js → chunk-42CWYVZJ.js} +44 -61
  18. package/dist/chunk-42CWYVZJ.js.map +1 -0
  19. package/dist/chunk-BMF4TM2Z.js +22 -0
  20. package/dist/chunk-BMF4TM2Z.js.map +1 -0
  21. package/dist/chunk-JZJ6GXX3.js +12 -0
  22. package/dist/chunk-JZJ6GXX3.js.map +1 -0
  23. package/dist/{chunk-EYDMBI5T.js → chunk-MKKMTLOY.js} +11 -311
  24. package/dist/chunk-MKKMTLOY.js.map +1 -0
  25. package/dist/{chunk-UE2C76OR.js → chunk-N3275IPH.js} +2 -69
  26. package/dist/chunk-N3275IPH.js.map +1 -0
  27. package/dist/chunk-NWEHOMTS.js +315 -0
  28. package/dist/chunk-NWEHOMTS.js.map +1 -0
  29. package/dist/chunk-SBITVBF7.js +49 -0
  30. package/dist/chunk-SBITVBF7.js.map +1 -0
  31. package/dist/{chunk-SZVNPK24.js → chunk-SO7D5E7O.js} +17 -9
  32. package/dist/{chunk-SZVNPK24.js.map → chunk-SO7D5E7O.js.map} +1 -1
  33. package/dist/{createLanka-x4oSMs7P.d.ts → createLanka-DvUGu9Hl.d.ts} +2 -2
  34. package/dist/{createLankaScope-DomNbEvb.d.ts → createLankaScope-CVoV0EwO.d.ts} +1 -1
  35. package/dist/gateway/index.js +3 -3
  36. package/dist/index.d.ts +14 -9
  37. package/dist/index.js +10 -4
  38. package/dist/locator/gateway/lanka-gateway-locator/LankaGatewayLocator.d.ts +18 -0
  39. package/dist/locator/gateway/lanka-gateway-locator/LankaGatewayLocator.js +9 -0
  40. package/dist/locator/gateway/lanka-gateway-locator/LankaGatewayLocator.js.map +1 -0
  41. package/dist/locator/index.d.ts +4 -2
  42. package/dist/locator/index.js +4 -1
  43. package/dist/locator/index.js.map +1 -1
  44. package/dist/locator/scenario/lanka-scenario-locator/LankaScenarioLocator.d.ts +60 -0
  45. package/dist/locator/scenario/lanka-scenario-locator/LankaScenarioLocator.js +12 -0
  46. package/dist/locator/scenario/lanka-scenario-locator/LankaScenarioLocator.js.map +1 -0
  47. package/dist/locator/shared-store/lanka-shared-store-locator/LankaSharedStoreLocator.d.ts +22 -0
  48. package/dist/locator/shared-store/lanka-shared-store-locator/LankaSharedStoreLocator.js +9 -0
  49. package/dist/locator/shared-store/lanka-shared-store-locator/LankaSharedStoreLocator.js.map +1 -0
  50. package/dist/locator/singleton/lanka-singleton-locator/LankaSingletonLocator.d.ts +30 -0
  51. package/dist/locator/singleton/lanka-singleton-locator/LankaSingletonLocator.js +9 -0
  52. package/dist/locator/singleton/lanka-singleton-locator/LankaSingletonLocator.js.map +1 -0
  53. package/dist/scenario/index.d.ts +4 -3
  54. package/dist/scenario/index.js +5 -3
  55. package/dist/scenario/index.js.map +1 -1
  56. package/dist/stream/index.d.ts +17 -12
  57. package/dist/viewmodel/index.d.ts +42 -12
  58. package/dist/viewmodel/index.js +2 -1
  59. package/dist/viewmodel/index.js.map +1 -1
  60. package/package.json +2 -2
  61. package/skills/lanka-core/SKILL.md +1 -1
  62. package/skills/lanka-core/reference.md +1 -1
  63. package/skills/lanka-packages/SKILL.md +1 -1
  64. package/dist/chunk-EYDMBI5T.js.map +0 -1
  65. package/dist/chunk-UE2C76OR.js.map +0 -1
  66. package/dist/chunk-UMPSR4US.js.map +0 -1
@@ -0,0 +1,43 @@
1
+ import {
2
+ findExportedClass
3
+ } from "./chunk-JZJ6GXX3.js";
4
+ import {
5
+ ALankaLocator
6
+ } from "./chunk-N3275IPH.js";
7
+
8
+ // src/locator/singleton/lanka-singleton-locator/LankaSingletonLocator.ts
9
+ import * as SingletonsModule from "@lanka_di/Singletons";
10
+ var LankaSingletonLocator = class extends ALankaLocator {
11
+ singletonIndexModule;
12
+ constructor(config) {
13
+ super({
14
+ findClassByName: (className) => {
15
+ return findExportedClass(SingletonsModule, className) ?? (this.singletonIndexModule ? findExportedClass(this.singletonIndexModule, className) : void 0);
16
+ },
17
+ createInstance: (Class) => {
18
+ return new Class();
19
+ },
20
+ notFoundError: (className, propertyName) => `Singleton "${className}" (accessed as "${propertyName}") not found. Make sure the class is exported from @lanka_di/Singletons.ts or registered via registerSingleton method.`
21
+ });
22
+ this.singletonIndexModule = config?.singletonIndexModule;
23
+ }
24
+ /**
25
+ * Creates a NEW service object, bypassing the locator's cache.
26
+ *
27
+ * For scopes: they take the class from here and set the lifetime themselves.
28
+ * The root cache is untouched — otherwise the first resolution inside a scope
29
+ * would replace the application's root object.
30
+ */
31
+ createScopedInstance(className, propertyName) {
32
+ const Class = this.classFor(className);
33
+ if (!Class) {
34
+ throw new Error(this.config.notFoundError(className, propertyName));
35
+ }
36
+ return this.config.createInstance(Class);
37
+ }
38
+ };
39
+
40
+ export {
41
+ LankaSingletonLocator
42
+ };
43
+ //# sourceMappingURL=chunk-24MUFFHF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/locator/singleton/lanka-singleton-locator/LankaSingletonLocator.ts"],"sourcesContent":["import { ALankaLocator } from \"../../_abstractions/lanka-locator/ALankaLocator\";\nimport { findExportedClass } from \"../../_internal/find-exported-class/findExportedClass\";\n/**\n * Classes come from the consumer's barrel.\n *\n * Adding one is ONE export line: types are inferred, autocomplete works, and no\n * list has to be maintained. A list maintained by hand is a list that eventually\n * falls behind the code.\n */\nimport * as SingletonsModule from \"@lanka_di/Singletons\";\n\n/**\n * LankaSingletonLocator configuration.\n */\nexport interface ILankaSingletonLocatorConfig {\n\t/** The module holding singleton classes — the consumer's barrel. */\n\tsingletonIndexModule?: Record<string, unknown>;\n}\n\n/**\n * Resolves singletons by property name (camelCase) or class name (PascalCase),\n * constructing them on first use and caching them.\n *\n * A class arrives either from the consumer's barrel or registered by hand — the\n * latter for tests and for objects that arrive already built.\n */\nexport class LankaSingletonLocator extends ALankaLocator<unknown> {\n\tprivate readonly singletonIndexModule?: Record<string, unknown>;\n\n\tconstructor(config?: ILankaSingletonLocatorConfig) {\n\t\tsuper({\n\t\t\tfindClassByName: (className: string) => {\n\t\t\t\t// Order: the application's barrel, then an extra module if one was\n\t\t\t\t// given. Hand-registered classes are read by `ALankaLocator` itself,\n\t\t\t\t// ahead of this callback — they used to be read here, and the copy is\n\t\t\t\t// what let the gateway and scenario locators forget them entirely.\n\t\t\t\t//\n\t\t\t\t// Each source is checked ONCE, by export key. A fallback pass over\n\t\t\t\t// `Class.name` looks for something a built bundle no longer has:\n\t\t\t\t// minification loses class names exactly as it loses export names.\n\t\t\t\treturn (\n\t\t\t\t\tfindExportedClass<unknown>(SingletonsModule, className) ??\n\t\t\t\t\t(this.singletonIndexModule\n\t\t\t\t\t\t? findExportedClass<unknown>(this.singletonIndexModule, className)\n\t\t\t\t\t\t: undefined)\n\t\t\t\t);\n\t\t\t},\n\t\t\tcreateInstance: (Class) => {\n\t\t\t\treturn new Class();\n\t\t\t},\n\t\t\tnotFoundError: (className, propertyName) =>\n\t\t\t\t`Singleton \"${className}\" (accessed as \"${propertyName}\") not found. ` +\n\t\t\t\t`Make sure the class is exported from @lanka_di/Singletons.ts or registered via registerSingleton method.`,\n\t\t});\n\n\t\tthis.singletonIndexModule = config?.singletonIndexModule;\n\t}\n\n\t/**\n\t * Creates a NEW service object, bypassing the locator's cache.\n\t *\n\t * For scopes: they take the class from here and set the lifetime themselves.\n\t * The root cache is untouched — otherwise the first resolution inside a scope\n\t * would replace the application's root object.\n\t */\n\tpublic createScopedInstance(className: string, propertyName: string): unknown {\n\t\t// `classFor`, not `config.findClassByName`: a hand-registered class must\n\t\t// resolve inside a scope exactly as it does at the root.\n\t\tconst Class = this.classFor(className);\n\t\tif (!Class) {\n\t\t\tthrow new Error(this.config.notFoundError(className, propertyName));\n\t\t}\n\t\treturn this.config.createInstance(Class);\n\t}\n}\n"],"mappings":";;;;;;;;AASA,YAAY,sBAAsB;AAiB3B,IAAM,wBAAN,cAAoC,cAAuB;AAAA,EAChD;AAAA,EAEjB,YAAY,QAAuC;AAClD,UAAM;AAAA,MACL,iBAAiB,CAAC,cAAsB;AASvC,eACC,kBAA2B,kBAAkB,SAAS,MACrD,KAAK,uBACH,kBAA2B,KAAK,sBAAsB,SAAS,IAC/D;AAAA,MAEL;AAAA,MACA,gBAAgB,CAAC,UAAU;AAC1B,eAAO,IAAI,MAAM;AAAA,MAClB;AAAA,MACA,eAAe,CAAC,WAAW,iBAC1B,cAAc,SAAS,mBAAmB,YAAY;AAAA,IAExD,CAAC;AAED,SAAK,uBAAuB,QAAQ;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,qBAAqB,WAAmB,cAA+B;AAG7E,UAAM,QAAQ,KAAK,SAAS,SAAS;AACrC,QAAI,CAAC,OAAO;AACX,YAAM,IAAI,MAAM,KAAK,OAAO,cAAc,WAAW,YAAY,CAAC;AAAA,IACnE;AACA,WAAO,KAAK,OAAO,eAAe,KAAK;AAAA,EACxC;AACD;","names":[]}
@@ -0,0 +1,35 @@
1
+ import {
2
+ findExportedClass
3
+ } from "./chunk-JZJ6GXX3.js";
4
+ import {
5
+ ALankaLocator
6
+ } from "./chunk-N3275IPH.js";
7
+
8
+ // src/locator/shared-store/lanka-shared-store-locator/LankaSharedStoreLocator.ts
9
+ import * as SharedStoresModule from "@lanka_di/SharedStores";
10
+ var LankaSharedStoreLocator = class extends ALankaLocator {
11
+ sharedStoreIndexModule;
12
+ constructor(config) {
13
+ super({
14
+ findClassByName: (className) => {
15
+ return findExportedClass(
16
+ SharedStoresModule,
17
+ className
18
+ ) ?? (this.sharedStoreIndexModule ? findExportedClass(
19
+ this.sharedStoreIndexModule,
20
+ className
21
+ ) : void 0);
22
+ },
23
+ createInstance: (Class) => {
24
+ return new Class();
25
+ },
26
+ notFoundError: (className, propertyName) => `SharedStore "${className}" (accessed as "${propertyName}") not found. Make sure the class extends ALankaSharedStore and is exported from @lanka_di/SharedStores.ts or registered via registerSharedStore method.`
27
+ });
28
+ this.sharedStoreIndexModule = config?.sharedStoreIndexModule;
29
+ }
30
+ };
31
+
32
+ export {
33
+ LankaSharedStoreLocator
34
+ };
35
+ //# sourceMappingURL=chunk-3R2NO47A.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/locator/shared-store/lanka-shared-store-locator/LankaSharedStoreLocator.ts"],"sourcesContent":["import { ALankaLocator } from \"../../_abstractions/lanka-locator/ALankaLocator\";\nimport { findExportedClass } from \"../../_internal/find-exported-class/findExportedClass\";\nimport { ALankaSharedStore } from \"../../../viewmodel/_abstractions/lanka-shared-store/ALankaSharedStore\";\nimport * as SharedStoresModule from \"@lanka_di/SharedStores\";\n\ntype TSharedStoreState = object;\n\n/**\n * LankaSharedStoreLocator configuration.\n */\nexport interface ILankaSharedStoreLocatorConfig {\n\t/** The module holding shared store classes — the consumer's barrel. */\n\tsharedStoreIndexModule?: Record<string, unknown>;\n}\n\n/**\n * Resolves shared stores by property name (camelCase) or class name\n * (PascalCase), constructing them on first use and caching them.\n */\nexport class LankaSharedStoreLocator extends ALankaLocator<ALankaSharedStore<TSharedStoreState>> {\n\tprivate readonly sharedStoreIndexModule?: Record<string, unknown>;\n\n\tconstructor(config?: ILankaSharedStoreLocatorConfig) {\n\t\tsuper({\n\t\t\tfindClassByName: (className: string) => {\n\t\t\t\t// Hand-registered classes are read by `ALankaLocator` itself, ahead of\n\t\t\t\t// this callback. This is only the barrel.\n\t\t\t\treturn (\n\t\t\t\t\tfindExportedClass<ALankaSharedStore<TSharedStoreState>>(\n\t\t\t\t\t\tSharedStoresModule,\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t) ??\n\t\t\t\t\t(this.sharedStoreIndexModule\n\t\t\t\t\t\t? findExportedClass<ALankaSharedStore<TSharedStoreState>>(\n\t\t\t\t\t\t\t\tthis.sharedStoreIndexModule,\n\t\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: undefined)\n\t\t\t\t);\n\t\t\t},\n\t\t\tcreateInstance: (Class) => {\n\t\t\t\treturn new Class();\n\t\t\t},\n\t\t\tnotFoundError: (className, propertyName) =>\n\t\t\t\t`SharedStore \"${className}\" (accessed as \"${propertyName}\") not found. ` +\n\t\t\t\t`Make sure the class extends ALankaSharedStore and is exported from @lanka_di/SharedStores.ts ` +\n\t\t\t\t`or registered via registerSharedStore method.`,\n\t\t});\n\n\t\tthis.sharedStoreIndexModule = config?.sharedStoreIndexModule;\n\t}\n}\n"],"mappings":";;;;;;;;AAGA,YAAY,wBAAwB;AAgB7B,IAAM,0BAAN,cAAsC,cAAoD;AAAA,EAC/E;AAAA,EAEjB,YAAY,QAAyC;AACpD,UAAM;AAAA,MACL,iBAAiB,CAAC,cAAsB;AAGvC,eACC;AAAA,UACC;AAAA,UACA;AAAA,QACD,MACC,KAAK,yBACH;AAAA,UACA,KAAK;AAAA,UACL;AAAA,QACD,IACC;AAAA,MAEL;AAAA,MACA,gBAAgB,CAAC,UAAU;AAC1B,eAAO,IAAI,MAAM;AAAA,MAClB;AAAA,MACA,eAAe,CAAC,WAAW,iBAC1B,gBAAgB,SAAS,mBAAmB,YAAY;AAAA,IAG1D,CAAC;AAED,SAAK,yBAAyB,QAAQ;AAAA,EACvC;AACD;","names":[]}
@@ -1,26 +1,10 @@
1
1
  import {
2
2
  ALankaScenario,
3
3
  LankaScenariosRegistry
4
- } from "./chunk-EYDMBI5T.js";
4
+ } from "./chunk-NWEHOMTS.js";
5
5
  import {
6
- ALankaLocator,
7
- caseConvert,
8
- findExportedClass
9
- } from "./chunk-UE2C76OR.js";
10
- import {
11
- lankaLogger
12
- } from "./chunk-FII3PW2G.js";
13
-
14
- // src/locator/gateway/lanka-gateway-locator/LankaGatewayLocator.ts
15
- import * as GatewaysModule from "@lanka_di/Gateways";
16
- var LankaGatewayLocator = class extends ALankaLocator {
17
- constructor() {
18
- super({
19
- findClassByName: (gatewayName) => findExportedClass(GatewaysModule, gatewayName),
20
- notFoundError: (gatewayName, propertyName) => `Gateway "${gatewayName}" (accessed as "${propertyName}") not found. Make sure the gateway class extends ALankaGateway and is exported from lankaGateways.ts.`
21
- });
22
- }
23
- };
6
+ ALankaLocator
7
+ } from "./chunk-N3275IPH.js";
24
8
 
25
9
  // src/locator/scenario/lanka-scenario-locator/LankaScenarioLocator.ts
26
10
  import * as ScenariosModule from "@lanka_di/Scenarios";
@@ -54,6 +38,45 @@ var LankaScenarioLocator = class extends ALankaLocator {
54
38
  get registry() {
55
39
  return LankaScenariosRegistry.getInstance();
56
40
  }
41
+ /**
42
+ * Every constructible class the consumer's barrel exports.
43
+ *
44
+ * Published so that this file stays the ONE module in the framework that reads
45
+ * `@lanka_di/Scenarios`. `LankaScenarioBootstrap` used to read it too, and
46
+ * that second reader is what made `lanka/scenario` — the entry a consumer's
47
+ * scenario class imports `ALankaScenario` from — part of the import cycle the
48
+ * inversion creates. A bundler is free to order the chunks behind that entry
49
+ * however it likes, and when it put the barrel first the consumer's class
50
+ * extended `undefined`. `lanka/locator` carries the cycle instead, and no
51
+ * scenario class imports it.
52
+ *
53
+ * Not a filter on "is a scenario": an export that is not a function has no
54
+ * chance of being one, and anything further is decided by CONSTRUCTING it,
55
+ * which is the caller's job and the only honest test.
56
+ *
57
+ * ## Why the values are widened to `unknown` first
58
+ *
59
+ * A type predicate has to be assignable to the type it narrows, and the type
60
+ * of what this reads is the CONSUMER'S — whatever their `Scenarios` barrel
61
+ * happens to export. A real scenario class is `typeof TheirScenario`, which
62
+ * carries the statics `ALankaScenario` declares, and `new () => ILankaScenario`
63
+ * has none of them: the predicate is not assignable to it, and the file does
64
+ * not compile in any project whose barrel has a scenario in it.
65
+ *
66
+ * It compiled here for one reason: this repository's fixture barrel says
67
+ * `export {}`, so `Object.values` is `never[]` and every predicate is
68
+ * vacuously assignable. `_playgrounds/node` is where it failed, because that
69
+ * is a barrel with a real class in it — the same blind spot, in the same
70
+ * shape, as the empty probe barrels that let the 2.0.0 chunk cycle ship.
71
+ *
72
+ * `unknown` is also what this honestly knows. The framework cannot see a
73
+ * consumer's types; it sees exports and asks whether each is a function.
74
+ */
75
+ getDeclaredScenarioClasses() {
76
+ return Object.values(ScenariosModule).filter(
77
+ (exported) => typeof exported === "function"
78
+ );
79
+ }
57
80
  constructor() {
58
81
  super({
59
82
  findClassByName: (scenarioName) => {
@@ -93,47 +116,7 @@ var LankaScenarioLocator = class extends ALankaLocator {
93
116
  }
94
117
  };
95
118
 
96
- // src/locator/_factories/create-lanka-scope/createLankaScope.ts
97
- function createLankaScope(singletons) {
98
- const instances = /* @__PURE__ */ new Map();
99
- let disposed = false;
100
- return {
101
- resolve(propertyName) {
102
- if (disposed) {
103
- throw new Error(
104
- `The scope is closed: "${propertyName}" can no longer be resolved in it. This is usually a scope reference that outlived the screen that created it.`
105
- );
106
- }
107
- const className = caseConvert(propertyName, "pascalCase");
108
- if (instances.has(className)) return instances.get(className);
109
- const instance = singletons.createScopedInstance(className, propertyName);
110
- instances.set(className, instance);
111
- return instance;
112
- },
113
- dispose() {
114
- if (disposed) return;
115
- disposed = true;
116
- for (const [name, instance] of instances) {
117
- const disposable = instance;
118
- if (typeof disposable.dispose !== "function") continue;
119
- try {
120
- disposable.dispose();
121
- } catch (error) {
122
- lankaLogger.printBootstrapLog(
123
- `Failed to dispose "${name}" in the scope`,
124
- error instanceof Error ? error.message : String(error)
125
- );
126
- }
127
- }
128
- instances.clear();
129
- },
130
- isDisposed: () => disposed
131
- };
132
- }
133
-
134
119
  export {
135
- LankaGatewayLocator,
136
- LankaScenarioLocator,
137
- createLankaScope
120
+ LankaScenarioLocator
138
121
  };
139
- //# sourceMappingURL=chunk-UMPSR4US.js.map
122
+ //# sourceMappingURL=chunk-42CWYVZJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/locator/scenario/lanka-scenario-locator/LankaScenarioLocator.ts"],"sourcesContent":["import { LankaScenariosRegistry } from \"../../../scenario/_registries/lanka-scenarios-registry/LankaScenariosRegistry\";\nimport { ILankaScenario } from \"../../../scenario/_interfaces/ILankaScenario\";\nimport { ALankaScenario } from \"../../../scenario/_abstractions/lanka-scenario/ALankaScenario\";\nimport { ALankaLocator } from \"../../_abstractions/lanka-locator/ALankaLocator\";\n/**\n * Classes come from the consumer's barrel.\n *\n * Adding one is ONE export line: types are inferred, autocomplete works, and no\n * list has to be maintained.\n */\nimport * as ScenariosModule from \"@lanka_di/Scenarios\";\n\n/**\n * The barrel's class whose INSTANCE carries this name, when the export key does\n * not.\n *\n * A pooled instance answers for its class without constructing another: the\n * pool is never drained, so a lookup that constructed every class on every miss\n * grew it by the whole barrel each time a bad name was asked for. Only a class\n * the pool has never seen is constructed here — once, and it joins the pool.\n */\nconst findScenarioClassByInstanceName = (\n\tscenarioName: string,\n): (new () => ILankaScenario<unknown>) | undefined => {\n\tconst pooled = ALankaScenario.getAutoRegisteredScenarios();\n\n\tfor (const value of Object.values(ScenariosModule)) {\n\t\tif (typeof value !== \"function\" || !value.prototype) continue;\n\n\t\tconst Class = value as new () => ALankaScenario<unknown>;\n\t\tconst instance =\n\t\t\tpooled.find((scenario) => scenario.constructor === Class) ?? construct(Class);\n\t\tif (instance?.name === scenarioName) return Class;\n\t}\n\n\treturn undefined;\n};\n\n/** A new instance, or `undefined` for an export that is not constructible. */\nconst construct = (\n\tClass: new () => ALankaScenario<unknown>,\n): ALankaScenario<unknown> | undefined => {\n\ttry {\n\t\treturn new Class();\n\t} catch {\n\t\treturn undefined;\n\t}\n};\n\n/**\n * Resolves scenarios by property name (camelCase) or scenario name\n * (PascalCase).\n *\n * Looks in the registry, then in the self-registration pool, and failing both\n * constructs the scenario from the consumer's barrel on first use.\n */\nexport class LankaScenarioLocator extends ALankaLocator<ILankaScenario<unknown>> {\n\t/**\n\t * The registry is read LAZILY rather than in a field initialiser.\n\t *\n\t * The locator is constructed INSIDE `createLanka`, before the instance becomes\n\t * active. A field initialiser would ask for the active instance at that moment\n\t * and fail with \"no instance yet\" while the instance being created is on the\n\t * stack. Deferred reading resolves it: by the first scenario resolution an\n\t * active instance exists.\n\t */\n\tprivate get registry(): LankaScenariosRegistry {\n\t\treturn LankaScenariosRegistry.getInstance();\n\t}\n\n\t/**\n\t * Every constructible class the consumer's barrel exports.\n\t *\n\t * Published so that this file stays the ONE module in the framework that reads\n\t * `@lanka_di/Scenarios`. `LankaScenarioBootstrap` used to read it too, and\n\t * that second reader is what made `lanka/scenario` — the entry a consumer's\n\t * scenario class imports `ALankaScenario` from — part of the import cycle the\n\t * inversion creates. A bundler is free to order the chunks behind that entry\n\t * however it likes, and when it put the barrel first the consumer's class\n\t * extended `undefined`. `lanka/locator` carries the cycle instead, and no\n\t * scenario class imports it.\n\t *\n\t * Not a filter on \"is a scenario\": an export that is not a function has no\n\t * chance of being one, and anything further is decided by CONSTRUCTING it,\n\t * which is the caller's job and the only honest test.\n\t *\n\t * ## Why the values are widened to `unknown` first\n\t *\n\t * A type predicate has to be assignable to the type it narrows, and the type\n\t * of what this reads is the CONSUMER'S — whatever their `Scenarios` barrel\n\t * happens to export. A real scenario class is `typeof TheirScenario`, which\n\t * carries the statics `ALankaScenario` declares, and `new () => ILankaScenario`\n\t * has none of them: the predicate is not assignable to it, and the file does\n\t * not compile in any project whose barrel has a scenario in it.\n\t *\n\t * It compiled here for one reason: this repository's fixture barrel says\n\t * `export {}`, so `Object.values` is `never[]` and every predicate is\n\t * vacuously assignable. `_playgrounds/node` is where it failed, because that\n\t * is a barrel with a real class in it — the same blind spot, in the same\n\t * shape, as the empty probe barrels that let the 2.0.0 chunk cycle ship.\n\t *\n\t * `unknown` is also what this honestly knows. The framework cannot see a\n\t * consumer's types; it sees exports and asks whether each is a function.\n\t */\n\tpublic getDeclaredScenarioClasses(): readonly (new () => ILankaScenario<unknown>)[] {\n\t\treturn (Object.values(ScenariosModule) as readonly unknown[]).filter(\n\t\t\t(exported): exported is new () => ILankaScenario<unknown> =>\n\t\t\t\ttypeof exported === \"function\",\n\t\t);\n\t}\n\n\tconstructor() {\n\t\tsuper({\n\t\t\tfindClassByName: (scenarioName: string) => {\n\t\t\t\t// By export key first: an instance name does not always survive minification.\n\t\t\t\tif (scenarioName in ScenariosModule) {\n\t\t\t\t\t// `as unknown` before the guards, exactly as in the singleton locator.\n\t\t\t\t\t// An EMPTY barrel — what the scaffolder writes, and what a new project\n\t\t\t\t\t// has until its first scenario — makes the module's keys `never`, so\n\t\t\t\t\t// an indexed access is `never` and reading `.prototype` off it does\n\t\t\t\t\t// not compile.\n\t\t\t\t\tconst ScenarioClass = ScenariosModule[\n\t\t\t\t\t\tscenarioName as keyof typeof ScenariosModule\n\t\t\t\t\t] as unknown;\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof ScenarioClass === \"function\" &&\n\t\t\t\t\t\t\"prototype\" in ScenarioClass &&\n\t\t\t\t\t\tScenarioClass.prototype\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn ScenarioClass as new () => ILankaScenario<unknown>;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Fallback: look up by instance name.\n\t\t\t\treturn findScenarioClassByInstanceName(scenarioName);\n\t\t\t},\n\t\t\tgetInstanceByName: (scenarioName: string) => {\n\t\t\t\t// The registry first.\n\t\t\t\tconst registered = this.registry.getScenarioByName(scenarioName);\n\t\t\t\tif (registered) {\n\t\t\t\t\treturn registered;\n\t\t\t\t}\n\n\t\t\t\t// Then those that registered themselves.\n\t\t\t\tconst autoRegistered = ALankaScenario.getAutoRegisteredScenarios();\n\t\t\t\tconst scenario = autoRegistered.find((s) => s.name === scenarioName);\n\n\t\t\t\tif (scenario) {\n\t\t\t\t\tif (!this.registry.isRegistered(scenarioName)) {\n\t\t\t\t\t\tthis.registry.register(scenario);\n\t\t\t\t\t}\n\t\t\t\t\treturn scenario;\n\t\t\t\t}\n\n\t\t\t\t// Then finding the class by name and constructing it.\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t\tcreateInstance: (ScenarioClass) => {\n\t\t\t\tconst instance = new ScenarioClass();\n\t\t\t\tconst scenarioName = instance.name;\n\t\t\t\tif (!this.registry.isRegistered(scenarioName)) {\n\t\t\t\t\tthis.registry.register(instance);\n\t\t\t\t}\n\t\t\t\treturn instance;\n\t\t\t},\n\t\t\tnotFoundError: (scenarioName, propertyName) =>\n\t\t\t\t`Scenario \"${scenarioName}\" (accessed as \"${propertyName}\") not found. ` +\n\t\t\t\t`Make sure the scenario class extends ALankaScenario and has name=\"${scenarioName}\".`,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;;AAUA,YAAY,qBAAqB;AAWjC,IAAM,kCAAkC,CACvC,iBACqD;AACrD,QAAM,SAAS,eAAe,2BAA2B;AAEzD,aAAW,SAAS,OAAO,OAAO,eAAe,GAAG;AACnD,QAAI,OAAO,UAAU,cAAc,CAAC,MAAM,UAAW;AAErD,UAAM,QAAQ;AACd,UAAM,WACL,OAAO,KAAK,CAAC,aAAa,SAAS,gBAAgB,KAAK,KAAK,UAAU,KAAK;AAC7E,QAAI,UAAU,SAAS,aAAc,QAAO;AAAA,EAC7C;AAEA,SAAO;AACR;AAGA,IAAM,YAAY,CACjB,UACyC;AACzC,MAAI;AACH,WAAO,IAAI,MAAM;AAAA,EAClB,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AASO,IAAM,uBAAN,cAAmC,cAAuC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUhF,IAAY,WAAmC;AAC9C,WAAO,uBAAuB,YAAY;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoCO,6BAA6E;AACnF,WAAQ,OAAO,OAAO,eAAe,EAAyB;AAAA,MAC7D,CAAC,aACA,OAAO,aAAa;AAAA,IACtB;AAAA,EACD;AAAA,EAEA,cAAc;AACb,UAAM;AAAA,MACL,iBAAiB,CAAC,iBAAyB;AAE1C,YAAI,gBAAgB,iBAAiB;AAMpC,gBAAM,gBAAgB,gBACrB,YACD;AACA,cACC,OAAO,kBAAkB,cACzB,eAAe,iBACf,cAAc,WACb;AACD,mBAAO;AAAA,UACR;AAAA,QACD;AAEA,eAAO,gCAAgC,YAAY;AAAA,MACpD;AAAA,MACA,mBAAmB,CAAC,iBAAyB;AAE5C,cAAM,aAAa,KAAK,SAAS,kBAAkB,YAAY;AAC/D,YAAI,YAAY;AACf,iBAAO;AAAA,QACR;AAGA,cAAM,iBAAiB,eAAe,2BAA2B;AACjE,cAAM,WAAW,eAAe,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY;AAEnE,YAAI,UAAU;AACb,cAAI,CAAC,KAAK,SAAS,aAAa,YAAY,GAAG;AAC9C,iBAAK,SAAS,SAAS,QAAQ;AAAA,UAChC;AACA,iBAAO;AAAA,QACR;AAGA,eAAO;AAAA,MACR;AAAA,MACA,gBAAgB,CAAC,kBAAkB;AAClC,cAAM,WAAW,IAAI,cAAc;AACnC,cAAM,eAAe,SAAS;AAC9B,YAAI,CAAC,KAAK,SAAS,aAAa,YAAY,GAAG;AAC9C,eAAK,SAAS,SAAS,QAAQ;AAAA,QAChC;AACA,eAAO;AAAA,MACR;AAAA,MACA,eAAe,CAAC,cAAc,iBAC7B,aAAa,YAAY,mBAAmB,YAAY,mFACa,YAAY;AAAA,IACnF,CAAC;AAAA,EACF;AACD;","names":[]}
@@ -0,0 +1,22 @@
1
+ import {
2
+ findExportedClass
3
+ } from "./chunk-JZJ6GXX3.js";
4
+ import {
5
+ ALankaLocator
6
+ } from "./chunk-N3275IPH.js";
7
+
8
+ // src/locator/gateway/lanka-gateway-locator/LankaGatewayLocator.ts
9
+ import * as GatewaysModule from "@lanka_di/Gateways";
10
+ var LankaGatewayLocator = class extends ALankaLocator {
11
+ constructor() {
12
+ super({
13
+ findClassByName: (gatewayName) => findExportedClass(GatewaysModule, gatewayName),
14
+ notFoundError: (gatewayName, propertyName) => `Gateway "${gatewayName}" (accessed as "${propertyName}") not found. Make sure the gateway class extends ALankaGateway and is exported from lankaGateways.ts.`
15
+ });
16
+ }
17
+ };
18
+
19
+ export {
20
+ LankaGatewayLocator
21
+ };
22
+ //# sourceMappingURL=chunk-BMF4TM2Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/locator/gateway/lanka-gateway-locator/LankaGatewayLocator.ts"],"sourcesContent":["import * as GatewaysModule from \"@lanka_di/Gateways\";\nimport type { ALankaGateway } from \"../../../gateway/_abstractions/lanka-gateway/ALankaGateway\";\nimport { ALankaLocator } from \"../../_abstractions/lanka-locator/ALankaLocator\";\nimport { findExportedClass } from \"../../_internal/find-exported-class/findExportedClass\";\n\n/**\n * Resolves a gateway by property name (camelCase) or class name (PascalCase),\n * constructing it lazily and caching the instance.\n *\n * Adding a gateway takes one export line in `@lanka_di/Gateways`: types are\n * inferred and nothing is registered.\n */\nexport class LankaGatewayLocator extends ALankaLocator<ALankaGateway<unknown>> {\n\tconstructor() {\n\t\tsuper({\n\t\t\tfindClassByName: (gatewayName: string) =>\n\t\t\t\tfindExportedClass<ALankaGateway<unknown>>(GatewaysModule, gatewayName),\n\t\t\tnotFoundError: (gatewayName, propertyName) =>\n\t\t\t\t`Gateway \"${gatewayName}\" (accessed as \"${propertyName}\") not found. ` +\n\t\t\t\t`Make sure the gateway class extends ALankaGateway and is exported from lankaGateways.ts.`,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;AAAA,YAAY,oBAAoB;AAYzB,IAAM,sBAAN,cAAkC,cAAsC;AAAA,EAC9E,cAAc;AACb,UAAM;AAAA,MACL,iBAAiB,CAAC,gBACjB,kBAA0C,gBAAgB,WAAW;AAAA,MACtE,eAAe,CAAC,aAAa,iBAC5B,YAAY,WAAW,mBAAmB,YAAY;AAAA,IAExD,CAAC;AAAA,EACF;AACD;","names":[]}
@@ -0,0 +1,12 @@
1
+ // src/locator/_internal/find-exported-class/findExportedClass.ts
2
+ function findExportedClass(module, exportName) {
3
+ if (!(exportName in module)) return void 0;
4
+ if (!Object.hasOwn(module, exportName)) return void 0;
5
+ const candidate = module[exportName];
6
+ return typeof candidate === "function" && candidate.prototype ? candidate : void 0;
7
+ }
8
+
9
+ export {
10
+ findExportedClass
11
+ };
12
+ //# sourceMappingURL=chunk-JZJ6GXX3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/locator/_internal/find-exported-class/findExportedClass.ts"],"sourcesContent":["/**\n * Finds a class in a module's ES namespace by name.\n *\n * An ES namespace is an ordinary object and `module[name]` is enough. Walking\n * `Reflect.ownKeys`, reading property descriptors and wrapping field access in\n * `try/catch` guards against what does not happen.\n *\n * ## Why a fallback pass over `Class.name` is worse than useless\n *\n * It is written for the case where the export name was lost to minification. But\n * `Class.name`.\n *\n * minification loses `Class.name` too — so the fallback looks for something a\n * built bundle no longer has, creating an impression of protection where there\n * is none.\n *\n * Resolution still works when the export name differs from the class name, which\n * `locator.contract.test.ts` pins: the lookup is by EXPORT KEY, and that is what\n * the consumer writes in the barrel.\n */\nexport function findExportedClass<TInstance>(\n\tmodule: object,\n\texportName: string,\n): (new () => TInstance) | undefined {\n\t// `in` first, then indexing. An ES namespace answers `undefined` for a missing\n\t// key, but a mocked module does not: vitest returns a proxy that THROWS on an\n\t// unknown key.\n\tif (!(exportName in module)) return undefined;\n\n\t// OWN properties only, and `in` alone was not enough. It walks the prototype\n\t// chain, so `\"constructor\" in module` is true for any plain object and\n\t// `module.constructor` is `Object` — a function WITH a prototype, which both\n\t// checks below accept. The locator would have handed back a class the barrel\n\t// never exported. `toString` and its siblings only escaped by luck: built-in\n\t// methods have no `.prototype`.\n\t//\n\t// It is asked SECOND, never first: `in` is what tolerates a vitest module\n\t// proxy, and this narrowing is only ever consulted for a key that already\n\t// exists. A real ES namespace has a null prototype, so nothing changes there.\n\tif (!Object.hasOwn(module, exportName)) return undefined;\n\n\tconst candidate = (module as Record<string, unknown>)[exportName];\n\n\t// `typeof === \"function\"` would also admit a plain function: it has a\n\t// `prototype` too. They cannot be told apart before calling, and that is a\n\t// deliberate boundary — the locator trusts the barrel, and `@lankajs/tool-di`\n\t// verifies the barrel.\n\treturn typeof candidate === \"function\" && candidate.prototype\n\t\t? (candidate as new () => TInstance)\n\t\t: undefined;\n}\n"],"mappings":";AAoBO,SAAS,kBACf,QACA,YACoC;AAIpC,MAAI,EAAE,cAAc,QAAS,QAAO;AAYpC,MAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,EAAG,QAAO;AAE/C,QAAM,YAAa,OAAmC,UAAU;AAMhE,SAAO,OAAO,cAAc,cAAc,UAAU,YAChD,YACD;AACJ;","names":[]}
@@ -1,3 +1,9 @@
1
+ import {
2
+ ALankaScenario,
3
+ LankaScenarioVMRegistry,
4
+ LankaScenariosRegistry,
5
+ lankaEventBus
6
+ } from "./chunk-NWEHOMTS.js";
1
7
  import {
2
8
  lankaLogger
3
9
  } from "./chunk-FII3PW2G.js";
@@ -6,309 +12,7 @@ import {
6
12
  requireActiveRuntime
7
13
  } from "./chunk-XGMXT4XZ.js";
8
14
 
9
- // src/scenario/event-bus/_facades/lanka-event-bus/lankaEventBus.ts
10
- var bus = () => requireActiveRuntime().eventBus;
11
- var lankaEventBus = Object.freeze({
12
- enableLogs: () => {
13
- bus().enableLogs();
14
- },
15
- disableLogs: () => {
16
- bus().disableLogs();
17
- },
18
- registerEvent: (eventType, metadata) => {
19
- bus().registerEvent(eventType, metadata);
20
- },
21
- getRegisteredEvents: () => bus().getRegisteredEvents(),
22
- getEventInfo: (eventType) => bus().getEventInfo(eventType),
23
- getSubscriptions: (eventType) => bus().getSubscriptions(eventType),
24
- subscribe: (eventType, callback, options) => bus().subscribe(eventType, callback, options),
25
- unsubscribe: (eventType, callback) => {
26
- bus().unsubscribe(eventType, callback);
27
- },
28
- dispatch: (eventType, data, usedBy) => {
29
- bus().dispatch(eventType, data, usedBy);
30
- },
31
- addMiddleware: (middleware) => {
32
- bus().addMiddleware(middleware);
33
- },
34
- removeMiddleware: (middleware) => {
35
- bus().removeMiddleware(middleware);
36
- },
37
- addObserver: (observer) => {
38
- bus().addObserver(observer);
39
- },
40
- removeObserver: (observer) => {
41
- bus().removeObserver(observer);
42
- },
43
- getEventLogs: (eventType, limit = 100) => bus().getEventLogs(eventType, limit),
44
- clearEvent: (eventType) => {
45
- bus().clearEvent(eventType);
46
- },
47
- clearAllEvents: () => {
48
- bus().clearAllEvents();
49
- },
50
- reset: () => {
51
- bus().reset();
52
- }
53
- });
54
-
55
- // src/scenario/_registries/lanka-scenario-vm-registry/LankaScenarioVMRegistry.ts
56
- var LankaScenarioVMRegistry = class {
57
- registeredViewModels = /* @__PURE__ */ new Set();
58
- /**
59
- * Public: the registry belongs to a framework instance rather than to the
60
- * module.
61
- */
62
- constructor() {
63
- }
64
- /**
65
- * The active instance's registry, for callers that cannot hold one — the
66
- * static `LankaScenarioBootstrap`. Instance holders read `lanka.viewModels`.
67
- */
68
- static getInstance() {
69
- return requireActiveRuntime().viewModels;
70
- }
71
- /** Whether this ViewModel is already registered. */
72
- isRegistered(viewModel) {
73
- return this.registeredViewModels.has(viewModel);
74
- }
75
- /**
76
- * Registers a ViewModel.
77
- *
78
- * @returns `false` when it was already registered
79
- */
80
- register(viewModel) {
81
- if (this.registeredViewModels.has(viewModel)) {
82
- return false;
83
- }
84
- this.registeredViewModels.add(viewModel);
85
- return true;
86
- }
87
- /** Removes a ViewModel from the registry. */
88
- unregister(viewModel) {
89
- this.registeredViewModels.delete(viewModel);
90
- }
91
- /** Every registered ViewModel. */
92
- getAllViewModels() {
93
- return Array.from(this.registeredViewModels);
94
- }
95
- /**
96
- * Clears every registered ViewModel. Required by tests.
97
- */
98
- clear() {
99
- this.registeredViewModels.clear();
100
- }
101
- /**
102
- * Unsubscribes every registered ViewModel from its scenarios and clears the
103
- * registry.
104
- *
105
- * Without it tests are not isolated: a subscription leaks from test to test.
106
- */
107
- resetAll() {
108
- this.registeredViewModels.forEach((vm) => {
109
- try {
110
- vm.resetScenario();
111
- } catch {
112
- }
113
- });
114
- this.clear();
115
- }
116
- };
117
-
118
- // src/scenario/_registries/lanka-scenarios-registry/LankaScenariosRegistry.ts
119
- var release = (scenario) => {
120
- if (!scenario.cleanup) return;
121
- try {
122
- scenario.cleanup();
123
- } catch (error) {
124
- lankaLogger.printScenarioLog(`Error cleaning up scenario "${scenario.name}":`, error);
125
- }
126
- };
127
- var LankaScenariosRegistry = class {
128
- registeredScenarios = /* @__PURE__ */ new Map();
129
- scenarioMetadata = /* @__PURE__ */ new Map();
130
- /**
131
- * Public: the registry belongs to a framework instance rather than to the
132
- * module.
133
- */
134
- constructor() {
135
- }
136
- /**
137
- * The active instance's registry, for callers that cannot hold one:
138
- * `ALankaScenario` (a base class the consumer extends) and the static
139
- * `LankaScenarioBootstrap`. Instance holders read `lanka.scenarios`.
140
- */
141
- static getInstance() {
142
- return requireActiveRuntime().scenarios;
143
- }
144
- /**
145
- * Registers a scenario by hand.
146
- *
147
- * @param scenario What to register
148
- * @returns `false` when it was already registered
149
- */
150
- register(scenario) {
151
- if (this.registeredScenarios.has(scenario.name)) {
152
- return false;
153
- }
154
- this.registeredScenarios.set(scenario.name, scenario);
155
- this.scenarioMetadata.set(scenario.name, {
156
- scenario,
157
- name: scenario.name,
158
- eventType: scenario.eventType,
159
- dataTypeName: scenario.dataTypeName,
160
- isRegistered: true
161
- });
162
- return true;
163
- }
164
- /**
165
- * Removes a scenario, calling its `cleanup` if it declared one.
166
- *
167
- * @param scenarioName Name of the scenario to unregister
168
- * @returns true if unregistered successfully, false if not found
169
- */
170
- unregister(scenarioName) {
171
- const scenario = this.registeredScenarios.get(scenarioName);
172
- if (!scenario) {
173
- return false;
174
- }
175
- const metadata = this.scenarioMetadata.get(scenarioName);
176
- if (metadata) {
177
- metadata.isRegistered = false;
178
- }
179
- this.registeredScenarios.delete(scenarioName);
180
- release(scenario);
181
- return true;
182
- }
183
- /**
184
- * Get metadata for a specific scenario
185
- * @param scenarioName Name of the scenario
186
- * @returns Scenario metadata or undefined if not found
187
- */
188
- getMetadata(scenarioName) {
189
- return this.scenarioMetadata.get(scenarioName);
190
- }
191
- /** Every registered scenario. */
192
- getAllScenarios() {
193
- return Array.from(this.registeredScenarios.values());
194
- }
195
- /** Metadata of every scenario. */
196
- getAllMetadata() {
197
- return Array.from(this.scenarioMetadata.values());
198
- }
199
- /** Whether a scenario with this name is registered. */
200
- isRegistered(scenarioName) {
201
- return this.registeredScenarios.has(scenarioName);
202
- }
203
- /**
204
- * Collects every scenario that registered itself at construction.
205
- */
206
- collectAutoRegisteredScenarios() {
207
- const autoRegistered = ALankaScenario.getAutoRegisteredScenarios();
208
- autoRegistered.forEach((scenario) => {
209
- if (!this.registeredScenarios.has(scenario.name)) {
210
- this.register(scenario);
211
- }
212
- });
213
- }
214
- /**
215
- * A scenario by name.
216
- *
217
- * @returns `undefined` when there is none
218
- */
219
- getScenarioByName(scenarioName) {
220
- return this.registeredScenarios.get(scenarioName);
221
- }
222
- /** Every registered ViewModel. */
223
- getAllViewModels() {
224
- return LankaScenarioVMRegistry.getInstance().getAllViewModels();
225
- }
226
- /**
227
- * Removes every scenario, calling each one's `cleanup`.
228
- *
229
- * What `dispose()` and the between-tests reset go through: `initialize` ran
230
- * for every scenario at bootstrap, and this is the one moment its mirror
231
- * image can run for all of them.
232
- */
233
- clear() {
234
- const scenarios = [...this.registeredScenarios.values()];
235
- this.registeredScenarios.clear();
236
- this.scenarioMetadata.clear();
237
- for (const scenario of scenarios) release(scenario);
238
- }
239
- };
240
-
241
- // src/scenario/_abstractions/lanka-scenario/ALankaScenario.ts
242
- var ALankaScenario = class _ALankaScenario {
243
- /** A subclass sets this to opt out of self-registration. */
244
- static skipAutoRegistration;
245
- /**
246
- * The self-registration pool.
247
- *
248
- * Class-level deliberately: a registry of DEFINITIONS, not runtime state. The
249
- * classes come from one barrel and both framework instances must see the same
250
- * list — splitting it would be divergence, not isolation.
251
- */
252
- static autoRegisteredScenarios = /* @__PURE__ */ new Set();
253
- /** Registers the scenario itself unless the subclass opted out. */
254
- constructor() {
255
- const constructor = this.constructor;
256
- if (!constructor.skipAutoRegistration) {
257
- _ALankaScenario.autoRegisteredScenarios.add(this);
258
- }
259
- }
260
- /**
261
- * Every scenario that registered itself.
262
- *
263
- * @internal
264
- */
265
- static getAutoRegisteredScenarios() {
266
- return Array.from(_ALankaScenario.autoRegisteredScenarios);
267
- }
268
- /**
269
- * Clears the auto-registration pool. Required by tests.
270
- * @internal
271
- */
272
- static clearAutoRegisteredScenarios() {
273
- _ALankaScenario.autoRegisteredScenarios.clear();
274
- }
275
- /**
276
- * Registers the scenario by hand.
277
- *
278
- * @returns `false` when it was already registered
279
- */
280
- register() {
281
- return LankaScenariosRegistry.getInstance().register(this);
282
- }
283
- /**
284
- * Removes the scenario from the registry.
285
- *
286
- * @returns `false` when it was not there
287
- */
288
- unregister() {
289
- return LankaScenariosRegistry.getInstance().unregister(this.name);
290
- }
291
- trigger(data) {
292
- lankaLogger.printScenarioLog("TRIGGER Scenario", this.name, data);
293
- lankaEventBus.dispatch(this.eventType, data, this.name);
294
- }
295
- /**
296
- * Subscribes a handler and returns an unsubscribe function.
297
- *
298
- * Without the return, unsubscribing is possible only by callback identity, and
299
- * every ViewModel factory has to keep a map of references for it.
300
- */
301
- subscribe(callback, options) {
302
- lankaLogger.printScenarioLog("SUBSCRIBE Scenario", this.name, this.dataTypeName);
303
- return lankaEventBus.subscribe(this.eventType, callback, {
304
- ...options,
305
- usedBy: options?.usedBy ?? this.name
306
- });
307
- }
308
- };
309
-
310
15
  // src/scenario/lanka-scenario-bootstrap/LankaScenarioBootstrap.ts
311
- import * as ScenariosModule from "@lanka_di/Scenarios";
312
16
  var LankaScenarioBootstrap = class {
313
17
  /**
314
18
  * The bootstrapped flag and the set of initialised VMs live on the INSTANCE.
@@ -327,11 +31,11 @@ var LankaScenarioBootstrap = class {
327
31
  const pooled = new Set(
328
32
  ALankaScenario.getAutoRegisteredScenarios().map((scenario) => scenario.constructor)
329
33
  );
330
- for (const exported of Object.values(ScenariosModule)) {
331
- if (typeof exported !== "function") continue;
332
- if (pooled.has(exported)) continue;
34
+ const declared = requireActiveRuntime().locators.scenarios.getDeclaredScenarioClasses();
35
+ for (const Scenario of declared) {
36
+ if (pooled.has(Scenario)) continue;
333
37
  try {
334
- new exported();
38
+ new Scenario();
335
39
  } catch {
336
40
  }
337
41
  }
@@ -541,10 +245,6 @@ var LankaScenarioBootstrap = class {
541
245
  var lankaScenarioBootstrap = new LankaScenarioBootstrap();
542
246
 
543
247
  export {
544
- lankaEventBus,
545
- ALankaScenario,
546
- LankaScenarioVMRegistry,
547
- LankaScenariosRegistry,
548
248
  lankaScenarioBootstrap
549
249
  };
550
- //# sourceMappingURL=chunk-EYDMBI5T.js.map
250
+ //# sourceMappingURL=chunk-MKKMTLOY.js.map