lanka 1.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/LICENSE +21 -0
- package/README.md +242 -0
- package/dist/ALankaGateway-ExlRGT3D.d.ts +122 -0
- package/dist/ALankaSharedStore-B7uepuuk.d.ts +29 -0
- package/dist/ILankaApiError-zI_2bNs0.d.ts +16 -0
- package/dist/ILankaRuntimeConfig-Vl436GWK.d.ts +62 -0
- package/dist/ILankaScenarioMetadata-Bu-yggTZ.d.ts +14 -0
- package/dist/ILankaScenarioVM-DuCyPoyT.d.ts +260 -0
- package/dist/LankaError-B1HtuIkw.d.ts +86 -0
- package/dist/LankaScenarioLocator-BGQHwf3n.d.ts +144 -0
- package/dist/LankaSharedStoreLocator-MvCpav5F.d.ts +126 -0
- package/dist/TLankaErrorHandler-Yfqtdh1M.d.ts +3 -0
- package/dist/_extend/index.d.ts +34 -0
- package/dist/_extend/index.js +36 -0
- package/dist/_extend/index.js.map +1 -0
- package/dist/_internal/index.d.ts +43 -0
- package/dist/_internal/index.js +34 -0
- package/dist/_internal/index.js.map +1 -0
- package/dist/activeRuntime-FcsSJvUg.d.ts +84 -0
- package/dist/bootstrap/index.d.ts +242 -0
- package/dist/bootstrap/index.js +22 -0
- package/dist/bootstrap/index.js.map +1 -0
- package/dist/chunk-73IVH3C6.js +52 -0
- package/dist/chunk-73IVH3C6.js.map +1 -0
- package/dist/chunk-BGVDPDX4.js +29 -0
- package/dist/chunk-BGVDPDX4.js.map +1 -0
- package/dist/chunk-C2HP7CRD.js +224 -0
- package/dist/chunk-C2HP7CRD.js.map +1 -0
- package/dist/chunk-D27MREPB.js +13 -0
- package/dist/chunk-D27MREPB.js.map +1 -0
- package/dist/chunk-DTO27QFR.js +59 -0
- package/dist/chunk-DTO27QFR.js.map +1 -0
- package/dist/chunk-EWVDJYCC.js +296 -0
- package/dist/chunk-EWVDJYCC.js.map +1 -0
- package/dist/chunk-FIR4XTBL.js +136 -0
- package/dist/chunk-FIR4XTBL.js.map +1 -0
- package/dist/chunk-ILQNYQY5.js +200 -0
- package/dist/chunk-ILQNYQY5.js.map +1 -0
- package/dist/chunk-J5LA3Q6D.js +14 -0
- package/dist/chunk-J5LA3Q6D.js.map +1 -0
- package/dist/chunk-MDZ42XRH.js +10 -0
- package/dist/chunk-MDZ42XRH.js.map +1 -0
- package/dist/chunk-Q3SOVBIJ.js +176 -0
- package/dist/chunk-Q3SOVBIJ.js.map +1 -0
- package/dist/chunk-Q7QESSYF.js +49 -0
- package/dist/chunk-Q7QESSYF.js.map +1 -0
- package/dist/chunk-RKYKK6MN.js +19 -0
- package/dist/chunk-RKYKK6MN.js.map +1 -0
- package/dist/chunk-RYFZCAQ3.js +637 -0
- package/dist/chunk-RYFZCAQ3.js.map +1 -0
- package/dist/chunk-UJEC7H6K.js +39 -0
- package/dist/chunk-UJEC7H6K.js.map +1 -0
- package/dist/chunk-XESL274R.js +23 -0
- package/dist/chunk-XESL274R.js.map +1 -0
- package/dist/chunk-YR4MZXMU.js +13 -0
- package/dist/chunk-YR4MZXMU.js.map +1 -0
- package/dist/config/index.d.ts +63 -0
- package/dist/config/index.js +16 -0
- package/dist/config/index.js.map +1 -0
- package/dist/createLankaScope-Bc_vChRs.d.ts +30 -0
- package/dist/errors/index.d.ts +37 -0
- package/dist/errors/index.js +16 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/gateway/index.d.ts +258 -0
- package/dist/gateway/index.js +438 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/lankaHttpInFlight-Bk1eIuSx.d.ts +43 -0
- package/dist/lankaRequestMiddleware-DAC5kCb7.d.ts +62 -0
- package/dist/lankaStandardValidator-CL-r-zEV.d.ts +34 -0
- package/dist/locator/index.d.ts +282 -0
- package/dist/locator/index.js +67 -0
- package/dist/locator/index.js.map +1 -0
- package/dist/logger/index.d.ts +146 -0
- package/dist/logger/index.js +11 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/mock/index.d.ts +16 -0
- package/dist/mock/index.js +58 -0
- package/dist/mock/index.js.map +1 -0
- package/dist/role/index.d.ts +48 -0
- package/dist/role/index.js +7 -0
- package/dist/role/index.js.map +1 -0
- package/dist/scenario/index.d.ts +204 -0
- package/dist/scenario/index.js +28 -0
- package/dist/scenario/index.js.map +1 -0
- package/dist/validation/index.d.ts +18 -0
- package/dist/validation/index.js +53 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/viewmodel/index.d.ts +478 -0
- package/dist/viewmodel/index.js +701 -0
- package/dist/viewmodel/index.js.map +1 -0
- package/package.json +99 -0
- package/skills/lanka-core/SKILL.md +241 -0
- package/skills/lanka-core/reference.md +1090 -0
- package/skills/lanka-packages/SKILL.md +70 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata describing an event type.
|
|
3
|
+
*/
|
|
4
|
+
interface ILankaEventMetadata {
|
|
5
|
+
/** Expected data type name (informational only). */
|
|
6
|
+
dataType?: string;
|
|
7
|
+
/** Human-readable description of the event. */
|
|
8
|
+
description?: string;
|
|
9
|
+
/** List of modules/components using this event. */
|
|
10
|
+
usedBy?: string[];
|
|
11
|
+
/** Optional validation schema for event data. */
|
|
12
|
+
schema?: (data: unknown) => boolean;
|
|
13
|
+
/** Default subscription priority (higher = earlier execution). */
|
|
14
|
+
priority?: number;
|
|
15
|
+
/** Maximum number of logs to keep for this event. */
|
|
16
|
+
maxLogs?: number;
|
|
17
|
+
/**
|
|
18
|
+
* How many recent values are kept for late subscribers.
|
|
19
|
+
*
|
|
20
|
+
* Declared on the EVENT, not merely requested by a subscriber: an event may
|
|
21
|
+
* fire before anyone subscribes, and only the event's own declaration can
|
|
22
|
+
* have caused the value to be retained by then.
|
|
23
|
+
*
|
|
24
|
+
* Default is to keep nothing — a buffer that is on by default retains
|
|
25
|
+
* payloads no one asked for.
|
|
26
|
+
*/
|
|
27
|
+
replay?: boolean | "last" | number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Represents a single log entry for a dispatched event.
|
|
32
|
+
*/
|
|
33
|
+
interface ILankaEventLog {
|
|
34
|
+
/** The event type name. */
|
|
35
|
+
eventType: string;
|
|
36
|
+
/** ISO timestamp of when the event was dispatched. */
|
|
37
|
+
timestamp: string;
|
|
38
|
+
/** The payload data of the event. */
|
|
39
|
+
data: unknown;
|
|
40
|
+
/** Optional captured stack trace (if enabled). */
|
|
41
|
+
stackTrace?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Why a middleware stopped delivery.
|
|
44
|
+
*
|
|
45
|
+
* Present only on stopped events; it exists so that a stop is never silent.
|
|
46
|
+
*/
|
|
47
|
+
stoppedBy?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A middleware's decision about an event.
|
|
52
|
+
*
|
|
53
|
+
* `"pass"` lets it through. `{ stop }` halts it, naming the reason.
|
|
54
|
+
*/
|
|
55
|
+
type TLankaEventBusDecision = "pass" | {
|
|
56
|
+
stop: string;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* A bus event interceptor.
|
|
60
|
+
*
|
|
61
|
+
* ## Why the decision is RETURNED rather than expressed by calling `next()`
|
|
62
|
+
*
|
|
63
|
+
* A `(eventType, data, next) => void` shape rests on a convention: call `next`
|
|
64
|
+
* and the event continues, do not and it stops. The second happens SILENTLY — no
|
|
65
|
+
* subscriber runs and nothing is logged or counted, so a mechanism that exists
|
|
66
|
+
* for observability becomes its own blind spot.
|
|
67
|
+
*
|
|
68
|
+
* A returned decision cannot be forgotten: the type demands it, and a stop
|
|
69
|
+
* carries a reason into the bus log.
|
|
70
|
+
*
|
|
71
|
+
* ## How this differs from REQUEST middleware
|
|
72
|
+
*
|
|
73
|
+
* There the `(ctx, next) => …` shape stays, and not by oversight: request
|
|
74
|
+
* middleware must be able to RETRY, which can only be expressed by calling
|
|
75
|
+
* `next` twice. And not calling it there means returning a value instead of a
|
|
76
|
+
* request, which the caller sees. Here, not calling it meant the event vanished.
|
|
77
|
+
*/
|
|
78
|
+
type TLankaEventBusMiddleware<T> = (eventType: string, data: T) => TLankaEventBusDecision;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* How many recent values to replay to a new subscriber.
|
|
82
|
+
*
|
|
83
|
+
* `true` is kept and means "the last one".
|
|
84
|
+
*/
|
|
85
|
+
type TLankaReplayRequest = boolean | "last" | number;
|
|
86
|
+
declare class LankaEventBusInstance {
|
|
87
|
+
/** Event registry and per-event state — private to each instance. */
|
|
88
|
+
private registry;
|
|
89
|
+
/** Middleware registered on this instance. */
|
|
90
|
+
private middlewares;
|
|
91
|
+
/** Default maximum number of logs kept per event type. */
|
|
92
|
+
private defaultMaxLogs;
|
|
93
|
+
/** Internal timers for replay batching (avoid multiple replays in the same tick). */
|
|
94
|
+
private pendingReplayTimers;
|
|
95
|
+
/** Whether event logging is enabled. */
|
|
96
|
+
private isEnableLogs;
|
|
97
|
+
/** Configures the bus, e.g. logging. Called once at application start. */
|
|
98
|
+
enableLogs(): void;
|
|
99
|
+
disableLogs(): void;
|
|
100
|
+
/**
|
|
101
|
+
* Ensures the event is registered, registering it if not.
|
|
102
|
+
*
|
|
103
|
+
* @param eventType Event type
|
|
104
|
+
* @param usedBy Who uses it — for the inspector and for finding an owner
|
|
105
|
+
*/
|
|
106
|
+
private ensureEvent;
|
|
107
|
+
/**
|
|
108
|
+
* Declares an event explicitly, together with its metadata.
|
|
109
|
+
*
|
|
110
|
+
* @param eventType Event type
|
|
111
|
+
* @param metadata What is known about the event and what it is allowed
|
|
112
|
+
*/
|
|
113
|
+
registerEvent(eventType: string, metadata: ILankaEventMetadata): void;
|
|
114
|
+
/** Every registered event with its metadata. */
|
|
115
|
+
getRegisteredEvents(): {
|
|
116
|
+
eventType: string;
|
|
117
|
+
metadata: ILankaEventMetadata;
|
|
118
|
+
}[];
|
|
119
|
+
/** Metadata of one event type. */
|
|
120
|
+
getEventInfo(eventType: string): ILankaEventMetadata | null;
|
|
121
|
+
/** How many live subscriptions this event has. */
|
|
122
|
+
/**
|
|
123
|
+
* How many values sit in the event's buffer.
|
|
124
|
+
*
|
|
125
|
+
* Exists for the test: "the buffer stays empty until someone asks for replay"
|
|
126
|
+
* is a claim about MEMORY, and nothing but asking can check it.
|
|
127
|
+
*/
|
|
128
|
+
getBufferedCount(eventType: string): number;
|
|
129
|
+
getSubscriptions(eventType: string): number;
|
|
130
|
+
/**
|
|
131
|
+
* Subscribes a handler to an event type.
|
|
132
|
+
*
|
|
133
|
+
* @param eventType Event type
|
|
134
|
+
* @param callback What to run on dispatch
|
|
135
|
+
* @param options Subscription options:
|
|
136
|
+
* - `priority` — execution order, higher runs earlier;
|
|
137
|
+
* - `replay` — receive what was dispatched before subscribing;
|
|
138
|
+
* - `usedBy` — who subscribed, for the inspector.
|
|
139
|
+
*/
|
|
140
|
+
subscribe<T>(eventType: string, callback: (data: T) => void, options?: {
|
|
141
|
+
priority?: number;
|
|
142
|
+
replay?: TLankaReplayRequest;
|
|
143
|
+
usedBy?: string;
|
|
144
|
+
}): () => void;
|
|
145
|
+
/**
|
|
146
|
+
* Removes a handler from an event type.
|
|
147
|
+
*
|
|
148
|
+
* @param eventType Event type
|
|
149
|
+
* @param callback A previously subscribed handler
|
|
150
|
+
*/
|
|
151
|
+
unsubscribe<T>(eventType: string, callback: (data: T) => void): void;
|
|
152
|
+
/**
|
|
153
|
+
* Dispatches an event: the middleware chain first, then subscribers.
|
|
154
|
+
*
|
|
155
|
+
* @param eventType Event type
|
|
156
|
+
* @param data Payload
|
|
157
|
+
* @param usedBy Who dispatched — recorded in the metadata
|
|
158
|
+
*/
|
|
159
|
+
dispatch<T>(eventType: string, data?: T, usedBy?: string): void;
|
|
160
|
+
/** Adds middleware to the shared chain. */
|
|
161
|
+
addMiddleware<T>(mw: TLankaEventBusMiddleware<T>): void;
|
|
162
|
+
/** Removes previously added middleware. */
|
|
163
|
+
removeMiddleware<T>(mw: TLankaEventBusMiddleware<T>): void;
|
|
164
|
+
/**
|
|
165
|
+
* Log of dispatched events.
|
|
166
|
+
*
|
|
167
|
+
* @param eventType Limit to one type
|
|
168
|
+
* @param limit How many recent records to return
|
|
169
|
+
*/
|
|
170
|
+
getEventLogs(eventType?: string, limit?: number): ILankaEventLog[];
|
|
171
|
+
/** Removes an event together with its subscriptions, log and buffer. */
|
|
172
|
+
clearEvent(eventType: string): void;
|
|
173
|
+
/** Removes every event and any scheduled replays. */
|
|
174
|
+
clearAllEvents(): void;
|
|
175
|
+
/** Full bus reset: events and middleware. */
|
|
176
|
+
reset(): void;
|
|
177
|
+
/**
|
|
178
|
+
* Marks the last log record with the reason it was stopped.
|
|
179
|
+
*
|
|
180
|
+
* Writes where `logEvent` just put the event: a stop is not a separate
|
|
181
|
+
* occurrence but this one's outcome.
|
|
182
|
+
*/
|
|
183
|
+
private markStopped;
|
|
184
|
+
/** Add an event log entry for debugging/auditing. */
|
|
185
|
+
private logEvent;
|
|
186
|
+
/**
|
|
187
|
+
* Schedules replay for late subscribers that asked for it.
|
|
188
|
+
*
|
|
189
|
+
* Replays are batched into one tick: otherwise ten subscriptions to one event
|
|
190
|
+
* would make ten separate passes over the same buffer.
|
|
191
|
+
*/
|
|
192
|
+
private scheduleBatchedReplay;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* A scenario: a named unit of coordination over the event bus.
|
|
197
|
+
*
|
|
198
|
+
* This is how ViewModels talk to each other without knowing about each other.
|
|
199
|
+
*
|
|
200
|
+
* @template TData The data that travels with the event
|
|
201
|
+
*/
|
|
202
|
+
interface ILankaScenario<TData = void> {
|
|
203
|
+
/** The scenario's name, and the key it is found by. */
|
|
204
|
+
readonly name: string;
|
|
205
|
+
/** The event type on the bus. */
|
|
206
|
+
readonly eventType: string;
|
|
207
|
+
/** The event data's type name — for the bus metadata. */
|
|
208
|
+
readonly dataTypeName: string;
|
|
209
|
+
/**
|
|
210
|
+
* Announces that the scenario happened.
|
|
211
|
+
*
|
|
212
|
+
* @param data What travels with the event
|
|
213
|
+
*/
|
|
214
|
+
trigger(data?: TData): void;
|
|
215
|
+
/**
|
|
216
|
+
* Subscribes a handler and returns an unsubscribe function.
|
|
217
|
+
*
|
|
218
|
+
* The return is the only way to remove EXACTLY this subscription: by callback,
|
|
219
|
+
* two subscriptions of one function are indistinguishable.
|
|
220
|
+
*/
|
|
221
|
+
subscribe(callback: (data?: TData) => void, options?: {
|
|
222
|
+
priority?: number;
|
|
223
|
+
replay?: TLankaReplayRequest;
|
|
224
|
+
usedBy?: string;
|
|
225
|
+
}): () => void;
|
|
226
|
+
/** Called when the scenario is registered, if declared. */
|
|
227
|
+
initialize?(): void;
|
|
228
|
+
/** Called when the scenario is removed from the registry, if declared. */
|
|
229
|
+
cleanup?(): void;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* A ViewModel that participates in scenarios.
|
|
234
|
+
*
|
|
235
|
+
* Not every ViewModel does: one with no `scenarioHandlers` never subscribes to
|
|
236
|
+
* anything and is never registered. This is the pair of methods
|
|
237
|
+
* `LankaScenarioBootstrap` calls on those that do, which is why the name says
|
|
238
|
+
* scenario rather than ViewModel.
|
|
239
|
+
*
|
|
240
|
+
* Both are idempotent by contract: bootstrap may run after a ViewModel has
|
|
241
|
+
* already initialised itself, and a reset may arrive for one that never did.
|
|
242
|
+
*/
|
|
243
|
+
interface ILankaScenarioVM {
|
|
244
|
+
/**
|
|
245
|
+
* Subscribes this ViewModel's scenario handlers.
|
|
246
|
+
*
|
|
247
|
+
* Called once the scenario registry is populated — a ViewModel declared at
|
|
248
|
+
* module level exists before any scenario does.
|
|
249
|
+
*/
|
|
250
|
+
initializeScenario(): void;
|
|
251
|
+
/**
|
|
252
|
+
* Releases every subscription, leaving the ViewModel ready to initialise again.
|
|
253
|
+
*
|
|
254
|
+
* Called when the framework instance is disposed, and by `resetLanka()`
|
|
255
|
+
* between tests.
|
|
256
|
+
*/
|
|
257
|
+
resetScenario(): void;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { type ILankaScenarioVM as I, LankaEventBusInstance as L, type TLankaReplayRequest as T, type ILankaScenario as a, type ILankaEventMetadata as b, type TLankaEventBusMiddleware as c, type ILankaEventLog as d, type TLankaEventBusDecision as e };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { I as ILankaApiError } from './ILankaApiError-zI_2bNs0.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How a request ended.
|
|
5
|
+
*
|
|
6
|
+
* Six kinds rather than one, for one reason: each demands something DIFFERENT of
|
|
7
|
+
* the interface. A distinction that implies no different behaviour is
|
|
8
|
+
* superfluous, which is why there is no seventh.
|
|
9
|
+
*/
|
|
10
|
+
type TLankaErrorKind =
|
|
11
|
+
/** Never reached the server: dropped link, DNS failure, no network. Offer a retry. */
|
|
12
|
+
"network"
|
|
13
|
+
/** Reached it; the response never came. Also a retry, but a different message. */
|
|
14
|
+
| "timeout"
|
|
15
|
+
/** Cancelled by the caller. Nothing to show: the user left. */
|
|
16
|
+
| "aborted"
|
|
17
|
+
/** The server answered with an error status; what to show depends on it. */
|
|
18
|
+
| "http"
|
|
19
|
+
/** A response arrived in the wrong shape. A break, not the user's fault. */
|
|
20
|
+
| "schema"
|
|
21
|
+
/** The server refused deliberately and named the reason. Show what it said. */
|
|
22
|
+
| "domain";
|
|
23
|
+
interface ILankaErrorInit {
|
|
24
|
+
kind: TLankaErrorKind;
|
|
25
|
+
message: string;
|
|
26
|
+
/** HTTP status, when there was one. */
|
|
27
|
+
status?: number;
|
|
28
|
+
/** The domain failure code — what the application branches on. */
|
|
29
|
+
code?: string;
|
|
30
|
+
/** Details: server messages, or paths to the fields that failed validation. */
|
|
31
|
+
issues?: readonly string[];
|
|
32
|
+
/**
|
|
33
|
+
* The parsed ERROR response body, when there was one and it was JSON.
|
|
34
|
+
*
|
|
35
|
+
* Travels with the error because a `Response` is read once: without this field
|
|
36
|
+
* a plugin extracting the domain failure code would read an already-drained
|
|
37
|
+
* stream and get nothing. Core does not look into the body; it carries it.
|
|
38
|
+
*/
|
|
39
|
+
body?: unknown;
|
|
40
|
+
/** The original error, when this one wraps it. */
|
|
41
|
+
cause?: unknown;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* One failure type for every layer of the framework.
|
|
45
|
+
*
|
|
46
|
+
* Without a tagged kind, an app cannot tell a network failure from a timeout,
|
|
47
|
+
* from a broken schema, from a deliberate domain refusal — so it builds its own
|
|
48
|
+
* error contract ON TOP of the framework, and builds it once per application.
|
|
49
|
+
*
|
|
50
|
+
* Implements `ILankaApiError`: `status` and `errors` are present, so code reading
|
|
51
|
+
* them the old way keeps working.
|
|
52
|
+
*
|
|
53
|
+
* What is NOT here: parsing a particular response body format. Which JSON a
|
|
54
|
+
* backend sends is policy, and policy lives in `@lankajs/plugin-http`. Core knows
|
|
55
|
+
* only that it has a failure and must name its kind.
|
|
56
|
+
*/
|
|
57
|
+
declare class LankaError extends Error implements ILankaApiError {
|
|
58
|
+
readonly kind: TLankaErrorKind;
|
|
59
|
+
readonly status?: number;
|
|
60
|
+
readonly code?: string;
|
|
61
|
+
readonly issues?: readonly string[];
|
|
62
|
+
/** The parsed error response body; core carries it without reading it. */
|
|
63
|
+
readonly body?: unknown;
|
|
64
|
+
constructor(init: ILankaErrorInit);
|
|
65
|
+
/** The `ILankaApiError` field. The details are the message list. */
|
|
66
|
+
get errors(): string[] | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Whether to show this to the user.
|
|
69
|
+
*
|
|
70
|
+
* A cancelled request is the one failure that must NOT be reported: its cause
|
|
71
|
+
* is that the user left before the response, and a toast would catch them on
|
|
72
|
+
* another screen.
|
|
73
|
+
*/
|
|
74
|
+
get isSilent(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Recognises our error among others.
|
|
77
|
+
*
|
|
78
|
+
* Checks the name rather than `instanceof` alone: a consumer may end up with
|
|
79
|
+
* two copies of the package — adjacent majors in the dependency tree — and
|
|
80
|
+
* then `instanceof` answers `false` for an error that is ours by every other
|
|
81
|
+
* sign.
|
|
82
|
+
*/
|
|
83
|
+
static is(value: unknown): value is LankaError;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { type ILankaErrorInit as I, LankaError as L, type TLankaErrorKind as T };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { a as ILankaScenario, I as ILankaScenarioVM } from './ILankaScenarioVM-DuCyPoyT.js';
|
|
2
|
+
import { I as ILankaScenarioMetadata } from './ILankaScenarioMetadata-Bu-yggTZ.js';
|
|
3
|
+
import { A as ALankaGateway } from './ALankaGateway-ExlRGT3D.js';
|
|
4
|
+
import { A as ALankaLocator } from './LankaSharedStoreLocator-MvCpav5F.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The scenario registry: both those that registered themselves and those
|
|
8
|
+
* registered by hand.
|
|
9
|
+
*
|
|
10
|
+
* `ALankaScenario` subclasses arrive here automatically unless they opted out.
|
|
11
|
+
*/
|
|
12
|
+
declare class LankaScenariosRegistry {
|
|
13
|
+
private registeredScenarios;
|
|
14
|
+
private scenarioMetadata;
|
|
15
|
+
/**
|
|
16
|
+
* Public: the registry belongs to a framework instance rather than to the
|
|
17
|
+
* module.
|
|
18
|
+
*/
|
|
19
|
+
constructor();
|
|
20
|
+
/**
|
|
21
|
+
* The active instance's registry, for callers that cannot hold one:
|
|
22
|
+
* `ALankaScenario` (a base class the consumer extends) and the static
|
|
23
|
+
* `LankaScenarioBootstrap`. Instance holders read `lanka.scenarios`.
|
|
24
|
+
*/
|
|
25
|
+
static getInstance(): LankaScenariosRegistry;
|
|
26
|
+
/**
|
|
27
|
+
* Registers a scenario by hand.
|
|
28
|
+
*
|
|
29
|
+
* @param scenario What to register
|
|
30
|
+
* @returns `false` when it was already registered
|
|
31
|
+
*/
|
|
32
|
+
register(scenario: ILankaScenario<unknown>): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Unregister a scenario
|
|
35
|
+
* @param scenarioName Name of the scenario to unregister
|
|
36
|
+
* @returns true if unregistered successfully, false if not found
|
|
37
|
+
*/
|
|
38
|
+
unregister(scenarioName: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Get metadata for a specific scenario
|
|
41
|
+
* @param scenarioName Name of the scenario
|
|
42
|
+
* @returns Scenario metadata or undefined if not found
|
|
43
|
+
*/
|
|
44
|
+
getMetadata(scenarioName: string): ILankaScenarioMetadata | undefined;
|
|
45
|
+
/** Every registered scenario. */
|
|
46
|
+
getAllScenarios(): ILankaScenario<unknown>[];
|
|
47
|
+
/** Metadata of every scenario. */
|
|
48
|
+
getAllMetadata(): ILankaScenarioMetadata[];
|
|
49
|
+
/** Whether a scenario with this name is registered. */
|
|
50
|
+
isRegistered(scenarioName: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Collects every scenario that registered itself at construction.
|
|
53
|
+
*/
|
|
54
|
+
collectAutoRegisteredScenarios(): void;
|
|
55
|
+
/**
|
|
56
|
+
* A scenario by name.
|
|
57
|
+
*
|
|
58
|
+
* @returns `undefined` when there is none
|
|
59
|
+
*/
|
|
60
|
+
getScenarioByName(scenarioName: string): ILankaScenario<unknown> | undefined;
|
|
61
|
+
/** Every registered ViewModel. */
|
|
62
|
+
getAllViewModels(): ILankaScenarioVM[];
|
|
63
|
+
/**
|
|
64
|
+
* Clears every registered scenario. Required by tests.
|
|
65
|
+
*/
|
|
66
|
+
clear(): void;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The registry of ViewModels that use scenarios.
|
|
71
|
+
*
|
|
72
|
+
* They arrive by themselves: the factory registers a ViewModel when it declares
|
|
73
|
+
* scenario handlers.
|
|
74
|
+
*/
|
|
75
|
+
declare class LankaScenarioVMRegistry {
|
|
76
|
+
private registeredViewModels;
|
|
77
|
+
/**
|
|
78
|
+
* Public: the registry belongs to a framework instance rather than to the
|
|
79
|
+
* module.
|
|
80
|
+
*/
|
|
81
|
+
constructor();
|
|
82
|
+
/**
|
|
83
|
+
* The active instance's registry, for callers that cannot hold one — the
|
|
84
|
+
* static `LankaScenarioBootstrap`. Instance holders read `lanka.viewModels`.
|
|
85
|
+
*/
|
|
86
|
+
static getInstance(): LankaScenarioVMRegistry;
|
|
87
|
+
/** Whether this ViewModel is already registered. */
|
|
88
|
+
isRegistered(viewModel: ILankaScenarioVM): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Registers a ViewModel.
|
|
91
|
+
*
|
|
92
|
+
* @returns `false` when it was already registered
|
|
93
|
+
*/
|
|
94
|
+
register(viewModel: ILankaScenarioVM): boolean;
|
|
95
|
+
/** Removes a ViewModel from the registry. */
|
|
96
|
+
unregister(viewModel: ILankaScenarioVM): void;
|
|
97
|
+
/** Every registered ViewModel. */
|
|
98
|
+
getAllViewModels(): ILankaScenarioVM[];
|
|
99
|
+
/**
|
|
100
|
+
* Clears every registered ViewModel. Required by tests.
|
|
101
|
+
*/
|
|
102
|
+
clear(): void;
|
|
103
|
+
/**
|
|
104
|
+
* Unsubscribes every registered ViewModel from its scenarios and clears the
|
|
105
|
+
* registry.
|
|
106
|
+
*
|
|
107
|
+
* Without it tests are not isolated: a subscription leaks from test to test.
|
|
108
|
+
*/
|
|
109
|
+
resetAll(): void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Resolves a gateway by property name (camelCase) or class name (PascalCase),
|
|
114
|
+
* constructing it lazily and caching the instance.
|
|
115
|
+
*
|
|
116
|
+
* Adding a gateway takes one export line in `@lanka_di/Gateways`: types are
|
|
117
|
+
* inferred and nothing is registered.
|
|
118
|
+
*/
|
|
119
|
+
declare class LankaGatewayLocator extends ALankaLocator<ALankaGateway<unknown>> {
|
|
120
|
+
constructor();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Resolves scenarios by property name (camelCase) or scenario name
|
|
125
|
+
* (PascalCase).
|
|
126
|
+
*
|
|
127
|
+
* Looks in the registry, then in the self-registration pool, and failing both
|
|
128
|
+
* constructs the scenario from the consumer's barrel on first use.
|
|
129
|
+
*/
|
|
130
|
+
declare class LankaScenarioLocator extends ALankaLocator<ILankaScenario<unknown>> {
|
|
131
|
+
/**
|
|
132
|
+
* The registry is read LAZILY rather than in a field initialiser.
|
|
133
|
+
*
|
|
134
|
+
* The locator is constructed INSIDE `createLanka`, before the instance becomes
|
|
135
|
+
* active. A field initialiser would ask for the active instance at that moment
|
|
136
|
+
* and fail with "no instance yet" while the instance being created is on the
|
|
137
|
+
* stack. Deferred reading resolves it: by the first scenario resolution an
|
|
138
|
+
* active instance exists.
|
|
139
|
+
*/
|
|
140
|
+
private get registry();
|
|
141
|
+
constructor();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export { LankaGatewayLocator as L, LankaScenarioLocator as a, LankaScenarioVMRegistry as b, LankaScenariosRegistry as c };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { A as ALankaSharedStore } from './ALankaSharedStore-B7uepuuk.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolves instances by camelCase property name, mapping it to the PascalCase
|
|
5
|
+
* class name.
|
|
6
|
+
*/
|
|
7
|
+
interface ILankaLocator<TInstance> {
|
|
8
|
+
/**
|
|
9
|
+
* The instance for a camelCase property name.
|
|
10
|
+
*
|
|
11
|
+
* @param propertyName For example, `userGateway`
|
|
12
|
+
* @throws If no such instance exists
|
|
13
|
+
*/
|
|
14
|
+
get(propertyName: string): TInstance;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Base locator configuration.
|
|
19
|
+
*/
|
|
20
|
+
interface ILankaLocatorConfig<TInstance> {
|
|
21
|
+
/** How to find a constructor by class name. */
|
|
22
|
+
findClassByName: (name: string) => (new () => TInstance) | undefined;
|
|
23
|
+
/** How to create an object from a constructor. */
|
|
24
|
+
createInstance?: (Class: new () => TInstance) => TInstance;
|
|
25
|
+
/** Custom resolution by name, when the ordinary one is not enough. */
|
|
26
|
+
getInstanceByName?: (name: string) => TInstance | undefined;
|
|
27
|
+
/** What to say when there is no such object. */
|
|
28
|
+
notFoundError?: (name: string, propertyName: string) => string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The locator base: resolves objects by property name (camelCase), translating
|
|
32
|
+
* it into a class name (PascalCase).
|
|
33
|
+
*
|
|
34
|
+
* Handles what every locator shares — name translation, construction on first
|
|
35
|
+
* use from the barrel's exports, and caching what was constructed.
|
|
36
|
+
*/
|
|
37
|
+
declare abstract class ALankaLocator<TInstance> implements ILankaLocator<TInstance> {
|
|
38
|
+
protected readonly instanceCache: Map<string, TInstance>;
|
|
39
|
+
protected readonly registeredClasses: Map<string, new () => TInstance>;
|
|
40
|
+
protected readonly registeredInstances: Map<string, TInstance>;
|
|
41
|
+
protected readonly config: ILankaLocatorConfig<TInstance> & {
|
|
42
|
+
createInstance: (Class: new () => TInstance) => TInstance;
|
|
43
|
+
notFoundError: (name: string, propertyName: string) => string;
|
|
44
|
+
};
|
|
45
|
+
protected constructor(config: ILankaLocatorConfig<TInstance>);
|
|
46
|
+
/**
|
|
47
|
+
* An object by class name.
|
|
48
|
+
*
|
|
49
|
+
* The cache first, then custom resolution when configured, and only then
|
|
50
|
+
* construction.
|
|
51
|
+
*/
|
|
52
|
+
protected getInstanceByName(instanceName: string): TInstance | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* An object by property name (camelCase).
|
|
55
|
+
*
|
|
56
|
+
* Throws when there is none: a silent `undefined` would surface layers later.
|
|
57
|
+
*/
|
|
58
|
+
get(propertyName: string): TInstance;
|
|
59
|
+
/**
|
|
60
|
+
* Clears the instance cache. Required by tests.
|
|
61
|
+
*/
|
|
62
|
+
clearCache(): void;
|
|
63
|
+
/**
|
|
64
|
+
* Registers a class by hand, ahead of the consumer's barrel.
|
|
65
|
+
*
|
|
66
|
+
* The cache entry is dropped: what it holds was built from the previous class.
|
|
67
|
+
*/
|
|
68
|
+
register(className: string, Class: new () => TInstance): void;
|
|
69
|
+
/**
|
|
70
|
+
* Registers an already-built object by hand.
|
|
71
|
+
*
|
|
72
|
+
* It goes straight into the cache: there is nothing left to construct, and a
|
|
73
|
+
* later lookup must not build a rival.
|
|
74
|
+
*/
|
|
75
|
+
registerInstance(className: string, instance: TInstance): void;
|
|
76
|
+
/** Removes a class or object registered by hand, and what was built from it. */
|
|
77
|
+
unregister(className: string): void;
|
|
78
|
+
/** Whether this name resolves to anything the locator already holds. */
|
|
79
|
+
isRegistered(className: string): boolean;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* LankaSingletonLocator configuration.
|
|
84
|
+
*/
|
|
85
|
+
interface ILankaSingletonLocatorConfig {
|
|
86
|
+
/** The module holding singleton classes — the consumer's barrel. */
|
|
87
|
+
singletonIndexModule?: Record<string, unknown>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Resolves singletons by property name (camelCase) or class name (PascalCase),
|
|
91
|
+
* constructing them on first use and caching them.
|
|
92
|
+
*
|
|
93
|
+
* A class arrives either from the consumer's barrel or registered by hand — the
|
|
94
|
+
* latter for tests and for objects that arrive already built.
|
|
95
|
+
*/
|
|
96
|
+
declare class LankaSingletonLocator extends ALankaLocator<unknown> {
|
|
97
|
+
private readonly singletonIndexModule?;
|
|
98
|
+
constructor(config?: ILankaSingletonLocatorConfig);
|
|
99
|
+
/**
|
|
100
|
+
* Creates a NEW service object, bypassing the locator's cache.
|
|
101
|
+
*
|
|
102
|
+
* For scopes: they take the class from here and set the lifetime themselves.
|
|
103
|
+
* The root cache is untouched — otherwise the first resolution inside a scope
|
|
104
|
+
* would replace the application's root object.
|
|
105
|
+
*/
|
|
106
|
+
createScopedInstance(className: string, propertyName: string): unknown;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
type TSharedStoreState = object;
|
|
110
|
+
/**
|
|
111
|
+
* LankaSharedStoreLocator configuration.
|
|
112
|
+
*/
|
|
113
|
+
interface ILankaSharedStoreLocatorConfig {
|
|
114
|
+
/** The module holding shared store classes — the consumer's barrel. */
|
|
115
|
+
sharedStoreIndexModule?: Record<string, unknown>;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolves shared stores by property name (camelCase) or class name
|
|
119
|
+
* (PascalCase), constructing them on first use and caching them.
|
|
120
|
+
*/
|
|
121
|
+
declare class LankaSharedStoreLocator extends ALankaLocator<ALankaSharedStore<TSharedStoreState>> {
|
|
122
|
+
private readonly sharedStoreIndexModule?;
|
|
123
|
+
constructor(config?: ILankaSharedStoreLocatorConfig);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export { ALankaLocator as A, type ILankaLocatorConfig as I, LankaSharedStoreLocator as L, type ILankaLocator as a, LankaSingletonLocator as b, type ILankaSharedStoreLocatorConfig as c, type ILankaSingletonLocatorConfig as d };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export { L as LankaGatewayLocator, a as LankaScenarioLocator, b as LankaScenarioVMRegistry, c as LankaScenariosRegistry } from '../LankaScenarioLocator-BGQHwf3n.js';
|
|
2
|
+
import { a as ILankaLocator } from '../LankaSharedStoreLocator-MvCpav5F.js';
|
|
3
|
+
export { A as ALankaLocator, L as LankaSharedStoreLocator, b as LankaSingletonLocator } from '../LankaSharedStoreLocator-MvCpav5F.js';
|
|
4
|
+
export { c as createLankaScope } from '../createLankaScope-Bc_vChRs.js';
|
|
5
|
+
export { c as composeLankaRequestMiddleware } from '../lankaRequestMiddleware-DAC5kCb7.js';
|
|
6
|
+
import '../ILankaScenarioVM-DuCyPoyT.js';
|
|
7
|
+
import '../ILankaScenarioMetadata-Bu-yggTZ.js';
|
|
8
|
+
import '../ALankaGateway-ExlRGT3D.js';
|
|
9
|
+
import '../lankaStandardValidator-CL-r-zEV.js';
|
|
10
|
+
import '@standard-schema/spec';
|
|
11
|
+
import '../ALankaSharedStore-B7uepuuk.js';
|
|
12
|
+
import 'zustand/vanilla';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Configuration of the global locator proxy.
|
|
16
|
+
*/
|
|
17
|
+
interface ILankaLocatorProxyConfig<TInstance> {
|
|
18
|
+
/** The locator that actually resolves instances. */
|
|
19
|
+
locator: ILankaLocator<TInstance>;
|
|
20
|
+
/** Properties whose access must throw. */
|
|
21
|
+
protectedProperties?: string[];
|
|
22
|
+
/** Prefix of the message thrown for an unknown property. */
|
|
23
|
+
errorPrefix?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a Proxy for dynamic access to instances with type safety.
|
|
27
|
+
* Converts camelCase property access to PascalCase instance names.
|
|
28
|
+
*
|
|
29
|
+
* @param config Proxy configuration
|
|
30
|
+
* @returns Proxy object typed as TType
|
|
31
|
+
*/
|
|
32
|
+
declare function createLankaLocatorProxy<TInstance, TType extends Record<string, TInstance>>(config: ILankaLocatorProxyConfig<TInstance>): TType;
|
|
33
|
+
|
|
34
|
+
export { type ILankaLocatorProxyConfig, createLankaLocatorProxy };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LankaGatewayLocator,
|
|
3
|
+
LankaScenarioLocator,
|
|
4
|
+
createLankaScope
|
|
5
|
+
} from "../chunk-FIR4XTBL.js";
|
|
6
|
+
import {
|
|
7
|
+
LankaScenarioVMRegistry,
|
|
8
|
+
LankaScenariosRegistry
|
|
9
|
+
} from "../chunk-EWVDJYCC.js";
|
|
10
|
+
import {
|
|
11
|
+
composeLankaRequestMiddleware
|
|
12
|
+
} from "../chunk-YR4MZXMU.js";
|
|
13
|
+
import {
|
|
14
|
+
createLankaLocatorProxy
|
|
15
|
+
} from "../chunk-DTO27QFR.js";
|
|
16
|
+
import {
|
|
17
|
+
ALankaLocator,
|
|
18
|
+
LankaSharedStoreLocator,
|
|
19
|
+
LankaSingletonLocator
|
|
20
|
+
} from "../chunk-ILQNYQY5.js";
|
|
21
|
+
import "../chunk-C2HP7CRD.js";
|
|
22
|
+
import "../chunk-D27MREPB.js";
|
|
23
|
+
import "../chunk-BGVDPDX4.js";
|
|
24
|
+
export {
|
|
25
|
+
ALankaLocator,
|
|
26
|
+
LankaGatewayLocator,
|
|
27
|
+
LankaScenarioLocator,
|
|
28
|
+
LankaScenarioVMRegistry,
|
|
29
|
+
LankaScenariosRegistry,
|
|
30
|
+
LankaSharedStoreLocator,
|
|
31
|
+
LankaSingletonLocator,
|
|
32
|
+
composeLankaRequestMiddleware,
|
|
33
|
+
createLankaLocatorProxy,
|
|
34
|
+
createLankaScope
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=index.js.map
|