lanka 1.3.0 → 2.0.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.
- package/README.md +1 -1
- package/dist/ILankaReadableVM-BoPzHEPV.d.ts +72 -0
- package/dist/{LankaScenarioLocator-CAENLhDO.d.ts → LankaScenarioLocator-Dki2Es3O.d.ts} +2 -2
- package/dist/{LankaSharedStoreLocator-zS2kLu-S.d.ts → LankaSharedStoreLocator-jsz_gnUm.d.ts} +1 -1
- package/dist/_extend/index.d.ts +228 -5
- package/dist/_extend/index.js +137 -8
- package/dist/_extend/index.js.map +1 -1
- package/dist/_internal/index.d.ts +3 -3
- package/dist/_internal/index.js +9 -3
- package/dist/_internal/index.js.map +1 -1
- package/dist/{activeRuntime-BYd2D6Lx.d.ts → activeRuntime-BO-qY0yY.d.ts} +50 -3
- package/dist/bootstrap/index.d.ts +6 -6
- package/dist/bootstrap/index.js +7 -8
- package/dist/{chunk-D27MREPB.js → chunk-7DQUF2QR.js} +2 -2
- package/dist/{chunk-UJEC7H6K.js → chunk-BHQ2SQ7P.js} +2 -2
- package/dist/chunk-EYDMBI5T.js +550 -0
- package/dist/chunk-EYDMBI5T.js.map +1 -0
- package/dist/{chunk-C2HP7CRD.js → chunk-FII3PW2G.js} +2 -2
- package/dist/{chunk-DTO27QFR.js → chunk-H5TIUKRK.js} +2 -2
- package/dist/{chunk-NDCJBO47.js → chunk-O5EUTNR6.js} +2 -2
- package/dist/{chunk-RKYKK6MN.js → chunk-RUMUFHSL.js} +2 -2
- package/dist/{chunk-UBGXDTXC.js → chunk-SZVNPK24.js} +11 -13
- package/dist/chunk-SZVNPK24.js.map +1 -0
- package/dist/chunk-UDP6IXDS.js +17 -0
- package/dist/chunk-UDP6IXDS.js.map +1 -0
- package/dist/{chunk-5MAQVBI2.js → chunk-UMPSR4US.js} +3 -3
- package/dist/{chunk-BGVDPDX4.js → chunk-XGMXT4XZ.js} +20 -3
- package/dist/chunk-XGMXT4XZ.js.map +1 -0
- package/dist/config/index.js +3 -3
- package/dist/{createLanka-NrlvN-WQ.d.ts → createLanka-x4oSMs7P.d.ts} +2 -2
- package/dist/{createLankaScope-BiFxNQgl.d.ts → createLankaScope-DomNbEvb.d.ts} +1 -1
- package/dist/errors/index.js +3 -3
- package/dist/gateway/index.js +9 -9
- package/dist/index.d.ts +5 -5
- package/dist/index.js +8 -9
- package/dist/locator/index.d.ts +2 -2
- package/dist/locator/index.js +2 -2
- package/dist/logger/index.js +3 -3
- package/dist/mock/index.js +3 -3
- package/dist/scenario/index.d.ts +25 -0
- package/dist/scenario/index.js +6 -8
- package/dist/scenario/index.js.map +1 -1
- package/dist/stream/index.d.ts +5 -5
- package/dist/viewmodel/index.d.ts +137 -27
- package/dist/viewmodel/index.js +94 -126
- package/dist/viewmodel/index.js.map +1 -1
- package/package.json +3 -4
- package/skills/lanka-core/SKILL.md +18 -16
- package/skills/lanka-core/reference.md +135 -58
- package/skills/lanka-packages/SKILL.md +94 -22
- package/dist/chunk-B7EYIAW7.js +0 -216
- package/dist/chunk-B7EYIAW7.js.map +0 -1
- package/dist/chunk-BGVDPDX4.js.map +0 -1
- package/dist/chunk-O5ROO7QF.js +0 -315
- package/dist/chunk-O5ROO7QF.js.map +0 -1
- package/dist/chunk-UBGXDTXC.js.map +0 -1
- /package/dist/{chunk-D27MREPB.js.map → chunk-7DQUF2QR.js.map} +0 -0
- /package/dist/{chunk-UJEC7H6K.js.map → chunk-BHQ2SQ7P.js.map} +0 -0
- /package/dist/{chunk-C2HP7CRD.js.map → chunk-FII3PW2G.js.map} +0 -0
- /package/dist/{chunk-DTO27QFR.js.map → chunk-H5TIUKRK.js.map} +0 -0
- /package/dist/{chunk-NDCJBO47.js.map → chunk-O5EUTNR6.js.map} +0 -0
- /package/dist/{chunk-RKYKK6MN.js.map → chunk-RUMUFHSL.js.map} +0 -0
- /package/dist/{chunk-5MAQVBI2.js.map → chunk-UMPSR4US.js.map} +0 -0
package/dist/chunk-B7EYIAW7.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ALankaScenario,
|
|
3
|
-
LankaScenarioVMRegistry,
|
|
4
|
-
LankaScenariosRegistry,
|
|
5
|
-
lankaEventBus
|
|
6
|
-
} from "./chunk-O5ROO7QF.js";
|
|
7
|
-
import {
|
|
8
|
-
lankaLogger
|
|
9
|
-
} from "./chunk-C2HP7CRD.js";
|
|
10
|
-
import {
|
|
11
|
-
getActiveRuntime,
|
|
12
|
-
requireActiveRuntime
|
|
13
|
-
} from "./chunk-BGVDPDX4.js";
|
|
14
|
-
|
|
15
|
-
// src/scenario/lanka-scenario-bootstrap/LankaScenarioBootstrap.ts
|
|
16
|
-
import * as ScenariosModule from "@lanka_di/Scenarios";
|
|
17
|
-
var LankaScenarioBootstrap = class {
|
|
18
|
-
/**
|
|
19
|
-
* The bootstrapped flag and the set of initialised VMs live on the INSTANCE.
|
|
20
|
-
*
|
|
21
|
-
* As static fields, a second framework in the same process would exit
|
|
22
|
-
* `bootstrap()` on someone else's flag — never starting at all, with no symptom
|
|
23
|
-
* except that no scenario works.
|
|
24
|
-
*/
|
|
25
|
-
get state() {
|
|
26
|
-
return requireActiveRuntime().scenarioState;
|
|
27
|
-
}
|
|
28
|
-
isScenarioLayerBootstrapped() {
|
|
29
|
-
return this.state.bootstrapped;
|
|
30
|
-
}
|
|
31
|
-
forceInstantiateAllScenarios() {
|
|
32
|
-
const pooled = new Set(
|
|
33
|
-
ALankaScenario.getAutoRegisteredScenarios().map((scenario) => scenario.constructor)
|
|
34
|
-
);
|
|
35
|
-
for (const exported of Object.values(ScenariosModule)) {
|
|
36
|
-
if (typeof exported !== "function") continue;
|
|
37
|
-
if (pooled.has(exported)) continue;
|
|
38
|
-
try {
|
|
39
|
-
new exported();
|
|
40
|
-
} catch {
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
registerScenarioEvents(scenarios) {
|
|
45
|
-
const registeredEventTypes = /* @__PURE__ */ new Set();
|
|
46
|
-
scenarios.forEach((scenario) => {
|
|
47
|
-
if (!registeredEventTypes.has(scenario.eventType)) {
|
|
48
|
-
registeredEventTypes.add(scenario.eventType);
|
|
49
|
-
lankaLogger.printScenarioLog("REGISTER SCENARIO EVENT", scenario.name);
|
|
50
|
-
lankaEventBus.registerEvent(scenario.eventType, {
|
|
51
|
-
dataType: scenario.dataTypeName,
|
|
52
|
-
description: `Scenario: ${scenario.name}`,
|
|
53
|
-
usedBy: [scenario.name],
|
|
54
|
-
priority: 0
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
if (scenario.initialize) {
|
|
58
|
-
lankaLogger.printScenarioLog("INITIALIZE SCENARIO", scenario.name);
|
|
59
|
-
scenario.initialize();
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
initializeAlreadyCreatedViewModels() {
|
|
64
|
-
const viewModels = LankaScenarioVMRegistry.getInstance().getAllViewModels();
|
|
65
|
-
viewModels.forEach((vm) => {
|
|
66
|
-
if (!this.state.initialized.has(vm)) {
|
|
67
|
-
this.state.initialized.add(vm);
|
|
68
|
-
vm.initializeScenario();
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Brings up the scenario layer.
|
|
74
|
-
*
|
|
75
|
-
* Constructs the scenario classes so they can be collected, declares their
|
|
76
|
-
* events on the bus, calls `initialize()` where present, and initialises
|
|
77
|
-
* ViewModels that already exist — which happens in tests and under unusual
|
|
78
|
-
* import order.
|
|
79
|
-
*
|
|
80
|
-
* Idempotent.
|
|
81
|
-
*/
|
|
82
|
-
bootstrap() {
|
|
83
|
-
if (this.state.bootstrapped) return;
|
|
84
|
-
lankaLogger.printScenarioLog("BOOTSTRAP SCENARIOS START");
|
|
85
|
-
this.forceInstantiateAllScenarios();
|
|
86
|
-
const registry = LankaScenariosRegistry.getInstance();
|
|
87
|
-
registry.collectAutoRegisteredScenarios();
|
|
88
|
-
const scenarios = registry.getAllScenarios();
|
|
89
|
-
this.registerScenarioEvents(scenarios);
|
|
90
|
-
this.state.bootstrapped = true;
|
|
91
|
-
this.adoptDeclaredViewModels();
|
|
92
|
-
this.initializeAlreadyCreatedViewModels();
|
|
93
|
-
lankaLogger.printScenarioLog("BOOTSTRAP SCENARIOS FINISH");
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Called by a ViewModel factory when the ViewModel declares scenario handlers.
|
|
97
|
-
*
|
|
98
|
-
* Registers the ViewModel and, if the layer is already up, initialises it
|
|
99
|
-
* immediately. Duplicate registration and duplicate initialisation are
|
|
100
|
-
* impossible.
|
|
101
|
-
*
|
|
102
|
-
* @param viewModel What to register
|
|
103
|
-
* @param name Name for the log
|
|
104
|
-
*/
|
|
105
|
-
/**
|
|
106
|
-
* ViewModels DECLARED in this process.
|
|
107
|
-
*
|
|
108
|
-
* Module-level deliberately, the same case as the scenario pool: a registry of
|
|
109
|
-
* DEFINITIONS, not runtime state. Splitting it between instances would be
|
|
110
|
-
* divergence, not isolation — the classes come from the same modules and both
|
|
111
|
-
* instances must see one list.
|
|
112
|
-
*
|
|
113
|
-
* Two reasons it exists:
|
|
114
|
-
*
|
|
115
|
-
* 1. Declaring a ViewModel is a declaration, not work. A screen file creates it
|
|
116
|
-
* at module level, and import order decides whether that happens before or
|
|
117
|
-
* after `createLanka()`. Requiring a live instance at declaration time
|
|
118
|
-
* requires an import order the consumer does not control.
|
|
119
|
-
* 2. Instances come one after another: every test creates its own. The list is
|
|
120
|
-
* NOT drained by the first — otherwise the second instance would know no
|
|
121
|
-
* module-level ViewModel and its `dispose()` would not remove their
|
|
122
|
-
* subscriptions, so a test would receive events the previous one subscribed
|
|
123
|
-
* to.
|
|
124
|
-
*/
|
|
125
|
-
declaredViewModels = [];
|
|
126
|
-
/**
|
|
127
|
-
* Registers everything declared into a NEW instance.
|
|
128
|
-
*
|
|
129
|
-
* Called twice, and the second call is the one that makes this work on a
|
|
130
|
-
* server: `createLanka` calls it, and so does `bootstrap()`.
|
|
131
|
-
*
|
|
132
|
-
* The reason is an order nobody can change. Where "which instance is active"
|
|
133
|
-
* is answered by a RESOLVER — one instance per request, the shape
|
|
134
|
-
* `@lankajs/host` installs — an instance becomes findable only once the CALLER
|
|
135
|
-
* has put it in its store, and a caller can only do that after `createLanka`
|
|
136
|
-
* has returned. So during creation the answer is honestly "none", and asking
|
|
137
|
-
* for it threw: every server render of an application with a module-level
|
|
138
|
-
* ViewModel failed inside the call that was creating the scope, with a message
|
|
139
|
-
* about running outside one.
|
|
140
|
-
*
|
|
141
|
-
* Skipping is safe precisely because bootstrap adopts again. It is idempotent
|
|
142
|
-
* at the other end too: `attachViewModel` returns early for a ViewModel the
|
|
143
|
-
* registry already holds.
|
|
144
|
-
*/
|
|
145
|
-
adoptDeclaredViewModels() {
|
|
146
|
-
if (!getActiveRuntime()) return;
|
|
147
|
-
for (const { viewModel, name } of [...this.declaredViewModels]) {
|
|
148
|
-
this.attachViewModel(viewModel, name);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
registerViewModel(viewModel, name) {
|
|
152
|
-
const isKnown = this.declaredViewModels.some(
|
|
153
|
-
(declared) => declared.viewModel === viewModel
|
|
154
|
-
);
|
|
155
|
-
if (!isKnown) this.declaredViewModels.push({ viewModel, name });
|
|
156
|
-
if (!getActiveRuntime()) return;
|
|
157
|
-
this.attachViewModel(viewModel, name);
|
|
158
|
-
}
|
|
159
|
-
attachViewModel(viewModel, name) {
|
|
160
|
-
const registry = LankaScenarioVMRegistry.getInstance();
|
|
161
|
-
if (registry.isRegistered(viewModel)) {
|
|
162
|
-
if (name) {
|
|
163
|
-
lankaLogger.printViewModelLog("VM Already Registered (skipped)", name);
|
|
164
|
-
}
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
registry.register(viewModel);
|
|
168
|
-
if (name) {
|
|
169
|
-
lankaLogger.printViewModelLog("Register Scenario VM", name);
|
|
170
|
-
}
|
|
171
|
-
if (this.state.bootstrapped) {
|
|
172
|
-
if (!this.state.initialized.has(viewModel)) {
|
|
173
|
-
this.state.initialized.add(viewModel);
|
|
174
|
-
viewModel.initializeScenario();
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Resets the whole scenario layer. Without it tests are not isolated.
|
|
180
|
-
*
|
|
181
|
-
* Clears the self-registration list, the scenario registry with its metadata,
|
|
182
|
-
* the ViewModel registry together with all their subscriptions, and the bus —
|
|
183
|
-
* events and
|
|
184
|
-
* middleware.
|
|
185
|
-
*
|
|
186
|
-
* What it does NOT clear by default is which ViewModels were DECLARED, and
|
|
187
|
-
* that default is load-bearing: a module-level ViewModel is built once per
|
|
188
|
-
* process, so the declaration is the only thing that lets a second instance
|
|
189
|
-
* find it. Drop it and its handlers bind to nothing, silently, for the rest of
|
|
190
|
-
* the process — see `declaredViewModels`.
|
|
191
|
-
*
|
|
192
|
-
* `withDeclarations` is for the case that default gets wrong: a suite that
|
|
193
|
-
* builds ViewModels inside test BODIES. Those are declared like any other and
|
|
194
|
-
* nothing un-declares them, so the next bootstrap re-adopts every one ever
|
|
195
|
-
* built and a finished test's handlers run again — against the gateway that
|
|
196
|
-
* test built, which is somebody else's double. Forgetting is not a tombstone:
|
|
197
|
-
* a ViewModel declared again afterwards is adopted again.
|
|
198
|
-
*
|
|
199
|
-
* @param config `withDeclarations` also forgets which ViewModels exist
|
|
200
|
-
*/
|
|
201
|
-
reset(config = {}) {
|
|
202
|
-
ALankaScenario.clearAutoRegisteredScenarios();
|
|
203
|
-
LankaScenariosRegistry.getInstance().clear();
|
|
204
|
-
LankaScenarioVMRegistry.getInstance().resetAll();
|
|
205
|
-
lankaEventBus.clearAllEvents();
|
|
206
|
-
this.state.bootstrapped = false;
|
|
207
|
-
this.state.initialized = /* @__PURE__ */ new WeakSet();
|
|
208
|
-
if (config.withDeclarations) this.declaredViewModels.length = 0;
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
var lankaScenarioBootstrap = new LankaScenarioBootstrap();
|
|
212
|
-
|
|
213
|
-
export {
|
|
214
|
-
lankaScenarioBootstrap
|
|
215
|
-
};
|
|
216
|
-
//# sourceMappingURL=chunk-B7EYIAW7.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/scenario/lanka-scenario-bootstrap/LankaScenarioBootstrap.ts"],"sourcesContent":["import type { ILankaScenario } from \"../_interfaces/ILankaScenario\";\nimport type { ILankaScenarioVM } from \"../_interfaces/ILankaScenarioVM\";\nimport type { ILankaScenarioResetConfig } from \"../_interfaces/ILankaScenarioResetConfig\";\nimport { LankaScenariosRegistry } from \"../_registries/lanka-scenarios-registry/LankaScenariosRegistry\";\nimport { LankaScenarioVMRegistry } from \"../_registries/lanka-scenario-vm-registry/LankaScenarioVMRegistry\";\nimport { ALankaScenario } from \"../_abstractions/lanka-scenario/ALankaScenario\";\nimport { lankaLogger } from \"../../logger/lanka-logger/LankaLogger\";\n\n/**\n * Brings up the scenario layer — deliberately React-free.\n *\n * Two jobs: declare every scenario's events on the bus as early as possible,\n * before the first ViewModel exists; and let a ViewModel raise its own\n * subscriptions at construction.\n *\n * Called from the application entry point before ViewModels are imported.\n */\n\n// The barrel of every scenario class: what keeps bootstrap in step with the list.\nimport * as ScenariosModule from \"@lanka_di/Scenarios\";\nimport { lankaEventBus } from \"../event-bus/_facades/lanka-event-bus/lankaEventBus\";\nimport {\n\tgetActiveRuntime,\n\trequireActiveRuntime,\n} from \"../../_internal/active-runtime/activeRuntime\";\n\n/**\n * Bootstrapping the scenario layer, for callers with no instance in hand.\n *\n * An ordinary class with an ordinary instance: the declared-ViewModel list below\n * is deliberately shared across instances — every test builds a new framework and\n * module-level ViewModels are declared once — so the single instance IS the\n * shared list, and a second one would be a second list nobody adopts.\n */\nexport class LankaScenarioBootstrap {\n\t/**\n\t * The bootstrapped flag and the set of initialised VMs live on the INSTANCE.\n\t *\n\t * As static fields, a second framework in the same process would exit\n\t * `bootstrap()` on someone else's flag — never starting at all, with no symptom\n\t * except that no scenario works.\n\t */\n\tprivate get state() {\n\t\treturn requireActiveRuntime().scenarioState;\n\t}\n\n\tpublic isScenarioLayerBootstrapped(): boolean {\n\t\treturn this.state.bootstrapped;\n\t}\n\n\tprivate forceInstantiateAllScenarios(): void {\n\t\t// Every class the pool already holds an instance of. Constructing it again\n\t\t// would add a second instance to a pool nothing ever drains: each bootstrap\n\t\t// — one per framework instance, one per test — grew it by the whole barrel,\n\t\t// and both `collectAutoRegisteredScenarios` and the locator's fallback walk\n\t\t// it in full.\n\t\tconst pooled = new Set(\n\t\t\tALankaScenario.getAutoRegisteredScenarios().map((scenario) => scenario.constructor),\n\t\t);\n\n\t\tfor (const exported of Object.values(ScenariosModule)) {\n\t\t\t// Only class constructors are relevant.\n\t\t\tif (typeof exported !== \"function\") continue;\n\t\t\tif (pooled.has(exported)) continue;\n\n\t\t\ttry {\n\t\t\t\t// Constructing an ALankaScenario subclass puts it into the\n\t\t\t\t// self-registration pool — see ALankaScenario.\n\t\t\t\tnew (exported as unknown as new () => unknown)();\n\t\t\t} catch {\n\t\t\t\t// Not every export is constructible; skip those.\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate registerScenarioEvents(scenarios: ILankaScenario<unknown>[]): void {\n\t\tconst registeredEventTypes = new Set<string>();\n\n\t\tscenarios.forEach((scenario) => {\n\t\t\tif (!registeredEventTypes.has(scenario.eventType)) {\n\t\t\t\tregisteredEventTypes.add(scenario.eventType);\n\n\t\t\t\tlankaLogger.printScenarioLog(\"REGISTER SCENARIO EVENT\", scenario.name);\n\t\t\t\tlankaEventBus.registerEvent(scenario.eventType, {\n\t\t\t\t\tdataType: scenario.dataTypeName,\n\t\t\t\t\tdescription: `Scenario: ${scenario.name}`,\n\t\t\t\t\tusedBy: [scenario.name],\n\t\t\t\t\tpriority: 0,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (scenario.initialize) {\n\t\t\t\tlankaLogger.printScenarioLog(\"INITIALIZE SCENARIO\", scenario.name);\n\t\t\t\tscenario.initialize();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate initializeAlreadyCreatedViewModels(): void {\n\t\tconst viewModels = LankaScenarioVMRegistry.getInstance().getAllViewModels();\n\t\tviewModels.forEach((vm) => {\n\t\t\tif (!this.state.initialized.has(vm)) {\n\t\t\t\tthis.state.initialized.add(vm);\n\t\t\t\tvm.initializeScenario();\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Brings up the scenario layer.\n\t *\n\t * Constructs the scenario classes so they can be collected, declares their\n\t * events on the bus, calls `initialize()` where present, and initialises\n\t * ViewModels that already exist — which happens in tests and under unusual\n\t * import order.\n\t *\n\t * Idempotent.\n\t */\n\tpublic bootstrap(): void {\n\t\tif (this.state.bootstrapped) return;\n\n\t\tlankaLogger.printScenarioLog(\"BOOTSTRAP SCENARIOS START\");\n\n\t\t// Instances must exist, or the registry has nothing to collect.\n\t\tthis.forceInstantiateAllScenarios();\n\n\t\tconst registry = LankaScenariosRegistry.getInstance();\n\t\tregistry.collectAutoRegisteredScenarios();\n\n\t\tconst scenarios = registry.getAllScenarios();\n\t\tthis.registerScenarioEvents(scenarios);\n\n\t\tthis.state.bootstrapped = true;\n\n\t\t// The second adoption. On a server this is the FIRST one that can succeed:\n\t\t// the instance is in its caller's store by now, and creation's attempt was\n\t\t// made before it could be. In a browser it is a no-op — creation adopted\n\t\t// already, and attaching is idempotent.\n\t\tthis.adoptDeclaredViewModels();\n\n\t\t// Some ViewModels may predate bootstrap — in tests, or under unusual import\n\t\t// order; initialise them now.\n\t\tthis.initializeAlreadyCreatedViewModels();\n\n\t\tlankaLogger.printScenarioLog(\"BOOTSTRAP SCENARIOS FINISH\");\n\t}\n\n\t/**\n\t * Called by a ViewModel factory when the ViewModel declares scenario handlers.\n\t *\n\t * Registers the ViewModel and, if the layer is already up, initialises it\n\t * immediately. Duplicate registration and duplicate initialisation are\n\t * impossible.\n\t *\n\t * @param viewModel What to register\n\t * @param name Name for the log\n\t */\n\t/**\n\t * ViewModels DECLARED in this process.\n\t *\n\t * Module-level deliberately, the same case as the scenario pool: a registry of\n\t * DEFINITIONS, not runtime state. Splitting it between instances would be\n\t * divergence, not isolation — the classes come from the same modules and both\n\t * instances must see one list.\n\t *\n\t * Two reasons it exists:\n\t *\n\t * 1. Declaring a ViewModel is a declaration, not work. A screen file creates it\n\t * at module level, and import order decides whether that happens before or\n\t * after `createLanka()`. Requiring a live instance at declaration time\n\t * requires an import order the consumer does not control.\n\t * 2. Instances come one after another: every test creates its own. The list is\n\t * NOT drained by the first — otherwise the second instance would know no\n\t * module-level ViewModel and its `dispose()` would not remove their\n\t * subscriptions, so a test would receive events the previous one subscribed\n\t * to.\n\t */\n\tprivate readonly declaredViewModels: { viewModel: ILankaScenarioVM; name?: string }[] = [];\n\n\t/**\n\t * Registers everything declared into a NEW instance.\n\t *\n\t * Called twice, and the second call is the one that makes this work on a\n\t * server: `createLanka` calls it, and so does `bootstrap()`.\n\t *\n\t * The reason is an order nobody can change. Where \"which instance is active\"\n\t * is answered by a RESOLVER — one instance per request, the shape\n\t * `@lankajs/host` installs — an instance becomes findable only once the CALLER\n\t * has put it in its store, and a caller can only do that after `createLanka`\n\t * has returned. So during creation the answer is honestly \"none\", and asking\n\t * for it threw: every server render of an application with a module-level\n\t * ViewModel failed inside the call that was creating the scope, with a message\n\t * about running outside one.\n\t *\n\t * Skipping is safe precisely because bootstrap adopts again. It is idempotent\n\t * at the other end too: `attachViewModel` returns early for a ViewModel the\n\t * registry already holds.\n\t */\n\tpublic adoptDeclaredViewModels(): void {\n\t\tif (!getActiveRuntime()) return;\n\n\t\tfor (const { viewModel, name } of [...this.declaredViewModels]) {\n\t\t\tthis.attachViewModel(viewModel, name);\n\t\t}\n\t}\n\n\tpublic registerViewModel(viewModel: ILankaScenarioVM, name?: string): void {\n\t\tconst isKnown = this.declaredViewModels.some(\n\t\t\t(declared) => declared.viewModel === viewModel,\n\t\t);\n\t\tif (!isKnown) this.declaredViewModels.push({ viewModel, name });\n\n\t\t// No instance yet: the declaration came before bootstrap, and whoever\n\t\t// bootstraps will pick it up.\n\t\tif (!getActiveRuntime()) return;\n\n\t\tthis.attachViewModel(viewModel, name);\n\t}\n\n\tprivate attachViewModel(viewModel: ILankaScenarioVM, name?: string): void {\n\t\tconst registry = LankaScenarioVMRegistry.getInstance();\n\n\t\t// Already registered — nothing to do.\n\t\tif (registry.isRegistered(viewModel)) {\n\t\t\tif (name) {\n\t\t\t\tlankaLogger.printViewModelLog(\"VM Already Registered (skipped)\", name);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Register it.\n\t\tregistry.register(viewModel);\n\n\t\tif (name) {\n\t\t\tlankaLogger.printViewModelLog(\"Register Scenario VM\", name);\n\t\t}\n\n\t\t// The layer is already up — initialise it now rather than at the next\n\t\t// bootstrap.\n\t\tif (this.state.bootstrapped) {\n\t\t\tif (!this.state.initialized.has(viewModel)) {\n\t\t\t\tthis.state.initialized.add(viewModel);\n\t\t\t\tviewModel.initializeScenario();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Resets the whole scenario layer. Without it tests are not isolated.\n\t *\n\t * Clears the self-registration list, the scenario registry with its metadata,\n\t * the ViewModel registry together with all their subscriptions, and the bus —\n\t * events and\n\t * middleware.\n\t *\n\t * What it does NOT clear by default is which ViewModels were DECLARED, and\n\t * that default is load-bearing: a module-level ViewModel is built once per\n\t * process, so the declaration is the only thing that lets a second instance\n\t * find it. Drop it and its handlers bind to nothing, silently, for the rest of\n\t * the process — see `declaredViewModels`.\n\t *\n\t * `withDeclarations` is for the case that default gets wrong: a suite that\n\t * builds ViewModels inside test BODIES. Those are declared like any other and\n\t * nothing un-declares them, so the next bootstrap re-adopts every one ever\n\t * built and a finished test's handlers run again — against the gateway that\n\t * test built, which is somebody else's double. Forgetting is not a tombstone:\n\t * a ViewModel declared again afterwards is adopted again.\n\t *\n\t * @param config `withDeclarations` also forgets which ViewModels exist\n\t */\n\tpublic reset(config: ILankaScenarioResetConfig = {}): void {\n\t\tALankaScenario.clearAutoRegisteredScenarios();\n\t\tLankaScenariosRegistry.getInstance().clear();\n\t\tLankaScenarioVMRegistry.getInstance().resetAll();\n\t\tlankaEventBus.clearAllEvents();\n\t\tthis.state.bootstrapped = false;\n\t\tthis.state.initialized = new WeakSet<ILankaScenarioVM>();\n\n\t\tif (config.withDeclarations) this.declaredViewModels.length = 0;\n\t}\n}\n\n/** The one every caller wants. */\nexport const lankaScenarioBootstrap = new LankaScenarioBootstrap();\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/_internal/active-runtime/activeRuntime.ts"],"sourcesContent":["import type { LankaEventBusInstance } from \"../../scenario/event-bus/lanka-event-bus-instance/LankaEventBusInstance\";\nimport type { LankaScenariosRegistry } from \"../../scenario/_registries/lanka-scenarios-registry/LankaScenariosRegistry\";\nimport type { LankaScenarioVMRegistry } from \"../../scenario/_registries/lanka-scenario-vm-registry/LankaScenarioVMRegistry\";\nimport type { ILankaRuntimeConfig } from \"../../config/_interfaces/ILankaRuntimeConfig\";\nimport type { ILankaInFlightCounter } from \"../../gateway/inflight/lankaHttpInFlight\";\nimport type { ILankaScenarioVM } from \"../../scenario/_interfaces/ILankaScenarioVM\";\nimport type { TLankaRequestMiddleware } from \"../../gateway/request/lankaRequestMiddleware\";\nimport type { LankaGatewayLocator } from \"../../locator/gateway/lanka-gateway-locator/LankaGatewayLocator\";\nimport type { LankaScenarioLocator } from \"../../locator/scenario/lanka-scenario-locator/LankaScenarioLocator\";\nimport type { LankaSingletonLocator } from \"../../locator/singleton/lanka-singleton-locator/LankaSingletonLocator\";\nimport type { LankaSharedStoreLocator } from \"../../locator/shared-store/lanka-shared-store-locator/LankaSharedStoreLocator\";\n\n/**\n * The pointer to the framework instance that ambient facades resolve to.\n *\n * ## Why this module is separate and imports no value\n *\n * Framework state belongs to an instance (`createLanka`), but the callers of\n * `lankaEventBus.dispatch`, `getLankaFlags()`, `lankaSingletons.foo`, `lankaHttpInFlight` —\n * the ambient facades cannot hold one — a user-extended `ALankaScenario`, the\n * static `LankaScenarioBootstrap` — so they ask which instance is active.\n *\n * The module is dependency-free DELIBERATELY: every import here is `import type`\n * and disappears at compile time. Otherwise there would be a cycle\n * `createLanka → locator → gateway → config → createLanka`, and module\n * evaluation order would start deciding what ends up `undefined`.\n *\n * This is still a global pointer. Real isolation belongs to whoever holds an\n * instance: their own bus, registries and counter. The facades serve ONE active\n * instance — exactly what an application with one needs.\n */\nexport interface ILankaRuntime {\n\treadonly eventBus: LankaEventBusInstance;\n\treadonly scenarios: LankaScenariosRegistry;\n\treadonly viewModels: LankaScenarioVMRegistry;\n\treadonly inFlight: ILankaInFlightCounter;\n\t/**\n\t * Request wrappers, in registration order: the first wraps them all.\n\t *\n\t * An array, not a set: order carries meaning — retry must sit outside request\n\t * signing, or the second attempt goes out unsigned.\n\t */\n\treadonly requestMiddleware: readonly TLankaRequestMiddleware[];\n\t/** Default response deadline. `undefined` means no limit. */\n\treadonly requestTimeoutMs: number | undefined;\n\treadonly locators: {\n\t\treadonly gateways: LankaGatewayLocator;\n\t\treadonly scenarios: LankaScenarioLocator;\n\t\treadonly singletons: LankaSingletonLocator;\n\t\treadonly sharedStores: LankaSharedStoreLocator;\n\t};\n\treadonly config: ILankaRuntimeConfig;\n\t/**\n\t * Bootstrap state of the scenario layer.\n\t *\n\t * A mutable object rather than contract fields: `LankaScenarioBootstrap` is an\n\t * ambient facade and must write here without holding an instance.\n\t */\n\treadonly scenarioState: {\n\t\tbootstrapped: boolean;\n\t\tinitialized: WeakSet<ILankaScenarioVM>;\n\t};\n\tsetConfig(patch: ILankaRuntimeConfig): void;\n\tgetFlags(): NonNullable<ILankaRuntimeConfig[\"flags\"]>;\n}\n\n/**\n * How \"which instance is active\" is answered.\n *\n * A strategy, because the answer depends on where the code runs. In a browser\n * there is one instance per document and a module-level pointer IS the answer. In\n * a server process there is one instance per REQUEST, and a module-level pointer\n * is the bug: the last request to start would answer for all of them.\n */\nexport type TLankaRuntimeResolver = () => ILankaRuntime | null;\n\nlet active: ILankaRuntime | null = null;\nlet resolveRuntime: TLankaRuntimeResolver | null = null;\n\nexport function setActiveRuntime(runtime: ILankaRuntime | null): void {\n\tactive = runtime;\n}\n\n/**\n * Replaces the strategy, or restores the default one with `null`.\n *\n * The installed resolver is the WHOLE answer — the module-level pointer is not\n * consulted behind it. That is deliberate: a fallback would turn \"this ran\n * outside a request\" from a loud error into one request quietly reading another\n * request's instance, which is the failure this seam exists to make impossible.\n *\n * Core ships no resolver and knows of none. What installs one is a package that\n * knows the shape of a request; core knows only that the question has more than\n * one answer.\n */\nexport function setLankaRuntimeResolver(resolver: TLankaRuntimeResolver | null): void {\n\tresolveRuntime = resolver;\n}\n\nexport function getActiveRuntime(): ILankaRuntime | null {\n\treturn resolveRuntime ? resolveRuntime() : active;\n}\n\n/**\n * The active instance, or a loud failure.\n *\n * No fallback, deliberately, for the same reason `getLankaHost` has none: an\n * instance created silently on the fly would mean subscriptions went to one bus\n * and events to another, and the divergence would surface three layers away.\n */\nexport function requireActiveRuntime(): ILankaRuntime {\n\t// The strategy is read here rather than through `getActiveRuntime()`: this is\n\t// the hottest path in the framework — every ambient facade, every request,\n\t// every dispatch — and a call that only forwards is a call that shows up in\n\t// `perf/`.\n\tconst runtime = resolveRuntime ? resolveRuntime() : active;\n\n\tif (!runtime) {\n\t\tthrow new Error(\n\t\t\tresolveRuntime\n\t\t\t\t? \"lanka has no instance for this call. A runtime resolver is installed and \" +\n\t\t\t\t\t\t\"answered with none, which on a server means the code ran outside a \" +\n\t\t\t\t\t\t\"request scope — start one, or do this work inside it.\"\n\t\t\t\t: \"lanka used before an instance existed. Call createLanka({ host }) and \" +\n\t\t\t\t\t\t\"activate it.\",\n\t\t);\n\t}\n\n\treturn runtime;\n}\n"],"mappings":";AA4EA,IAAI,SAA+B;AACnC,IAAI,iBAA+C;AAE5C,SAAS,iBAAiB,SAAqC;AACrE,WAAS;AACV;AAcO,SAAS,wBAAwB,UAA8C;AACrF,mBAAiB;AAClB;AAEO,SAAS,mBAAyC;AACxD,SAAO,iBAAiB,eAAe,IAAI;AAC5C;AASO,SAAS,uBAAsC;AAKrD,QAAM,UAAU,iBAAiB,eAAe,IAAI;AAEpD,MAAI,CAAC,SAAS;AACb,UAAM,IAAI;AAAA,MACT,iBACG,2MAGA;AAAA,IAEJ;AAAA,EACD;AAEA,SAAO;AACR;","names":[]}
|
package/dist/chunk-O5ROO7QF.js
DELETED
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
lankaLogger
|
|
3
|
-
} from "./chunk-C2HP7CRD.js";
|
|
4
|
-
import {
|
|
5
|
-
requireActiveRuntime
|
|
6
|
-
} from "./chunk-BGVDPDX4.js";
|
|
7
|
-
|
|
8
|
-
// src/scenario/event-bus/_facades/lanka-event-bus/lankaEventBus.ts
|
|
9
|
-
var bus = () => requireActiveRuntime().eventBus;
|
|
10
|
-
var lankaEventBus = Object.freeze({
|
|
11
|
-
enableLogs: () => {
|
|
12
|
-
bus().enableLogs();
|
|
13
|
-
},
|
|
14
|
-
disableLogs: () => {
|
|
15
|
-
bus().disableLogs();
|
|
16
|
-
},
|
|
17
|
-
registerEvent: (eventType, metadata) => {
|
|
18
|
-
bus().registerEvent(eventType, metadata);
|
|
19
|
-
},
|
|
20
|
-
getRegisteredEvents: () => bus().getRegisteredEvents(),
|
|
21
|
-
getEventInfo: (eventType) => bus().getEventInfo(eventType),
|
|
22
|
-
getSubscriptions: (eventType) => bus().getSubscriptions(eventType),
|
|
23
|
-
subscribe: (eventType, callback, options) => bus().subscribe(eventType, callback, options),
|
|
24
|
-
unsubscribe: (eventType, callback) => {
|
|
25
|
-
bus().unsubscribe(eventType, callback);
|
|
26
|
-
},
|
|
27
|
-
dispatch: (eventType, data, usedBy) => {
|
|
28
|
-
bus().dispatch(eventType, data, usedBy);
|
|
29
|
-
},
|
|
30
|
-
addMiddleware: (middleware) => {
|
|
31
|
-
bus().addMiddleware(middleware);
|
|
32
|
-
},
|
|
33
|
-
removeMiddleware: (middleware) => {
|
|
34
|
-
bus().removeMiddleware(middleware);
|
|
35
|
-
},
|
|
36
|
-
addObserver: (observer) => {
|
|
37
|
-
bus().addObserver(observer);
|
|
38
|
-
},
|
|
39
|
-
removeObserver: (observer) => {
|
|
40
|
-
bus().removeObserver(observer);
|
|
41
|
-
},
|
|
42
|
-
getEventLogs: (eventType, limit = 100) => bus().getEventLogs(eventType, limit),
|
|
43
|
-
clearEvent: (eventType) => {
|
|
44
|
-
bus().clearEvent(eventType);
|
|
45
|
-
},
|
|
46
|
-
clearAllEvents: () => {
|
|
47
|
-
bus().clearAllEvents();
|
|
48
|
-
},
|
|
49
|
-
reset: () => {
|
|
50
|
-
bus().reset();
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// src/scenario/_registries/lanka-scenario-vm-registry/LankaScenarioVMRegistry.ts
|
|
55
|
-
var LankaScenarioVMRegistry = class {
|
|
56
|
-
registeredViewModels = /* @__PURE__ */ new Set();
|
|
57
|
-
/**
|
|
58
|
-
* Public: the registry belongs to a framework instance rather than to the
|
|
59
|
-
* module.
|
|
60
|
-
*/
|
|
61
|
-
constructor() {
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* The active instance's registry, for callers that cannot hold one — the
|
|
65
|
-
* static `LankaScenarioBootstrap`. Instance holders read `lanka.viewModels`.
|
|
66
|
-
*/
|
|
67
|
-
static getInstance() {
|
|
68
|
-
return requireActiveRuntime().viewModels;
|
|
69
|
-
}
|
|
70
|
-
/** Whether this ViewModel is already registered. */
|
|
71
|
-
isRegistered(viewModel) {
|
|
72
|
-
return this.registeredViewModels.has(viewModel);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Registers a ViewModel.
|
|
76
|
-
*
|
|
77
|
-
* @returns `false` when it was already registered
|
|
78
|
-
*/
|
|
79
|
-
register(viewModel) {
|
|
80
|
-
if (this.registeredViewModels.has(viewModel)) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
this.registeredViewModels.add(viewModel);
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
/** Removes a ViewModel from the registry. */
|
|
87
|
-
unregister(viewModel) {
|
|
88
|
-
this.registeredViewModels.delete(viewModel);
|
|
89
|
-
}
|
|
90
|
-
/** Every registered ViewModel. */
|
|
91
|
-
getAllViewModels() {
|
|
92
|
-
return Array.from(this.registeredViewModels);
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Clears every registered ViewModel. Required by tests.
|
|
96
|
-
*/
|
|
97
|
-
clear() {
|
|
98
|
-
this.registeredViewModels.clear();
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Unsubscribes every registered ViewModel from its scenarios and clears the
|
|
102
|
-
* registry.
|
|
103
|
-
*
|
|
104
|
-
* Without it tests are not isolated: a subscription leaks from test to test.
|
|
105
|
-
*/
|
|
106
|
-
resetAll() {
|
|
107
|
-
this.registeredViewModels.forEach((vm) => {
|
|
108
|
-
try {
|
|
109
|
-
vm.resetScenario();
|
|
110
|
-
} catch {
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
this.clear();
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
// src/scenario/_registries/lanka-scenarios-registry/LankaScenariosRegistry.ts
|
|
118
|
-
var release = (scenario) => {
|
|
119
|
-
if (!scenario.cleanup) return;
|
|
120
|
-
try {
|
|
121
|
-
scenario.cleanup();
|
|
122
|
-
} catch (error) {
|
|
123
|
-
lankaLogger.printScenarioLog(`Error cleaning up scenario "${scenario.name}":`, error);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
var LankaScenariosRegistry = class {
|
|
127
|
-
registeredScenarios = /* @__PURE__ */ new Map();
|
|
128
|
-
scenarioMetadata = /* @__PURE__ */ new Map();
|
|
129
|
-
/**
|
|
130
|
-
* Public: the registry belongs to a framework instance rather than to the
|
|
131
|
-
* module.
|
|
132
|
-
*/
|
|
133
|
-
constructor() {
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* The active instance's registry, for callers that cannot hold one:
|
|
137
|
-
* `ALankaScenario` (a base class the consumer extends) and the static
|
|
138
|
-
* `LankaScenarioBootstrap`. Instance holders read `lanka.scenarios`.
|
|
139
|
-
*/
|
|
140
|
-
static getInstance() {
|
|
141
|
-
return requireActiveRuntime().scenarios;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Registers a scenario by hand.
|
|
145
|
-
*
|
|
146
|
-
* @param scenario What to register
|
|
147
|
-
* @returns `false` when it was already registered
|
|
148
|
-
*/
|
|
149
|
-
register(scenario) {
|
|
150
|
-
if (this.registeredScenarios.has(scenario.name)) {
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
this.registeredScenarios.set(scenario.name, scenario);
|
|
154
|
-
this.scenarioMetadata.set(scenario.name, {
|
|
155
|
-
scenario,
|
|
156
|
-
name: scenario.name,
|
|
157
|
-
eventType: scenario.eventType,
|
|
158
|
-
dataTypeName: scenario.dataTypeName,
|
|
159
|
-
isRegistered: true
|
|
160
|
-
});
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Removes a scenario, calling its `cleanup` if it declared one.
|
|
165
|
-
*
|
|
166
|
-
* @param scenarioName Name of the scenario to unregister
|
|
167
|
-
* @returns true if unregistered successfully, false if not found
|
|
168
|
-
*/
|
|
169
|
-
unregister(scenarioName) {
|
|
170
|
-
const scenario = this.registeredScenarios.get(scenarioName);
|
|
171
|
-
if (!scenario) {
|
|
172
|
-
return false;
|
|
173
|
-
}
|
|
174
|
-
const metadata = this.scenarioMetadata.get(scenarioName);
|
|
175
|
-
if (metadata) {
|
|
176
|
-
metadata.isRegistered = false;
|
|
177
|
-
}
|
|
178
|
-
this.registeredScenarios.delete(scenarioName);
|
|
179
|
-
release(scenario);
|
|
180
|
-
return true;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Get metadata for a specific scenario
|
|
184
|
-
* @param scenarioName Name of the scenario
|
|
185
|
-
* @returns Scenario metadata or undefined if not found
|
|
186
|
-
*/
|
|
187
|
-
getMetadata(scenarioName) {
|
|
188
|
-
return this.scenarioMetadata.get(scenarioName);
|
|
189
|
-
}
|
|
190
|
-
/** Every registered scenario. */
|
|
191
|
-
getAllScenarios() {
|
|
192
|
-
return Array.from(this.registeredScenarios.values());
|
|
193
|
-
}
|
|
194
|
-
/** Metadata of every scenario. */
|
|
195
|
-
getAllMetadata() {
|
|
196
|
-
return Array.from(this.scenarioMetadata.values());
|
|
197
|
-
}
|
|
198
|
-
/** Whether a scenario with this name is registered. */
|
|
199
|
-
isRegistered(scenarioName) {
|
|
200
|
-
return this.registeredScenarios.has(scenarioName);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Collects every scenario that registered itself at construction.
|
|
204
|
-
*/
|
|
205
|
-
collectAutoRegisteredScenarios() {
|
|
206
|
-
const autoRegistered = ALankaScenario.getAutoRegisteredScenarios();
|
|
207
|
-
autoRegistered.forEach((scenario) => {
|
|
208
|
-
if (!this.registeredScenarios.has(scenario.name)) {
|
|
209
|
-
this.register(scenario);
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* A scenario by name.
|
|
215
|
-
*
|
|
216
|
-
* @returns `undefined` when there is none
|
|
217
|
-
*/
|
|
218
|
-
getScenarioByName(scenarioName) {
|
|
219
|
-
return this.registeredScenarios.get(scenarioName);
|
|
220
|
-
}
|
|
221
|
-
/** Every registered ViewModel. */
|
|
222
|
-
getAllViewModels() {
|
|
223
|
-
return LankaScenarioVMRegistry.getInstance().getAllViewModels();
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Removes every scenario, calling each one's `cleanup`.
|
|
227
|
-
*
|
|
228
|
-
* What `dispose()` and the between-tests reset go through: `initialize` ran
|
|
229
|
-
* for every scenario at bootstrap, and this is the one moment its mirror
|
|
230
|
-
* image can run for all of them.
|
|
231
|
-
*/
|
|
232
|
-
clear() {
|
|
233
|
-
const scenarios = [...this.registeredScenarios.values()];
|
|
234
|
-
this.registeredScenarios.clear();
|
|
235
|
-
this.scenarioMetadata.clear();
|
|
236
|
-
for (const scenario of scenarios) release(scenario);
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
// src/scenario/_abstractions/lanka-scenario/ALankaScenario.ts
|
|
241
|
-
var ALankaScenario = class _ALankaScenario {
|
|
242
|
-
/** A subclass sets this to opt out of self-registration. */
|
|
243
|
-
static skipAutoRegistration;
|
|
244
|
-
/**
|
|
245
|
-
* The self-registration pool.
|
|
246
|
-
*
|
|
247
|
-
* Class-level deliberately: a registry of DEFINITIONS, not runtime state. The
|
|
248
|
-
* classes come from one barrel and both framework instances must see the same
|
|
249
|
-
* list — splitting it would be divergence, not isolation.
|
|
250
|
-
*/
|
|
251
|
-
static autoRegisteredScenarios = /* @__PURE__ */ new Set();
|
|
252
|
-
/** Registers the scenario itself unless the subclass opted out. */
|
|
253
|
-
constructor() {
|
|
254
|
-
const constructor = this.constructor;
|
|
255
|
-
if (!constructor.skipAutoRegistration) {
|
|
256
|
-
_ALankaScenario.autoRegisteredScenarios.add(this);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Every scenario that registered itself.
|
|
261
|
-
*
|
|
262
|
-
* @internal
|
|
263
|
-
*/
|
|
264
|
-
static getAutoRegisteredScenarios() {
|
|
265
|
-
return Array.from(_ALankaScenario.autoRegisteredScenarios);
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Clears the auto-registration pool. Required by tests.
|
|
269
|
-
* @internal
|
|
270
|
-
*/
|
|
271
|
-
static clearAutoRegisteredScenarios() {
|
|
272
|
-
_ALankaScenario.autoRegisteredScenarios.clear();
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Registers the scenario by hand.
|
|
276
|
-
*
|
|
277
|
-
* @returns `false` when it was already registered
|
|
278
|
-
*/
|
|
279
|
-
register() {
|
|
280
|
-
return LankaScenariosRegistry.getInstance().register(this);
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Removes the scenario from the registry.
|
|
284
|
-
*
|
|
285
|
-
* @returns `false` when it was not there
|
|
286
|
-
*/
|
|
287
|
-
unregister() {
|
|
288
|
-
return LankaScenariosRegistry.getInstance().unregister(this.name);
|
|
289
|
-
}
|
|
290
|
-
trigger(data) {
|
|
291
|
-
lankaLogger.printScenarioLog("TRIGGER Scenario", this.name, data);
|
|
292
|
-
lankaEventBus.dispatch(this.eventType, data, this.name);
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Subscribes a handler and returns an unsubscribe function.
|
|
296
|
-
*
|
|
297
|
-
* Without the return, unsubscribing is possible only by callback identity, and
|
|
298
|
-
* every ViewModel factory has to keep a map of references for it.
|
|
299
|
-
*/
|
|
300
|
-
subscribe(callback, options) {
|
|
301
|
-
lankaLogger.printScenarioLog("SUBSCRIBE Scenario", this.name, this.dataTypeName);
|
|
302
|
-
return lankaEventBus.subscribe(this.eventType, callback, {
|
|
303
|
-
...options,
|
|
304
|
-
usedBy: options?.usedBy ?? this.name
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
export {
|
|
310
|
-
lankaEventBus,
|
|
311
|
-
ALankaScenario,
|
|
312
|
-
LankaScenarioVMRegistry,
|
|
313
|
-
LankaScenariosRegistry
|
|
314
|
-
};
|
|
315
|
-
//# sourceMappingURL=chunk-O5ROO7QF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/scenario/event-bus/_facades/lanka-event-bus/lankaEventBus.ts","../src/scenario/_registries/lanka-scenario-vm-registry/LankaScenarioVMRegistry.ts","../src/scenario/_registries/lanka-scenarios-registry/LankaScenariosRegistry.ts","../src/scenario/_abstractions/lanka-scenario/ALankaScenario.ts"],"sourcesContent":["import { requireActiveRuntime } from \"../../../../_internal/active-runtime/activeRuntime\";\nimport type { ILankaEventLog } from \"../../../_interfaces/ILankaEventLog\";\nimport type { ILankaEventMetadata } from \"../../../_interfaces/ILankaEventMetadata\";\nimport type { TLankaEventBusMiddleware } from \"../../../_types/TLankaEventBusMiddleware\";\nimport type { TLankaEventBusObserver } from \"../../../_types/TLankaEventBusObserver\";\nimport type { LankaEventBusInstance } from \"../../lanka-event-bus-instance/LankaEventBusInstance\";\nimport type { TLankaReplayRequest } from \"../../lanka-event-bus-instance/LankaEventBusInstance\";\n\n/**\n * Ambient bus: the active instance's, reachable without holding it.\n *\n * Every member is one line of delegation and that is all this does. It exists\n * for callers that cannot hold an instance — a user-extended `ALankaScenario`,\n * the scenario bootstrap.\n *\n * An object rather than a class with a default instance, and the difference is\n * not cosmetic: this owns no state, so a second one would delegate to the same\n * runtime and be the same object under another name. Where an ambient DOES own\n * state — storage — the class is real and a second instance means something.\n *\n * Isolation belongs to the instance holder: `lanka.eventBus.dispatch(…)`. This\n * cannot offer it — by definition it serves the ONE active instance, so two\n * instances in one process share nothing through it.\n */\nconst bus = (): LankaEventBusInstance => requireActiveRuntime().eventBus;\n\nexport const lankaEventBus = Object.freeze({\n\tenableLogs: (): void => {\n\t\tbus().enableLogs();\n\t},\n\n\tdisableLogs: (): void => {\n\t\tbus().disableLogs();\n\t},\n\n\tregisterEvent: (eventType: string, metadata: ILankaEventMetadata): void => {\n\t\tbus().registerEvent(eventType, metadata);\n\t},\n\n\tgetRegisteredEvents: () => bus().getRegisteredEvents(),\n\n\tgetEventInfo: (eventType: string): ILankaEventMetadata | null => bus().getEventInfo(eventType),\n\n\tgetSubscriptions: (eventType: string): number => bus().getSubscriptions(eventType),\n\n\tsubscribe: <T>(\n\t\teventType: string,\n\t\tcallback: (data: T) => void,\n\t\toptions?: { priority?: number; replay?: TLankaReplayRequest; usedBy?: string },\n\t): (() => void) => bus().subscribe(eventType, callback, options),\n\n\tunsubscribe: <T>(eventType: string, callback: (data: T) => void): void => {\n\t\tbus().unsubscribe(eventType, callback);\n\t},\n\n\tdispatch: <T>(eventType: string, data?: T, usedBy?: string): void => {\n\t\tbus().dispatch(eventType, data, usedBy);\n\t},\n\n\taddMiddleware: <T>(middleware: TLankaEventBusMiddleware<T>): void => {\n\t\tbus().addMiddleware(middleware);\n\t},\n\n\tremoveMiddleware: <T>(middleware: TLankaEventBusMiddleware<T>): void => {\n\t\tbus().removeMiddleware(middleware);\n\t},\n\n\taddObserver: (observer: TLankaEventBusObserver): void => {\n\t\tbus().addObserver(observer);\n\t},\n\n\tremoveObserver: (observer: TLankaEventBusObserver): void => {\n\t\tbus().removeObserver(observer);\n\t},\n\n\tgetEventLogs: (eventType?: string, limit = 100): ILankaEventLog[] =>\n\t\tbus().getEventLogs(eventType, limit),\n\n\tclearEvent: (eventType: string): void => {\n\t\tbus().clearEvent(eventType);\n\t},\n\n\tclearAllEvents: (): void => {\n\t\tbus().clearAllEvents();\n\t},\n\n\treset: (): void => {\n\t\tbus().reset();\n\t},\n});\n","import { requireActiveRuntime } from \"../../../_internal/active-runtime/activeRuntime\";\nimport { ILankaScenarioVM } from \"../../_interfaces/ILankaScenarioVM\";\n\n/**\n * The registry of ViewModels that use scenarios.\n *\n * They arrive by themselves: the factory registers a ViewModel when it declares\n * scenario handlers.\n */\nexport class LankaScenarioVMRegistry {\n\tprivate registeredViewModels: Set<ILankaScenarioVM> = new Set();\n\n\t/**\n\t * Public: the registry belongs to a framework instance rather than to the\n\t * module.\n\t */\n\tpublic constructor() {}\n\n\t/**\n\t * The active instance's registry, for callers that cannot hold one — the\n\t * static `LankaScenarioBootstrap`. Instance holders read `lanka.viewModels`.\n\t */\n\tpublic static getInstance(): LankaScenarioVMRegistry {\n\t\treturn requireActiveRuntime().viewModels;\n\t}\n\n\t/** Whether this ViewModel is already registered. */\n\tpublic isRegistered(viewModel: ILankaScenarioVM): boolean {\n\t\treturn this.registeredViewModels.has(viewModel);\n\t}\n\n\t/**\n\t * Registers a ViewModel.\n\t *\n\t * @returns `false` when it was already registered\n\t */\n\tpublic register(viewModel: ILankaScenarioVM): boolean {\n\t\tif (this.registeredViewModels.has(viewModel)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.registeredViewModels.add(viewModel);\n\t\treturn true;\n\t}\n\n\t/** Removes a ViewModel from the registry. */\n\tpublic unregister(viewModel: ILankaScenarioVM): void {\n\t\tthis.registeredViewModels.delete(viewModel);\n\t}\n\n\t/** Every registered ViewModel. */\n\tpublic getAllViewModels(): ILankaScenarioVM[] {\n\t\treturn Array.from(this.registeredViewModels);\n\t}\n\n\t/**\n\t * Clears every registered ViewModel. Required by tests.\n\t */\n\tpublic clear(): void {\n\t\tthis.registeredViewModels.clear();\n\t}\n\n\t/**\n\t * Unsubscribes every registered ViewModel from its scenarios and clears the\n\t * registry.\n\t *\n\t * Without it tests are not isolated: a subscription leaks from test to test.\n\t */\n\tpublic resetAll(): void {\n\t\tthis.registeredViewModels.forEach((vm) => {\n\t\t\ttry {\n\t\t\t\tvm.resetScenario();\n\t\t\t} catch {\n\t\t\t\t// One failing to reset is no reason to fail the rest.\n\t\t\t}\n\t\t});\n\t\tthis.clear();\n\t}\n}\n","import { requireActiveRuntime } from \"../../../_internal/active-runtime/activeRuntime\";\nimport { ILankaScenario } from \"../../_interfaces/ILankaScenario\";\nimport { ALankaScenario } from \"../../_abstractions/lanka-scenario/ALankaScenario\";\nimport { ILankaScenarioVM } from \"../../_interfaces/ILankaScenarioVM\";\nimport { LankaScenarioVMRegistry } from \"../lanka-scenario-vm-registry/LankaScenarioVMRegistry\";\nimport { lankaLogger } from \"../../../logger/lanka-logger/LankaLogger\";\nimport type { ILankaScenarioMetadata } from \"../../_interfaces/ILankaScenarioMetadata\";\n\n/**\n * Runs a scenario's `cleanup`, if it declared one, and contains what it throws.\n *\n * `ILankaScenario` promises `cleanup` is \"called when the scenario is removed\n * from the registry\", and for a long time nothing called it: a scenario whose\n * `initialize` opened something had no way to close it, and the promise read\n * as kept. Contained, because a removal runs over MANY scenarios — on dispose,\n * on the between-tests reset — and one failing to let go is no reason to leave\n * the rest registered.\n */\nconst release = (scenario: ILankaScenario<unknown>): void => {\n\tif (!scenario.cleanup) return;\n\ttry {\n\t\tscenario.cleanup();\n\t} catch (error) {\n\t\tlankaLogger.printScenarioLog(`Error cleaning up scenario \"${scenario.name}\":`, error);\n\t}\n};\n\n/**\n * The scenario registry: both those that registered themselves and those\n * registered by hand.\n *\n * `ALankaScenario` subclasses arrive here automatically unless they opted out.\n */\nexport class LankaScenariosRegistry {\n\tprivate registeredScenarios: Map<string, ILankaScenario<unknown>> = new Map();\n\tprivate scenarioMetadata: Map<string, ILankaScenarioMetadata> = new Map();\n\n\t/**\n\t * Public: the registry belongs to a framework instance rather than to the\n\t * module.\n\t */\n\tpublic constructor() {}\n\n\t/**\n\t * The active instance's registry, for callers that cannot hold one:\n\t * `ALankaScenario` (a base class the consumer extends) and the static\n\t * `LankaScenarioBootstrap`. Instance holders read `lanka.scenarios`.\n\t */\n\tpublic static getInstance(): LankaScenariosRegistry {\n\t\treturn requireActiveRuntime().scenarios;\n\t}\n\n\t/**\n\t * Registers a scenario by hand.\n\t *\n\t * @param scenario What to register\n\t * @returns `false` when it was already registered\n\t */\n\tpublic register(scenario: ILankaScenario<unknown>): boolean {\n\t\tif (this.registeredScenarios.has(scenario.name)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.registeredScenarios.set(scenario.name, scenario);\n\t\tthis.scenarioMetadata.set(scenario.name, {\n\t\t\tscenario,\n\t\t\tname: scenario.name,\n\t\t\teventType: scenario.eventType,\n\t\t\tdataTypeName: scenario.dataTypeName,\n\t\t\tisRegistered: true,\n\t\t});\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Removes a scenario, calling its `cleanup` if it declared one.\n\t *\n\t * @param scenarioName Name of the scenario to unregister\n\t * @returns true if unregistered successfully, false if not found\n\t */\n\tpublic unregister(scenarioName: string): boolean {\n\t\tconst scenario = this.registeredScenarios.get(scenarioName);\n\t\tif (!scenario) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst metadata = this.scenarioMetadata.get(scenarioName);\n\t\tif (metadata) {\n\t\t\tmetadata.isRegistered = false;\n\t\t}\n\n\t\tthis.registeredScenarios.delete(scenarioName);\n\t\trelease(scenario);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get metadata for a specific scenario\n\t * @param scenarioName Name of the scenario\n\t * @returns Scenario metadata or undefined if not found\n\t */\n\tpublic getMetadata(scenarioName: string): ILankaScenarioMetadata | undefined {\n\t\treturn this.scenarioMetadata.get(scenarioName);\n\t}\n\n\t/** Every registered scenario. */\n\tpublic getAllScenarios(): ILankaScenario<unknown>[] {\n\t\treturn Array.from(this.registeredScenarios.values());\n\t}\n\n\t/** Metadata of every scenario. */\n\tpublic getAllMetadata(): ILankaScenarioMetadata[] {\n\t\treturn Array.from(this.scenarioMetadata.values());\n\t}\n\n\t/** Whether a scenario with this name is registered. */\n\tpublic isRegistered(scenarioName: string): boolean {\n\t\treturn this.registeredScenarios.has(scenarioName);\n\t}\n\n\t/**\n\t * Collects every scenario that registered itself at construction.\n\t */\n\tpublic collectAutoRegisteredScenarios(): void {\n\t\t// Take those that registered themselves at construction.\n\t\tconst autoRegistered = ALankaScenario.getAutoRegisteredScenarios();\n\t\tautoRegistered.forEach((scenario) => {\n\t\t\tif (!this.registeredScenarios.has(scenario.name)) {\n\t\t\t\tthis.register(scenario);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * A scenario by name.\n\t *\n\t * @returns `undefined` when there is none\n\t */\n\tpublic getScenarioByName(scenarioName: string): ILankaScenario<unknown> | undefined {\n\t\treturn this.registeredScenarios.get(scenarioName);\n\t}\n\n\t/** Every registered ViewModel. */\n\tpublic getAllViewModels(): ILankaScenarioVM[] {\n\t\treturn LankaScenarioVMRegistry.getInstance().getAllViewModels();\n\t}\n\n\t/**\n\t * Removes every scenario, calling each one's `cleanup`.\n\t *\n\t * What `dispose()` and the between-tests reset go through: `initialize` ran\n\t * for every scenario at bootstrap, and this is the one moment its mirror\n\t * image can run for all of them.\n\t */\n\tpublic clear(): void {\n\t\tconst scenarios = [...this.registeredScenarios.values()];\n\t\tthis.registeredScenarios.clear();\n\t\tthis.scenarioMetadata.clear();\n\t\tfor (const scenario of scenarios) release(scenario);\n\t}\n}\n","import type { TLankaReplayRequest } from \"../../event-bus/lanka-event-bus-instance/LankaEventBusInstance\";\nimport { ILankaScenario } from \"../../_interfaces/ILankaScenario\";\nimport { LankaScenariosRegistry } from \"../../_registries/lanka-scenarios-registry/LankaScenariosRegistry\";\nimport { lankaLogger } from \"../../../logger/lanka-logger/LankaLogger\";\nimport { lankaEventBus } from \"../../event-bus/_facades/lanka-event-bus/lankaEventBus\";\n\n/**\n * The base of a scenario — a named unit of coordination over the event bus.\n *\n * A subclass declares `name`, `eventType` and `dataTypeName`, calls `trigger()`\n * when the event happens, and ViewModels subscribe to it and unsubscribe.\n *\n * Scenarios register THEMSELVES unless the subclass sets the static\n * `skipAutoRegistration`.\n *\n * ```ts\n * export class SessionUpdated extends ALankaScenario<TSession> {\n * readonly name = \"SessionUpdated\";\n * readonly eventType = \"session.updated\";\n * readonly dataTypeName = \"TSession\";\n * }\n * ```\n */\nexport abstract class ALankaScenario<TData = void> implements ILankaScenario<TData> {\n\tabstract readonly name: string;\n\tabstract readonly eventType: string;\n\tabstract readonly dataTypeName: string;\n\n\t/** A subclass sets this to opt out of self-registration. */\n\tstatic skipAutoRegistration?: boolean;\n\n\t/**\n\t * The self-registration pool.\n\t *\n\t * Class-level deliberately: a registry of DEFINITIONS, not runtime state. The\n\t * classes come from one barrel and both framework instances must see the same\n\t * list — splitting it would be divergence, not isolation.\n\t */\n\tprivate static autoRegisteredScenarios: Set<ALankaScenario<unknown>> = new Set();\n\n\t/** Registers the scenario itself unless the subclass opted out. */\n\tconstructor() {\n\t\t// The constructor comes from the actual class, that is the subclass.\n\t\tconst constructor = this.constructor as typeof ALankaScenario;\n\n\t\t// Register unless opted out.\n\t\tif (!constructor.skipAutoRegistration) {\n\t\t\tALankaScenario.autoRegisteredScenarios.add(this);\n\t\t}\n\t}\n\n\t/**\n\t * Every scenario that registered itself.\n\t *\n\t * @internal\n\t */\n\tpublic static getAutoRegisteredScenarios(): ALankaScenario<unknown>[] {\n\t\treturn Array.from(ALankaScenario.autoRegisteredScenarios);\n\t}\n\n\t/**\n\t * Clears the auto-registration pool. Required by tests.\n\t * @internal\n\t */\n\tpublic static clearAutoRegisteredScenarios(): void {\n\t\tALankaScenario.autoRegisteredScenarios.clear();\n\t}\n\n\t/**\n\t * Registers the scenario by hand.\n\t *\n\t * @returns `false` when it was already registered\n\t */\n\tpublic register(): boolean {\n\t\treturn LankaScenariosRegistry.getInstance().register(this);\n\t}\n\n\t/**\n\t * Removes the scenario from the registry.\n\t *\n\t * @returns `false` when it was not there\n\t */\n\tpublic unregister(): boolean {\n\t\treturn LankaScenariosRegistry.getInstance().unregister(this.name);\n\t}\n\n\ttrigger(data?: TData): void {\n\t\tlankaLogger.printScenarioLog(\"TRIGGER Scenario\", this.name, data);\n\t\tlankaEventBus.dispatch(this.eventType, data, this.name);\n\t}\n\n\t/**\n\t * Subscribes a handler and returns an unsubscribe function.\n\t *\n\t * Without the return, unsubscribing is possible only by callback identity, and\n\t * every ViewModel factory has to keep a map of references for it.\n\t */\n\tsubscribe(\n\t\tcallback: (data?: TData) => void,\n\t\toptions?: {\n\t\t\tpriority?: number;\n\t\t\treplay?: TLankaReplayRequest;\n\t\t\tusedBy?: string;\n\t\t},\n\t): () => void {\n\t\tlankaLogger.printScenarioLog(\"SUBSCRIBE Scenario\", this.name, this.dataTypeName);\n\t\treturn lankaEventBus.subscribe(this.eventType, callback, {\n\t\t\t...options,\n\t\t\tusedBy: options?.usedBy ?? this.name,\n\t\t});\n\t}\n}\n"],"mappings":"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","names":[]}
|