@nwire/app 0.7.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 +60 -0
- package/dist/__tests__/define-plugin.test.d.ts +16 -0
- package/dist/__tests__/define-plugin.test.d.ts.map +1 -0
- package/dist/__tests__/define-plugin.test.js +269 -0
- package/dist/__tests__/define-plugin.test.js.map +1 -0
- package/dist/__tests__/framework-events.test.d.ts +18 -0
- package/dist/__tests__/framework-events.test.d.ts.map +1 -0
- package/dist/__tests__/framework-events.test.js +156 -0
- package/dist/__tests__/framework-events.test.js.map +1 -0
- package/dist/app.d.ts +25 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +25 -0
- package/dist/app.js.map +1 -0
- package/dist/define-plugin.d.ts +150 -0
- package/dist/define-plugin.d.ts.map +1 -0
- package/dist/define-plugin.js +72 -0
- package/dist/define-plugin.js.map +1 -0
- package/dist/framework-event-bus.d.ts +89 -0
- package/dist/framework-event-bus.d.ts.map +1 -0
- package/dist/framework-event-bus.js +154 -0
- package/dist/framework-event-bus.js.map +1 -0
- package/dist/framework-events.d.ts +217 -0
- package/dist/framework-events.d.ts.map +1 -0
- package/dist/framework-events.js +142 -0
- package/dist/framework-events.js.map +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alex Gefter / 200apps Ltd.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# @nwire/app
|
|
2
|
+
|
|
3
|
+
> Container + plugin lifecycle + envelope — the app layer of the sealed v1.0 architecture.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
Composes modules and plugins into a managed Container, fires typed framework events at every lifecycle transition, and propagates correlation / tracing / tenant via the envelope. `definePlugin` is the single extension primitive; the bus carries `App*` events (`AppRegistering`, `AppBooting`, `AppBooted`, `AppReady`, `AppShuttingDown`, `AppShutdown`) plus any plugins declare themselves.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @nwire/app
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { FrameworkEventBus, AppBooted, defineFrameworkEvent } from "@nwire/app";
|
|
19
|
+
import { NoopLogger } from "@nwire/logger";
|
|
20
|
+
|
|
21
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
22
|
+
|
|
23
|
+
bus.on(AppBooted, async ({ appName, bootedAt }) => {
|
|
24
|
+
console.log(`${appName} booted at ${bootedAt}`);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const TenantSwitched = defineFrameworkEvent<{ tenantId: string }>(
|
|
28
|
+
"app.tenant-switched",
|
|
29
|
+
"parallel",
|
|
30
|
+
);
|
|
31
|
+
bus.on(TenantSwitched, ({ tenantId }) => console.log(`switched to ${tenantId}`));
|
|
32
|
+
|
|
33
|
+
await bus.fire(TenantSwitched, { tenantId: "acme" });
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## API surface
|
|
37
|
+
|
|
38
|
+
- `defineFrameworkEvent<TPayload>(name, mode)` — declare a typed lifecycle event.
|
|
39
|
+
- `FrameworkEventBus` — typed dispatcher; one per app instance.
|
|
40
|
+
- `AppRegistering` / `AppBooting` / `AppBooted` / `AppReady` / `AppShuttingDown` / `AppShutdown` — built-in lifecycle events.
|
|
41
|
+
- `definePlugin(name, setup)` — closure-form plugin with `bind` / `provide` / `on` / `before` / `after` / `middleware` / `boot` / `shutdown`.
|
|
42
|
+
- Dispatch modes — `parallel` (`*-ed`, fire-and-forget), `series` (sequential await), `series-bail` (`*-ing`, vetoable).
|
|
43
|
+
|
|
44
|
+
## When to use
|
|
45
|
+
|
|
46
|
+
The composition root for any non-trivial Nwire app. Standalone (L2): use framework events as a generic typed pub/sub for any lifecycle. Full-stack (L4/L5): pair with `@nwire/forge` and the bus carries `ActionDispatching` / `ActionCompleted` / `ActionFailed` alongside lifecycle events.
|
|
47
|
+
|
|
48
|
+
## Used only within nwire-app
|
|
49
|
+
|
|
50
|
+
This package is part of the Nwire stack — it only makes sense inside a Nwire application built with `@nwire/app` + `@nwire/forge`. If you're looking for a standalone primitive, see:
|
|
51
|
+
|
|
52
|
+
- [`@nwire/handler`](../nwire-handler/README.md) — the operation primitive (transport-agnostic)
|
|
53
|
+
- [`@nwire/hooks`](../nwire-hooks/README.md) — universal dispatch (chain + listeners)
|
|
54
|
+
- [`@nwire/http`](../nwire-http/README.md) — typed HTTP without forge
|
|
55
|
+
- [`@nwire/endpoint`](../nwire-endpoint/README.md) — graceful shutdown for any host
|
|
56
|
+
|
|
57
|
+
## See also
|
|
58
|
+
|
|
59
|
+
- [Architecture sketch §05 — App tier](../../architecture-sketch.html#packages)
|
|
60
|
+
- Sibling packages: [@nwire/container](../nwire-container), [@nwire/endpoint](../nwire-endpoint), [@nwire/forge](../nwire-forge)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `definePlugin` (app-layer) — proves the narrow shape works standalone.
|
|
3
|
+
*
|
|
4
|
+
* We exercise every builder in the AppPluginContext using a tiny inline
|
|
5
|
+
* "runner" that mimics what `createApp` will do once it's also extracted:
|
|
6
|
+
* call `setup(ctx)`, collect what the closure registered, then invoke
|
|
7
|
+
* provide/boot/shutdown in the documented order, firing framework events
|
|
8
|
+
* at the transitions.
|
|
9
|
+
*
|
|
10
|
+
* The point: this primitive is genuinely standalone. No forge, no
|
|
11
|
+
* @nwire/http, no container-awilix. A consumer with `@nwire/app` +
|
|
12
|
+
* `@nwire/container` + `@nwire/logger` can build their own minimal
|
|
13
|
+
* lifecycle on top.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=define-plugin.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-plugin.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/define-plugin.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `definePlugin` (app-layer) — proves the narrow shape works standalone.
|
|
3
|
+
*
|
|
4
|
+
* We exercise every builder in the AppPluginContext using a tiny inline
|
|
5
|
+
* "runner" that mimics what `createApp` will do once it's also extracted:
|
|
6
|
+
* call `setup(ctx)`, collect what the closure registered, then invoke
|
|
7
|
+
* provide/boot/shutdown in the documented order, firing framework events
|
|
8
|
+
* at the transitions.
|
|
9
|
+
*
|
|
10
|
+
* The point: this primitive is genuinely standalone. No forge, no
|
|
11
|
+
* @nwire/http, no container-awilix. A consumer with `@nwire/app` +
|
|
12
|
+
* `@nwire/container` + `@nwire/logger` can build their own minimal
|
|
13
|
+
* lifecycle on top.
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it, expect } from "vitest";
|
|
16
|
+
import { InMemoryContainer } from "@nwire/container";
|
|
17
|
+
import { NoopLogger } from "@nwire/logger";
|
|
18
|
+
import { definePlugin, isAppPlugin, FrameworkEventBus, AppBooting, AppBooted, AppShuttingDown, } from "../app.js";
|
|
19
|
+
/**
|
|
20
|
+
* Tiny app runner that exercises the plugin context. This will be
|
|
21
|
+
* replaced by the real `createApp` in `@nwire/app` once the rest of
|
|
22
|
+
* Phase 69 lands. For now, this proves the primitive's surface works.
|
|
23
|
+
*/
|
|
24
|
+
async function runMinimalApp(plugins) {
|
|
25
|
+
const container = new InMemoryContainer();
|
|
26
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
27
|
+
/**
|
|
28
|
+
* Accumulators — the plugin context's builders push into these.
|
|
29
|
+
* The runner consumes them at the right lifecycle moment.
|
|
30
|
+
*/
|
|
31
|
+
const provides = [];
|
|
32
|
+
const boots = [];
|
|
33
|
+
const shutdowns = [];
|
|
34
|
+
/**
|
|
35
|
+
* Track booted values so the runner can call their `shutdown(value)`
|
|
36
|
+
* at the right time — same way the real createApp will.
|
|
37
|
+
*/
|
|
38
|
+
const booted = [];
|
|
39
|
+
const ctx = {
|
|
40
|
+
container,
|
|
41
|
+
bus,
|
|
42
|
+
provide(name, lifecycle) {
|
|
43
|
+
provides.push({ name, lifecycle: lifecycle });
|
|
44
|
+
},
|
|
45
|
+
on(event, handler, priority) {
|
|
46
|
+
bus.on(event, handler, priority);
|
|
47
|
+
},
|
|
48
|
+
boot(fn) {
|
|
49
|
+
boots.push(fn);
|
|
50
|
+
},
|
|
51
|
+
shutdown(fn) {
|
|
52
|
+
shutdowns.push(fn);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
// 1. Run plugin setups in order
|
|
56
|
+
for (const p of plugins) {
|
|
57
|
+
await p.setup(ctx);
|
|
58
|
+
}
|
|
59
|
+
// 2. Fire AppBooting (interceptable)
|
|
60
|
+
const allowBoot = await bus.fire(AppBooting, { appName: "test" });
|
|
61
|
+
if (!allowBoot)
|
|
62
|
+
throw new Error("boot vetoed");
|
|
63
|
+
// 3. Resolve all bindings via their lifecycle.boot()
|
|
64
|
+
for (const { name, lifecycle } of provides) {
|
|
65
|
+
const value = await lifecycle.boot();
|
|
66
|
+
container.register(name, () => value);
|
|
67
|
+
booted.push({
|
|
68
|
+
name,
|
|
69
|
+
value,
|
|
70
|
+
shutdown: lifecycle.shutdown,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// 4. Run plugin boot() callbacks in order
|
|
74
|
+
for (const fn of boots)
|
|
75
|
+
await fn();
|
|
76
|
+
// 5. Fire AppBooted (observable)
|
|
77
|
+
await bus.fire(AppBooted, { appName: "test", bootedAt: new Date().toISOString() });
|
|
78
|
+
// Return a "running app" handle the test can interact with
|
|
79
|
+
return {
|
|
80
|
+
container,
|
|
81
|
+
bus,
|
|
82
|
+
async shutdown() {
|
|
83
|
+
// 6. Fire AppShuttingDown (interceptable)
|
|
84
|
+
const allow = await bus.fire(AppShuttingDown, { appName: "test" });
|
|
85
|
+
if (!allow)
|
|
86
|
+
throw new Error("shutdown vetoed");
|
|
87
|
+
// 7. Plugin shutdown callbacks in REVERSE order
|
|
88
|
+
for (let i = shutdowns.length - 1; i >= 0; i--) {
|
|
89
|
+
await shutdowns[i]();
|
|
90
|
+
}
|
|
91
|
+
// 8. Binding shutdowns in REVERSE order (last-registered first)
|
|
92
|
+
for (let i = booted.length - 1; i >= 0; i--) {
|
|
93
|
+
const b = booted[i];
|
|
94
|
+
if (b.shutdown)
|
|
95
|
+
await b.shutdown(b.value);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
describe("definePlugin (app layer)", () => {
|
|
101
|
+
it("returns a discriminable AppPluginDefinition", () => {
|
|
102
|
+
const p = definePlugin("test", () => undefined);
|
|
103
|
+
expect(isAppPlugin(p)).toBe(true);
|
|
104
|
+
expect(p.name).toBe("test");
|
|
105
|
+
expect(typeof p.setup).toBe("function");
|
|
106
|
+
});
|
|
107
|
+
it("isAppPlugin returns false for unrelated objects", () => {
|
|
108
|
+
expect(isAppPlugin({ name: "fake" })).toBe(false);
|
|
109
|
+
expect(isAppPlugin(null)).toBe(false);
|
|
110
|
+
expect(isAppPlugin("string")).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe("definePlugin — provide bindings", () => {
|
|
114
|
+
it("provides a value that becomes resolvable on the container", async () => {
|
|
115
|
+
class Database {
|
|
116
|
+
ping() {
|
|
117
|
+
return "ok";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const plugin = definePlugin("db", ({ provide }) => {
|
|
121
|
+
provide("db", { boot: () => new Database() });
|
|
122
|
+
});
|
|
123
|
+
const app = await runMinimalApp([plugin]);
|
|
124
|
+
expect(app.container.resolve("db").ping()).toBe("ok");
|
|
125
|
+
await app.shutdown();
|
|
126
|
+
});
|
|
127
|
+
it("provided value's shutdown is called in reverse boot order", async () => {
|
|
128
|
+
const order = [];
|
|
129
|
+
const a = definePlugin("a", ({ provide }) => {
|
|
130
|
+
provide("a", {
|
|
131
|
+
boot: () => "a-value",
|
|
132
|
+
shutdown: () => {
|
|
133
|
+
order.push("shutdown:a");
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
const b = definePlugin("b", ({ provide }) => {
|
|
138
|
+
provide("b", {
|
|
139
|
+
boot: () => "b-value",
|
|
140
|
+
shutdown: () => {
|
|
141
|
+
order.push("shutdown:b");
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
const app = await runMinimalApp([a, b]);
|
|
146
|
+
await app.shutdown();
|
|
147
|
+
// Booted a then b, so shutdown happens b first, a second
|
|
148
|
+
expect(order).toEqual(["shutdown:b", "shutdown:a"]);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
describe("definePlugin — framework event subscriptions", () => {
|
|
152
|
+
it("subscriptions fire when the bus fires the event", async () => {
|
|
153
|
+
const seen = [];
|
|
154
|
+
const plugin = definePlugin("observer", ({ on }) => {
|
|
155
|
+
on(AppBooted, ({ appName }) => {
|
|
156
|
+
seen.push(`booted:${appName}`);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
const app = await runMinimalApp([plugin]);
|
|
160
|
+
expect(seen).toEqual(["booted:test"]);
|
|
161
|
+
await app.shutdown();
|
|
162
|
+
});
|
|
163
|
+
it("priority is respected in series-bail dispatch", async () => {
|
|
164
|
+
const order = [];
|
|
165
|
+
const plugin = definePlugin("prio", ({ on }) => {
|
|
166
|
+
on(AppShuttingDown, () => {
|
|
167
|
+
order.push("low");
|
|
168
|
+
}, 0);
|
|
169
|
+
on(AppShuttingDown, () => {
|
|
170
|
+
order.push("highest");
|
|
171
|
+
}, 100);
|
|
172
|
+
on(AppShuttingDown, () => {
|
|
173
|
+
order.push("debug");
|
|
174
|
+
}, -100);
|
|
175
|
+
});
|
|
176
|
+
const app = await runMinimalApp([plugin]);
|
|
177
|
+
await app.shutdown();
|
|
178
|
+
expect(order).toEqual(["highest", "low", "debug"]);
|
|
179
|
+
});
|
|
180
|
+
it("a subscription returning false vetoes a series-bail event", async () => {
|
|
181
|
+
const plugin = definePlugin("blocker", ({ on }) => {
|
|
182
|
+
on(AppShuttingDown, () => false);
|
|
183
|
+
});
|
|
184
|
+
const app = await runMinimalApp([plugin]);
|
|
185
|
+
await expect(app.shutdown()).rejects.toThrow("shutdown vetoed");
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
describe("definePlugin — boot + shutdown callbacks", () => {
|
|
189
|
+
it("boot callbacks run in declaration order", async () => {
|
|
190
|
+
const order = [];
|
|
191
|
+
const plugin = definePlugin("boot-order", ({ boot }) => {
|
|
192
|
+
boot(() => {
|
|
193
|
+
order.push("first");
|
|
194
|
+
});
|
|
195
|
+
boot(() => {
|
|
196
|
+
order.push("second");
|
|
197
|
+
});
|
|
198
|
+
boot(async () => {
|
|
199
|
+
order.push("third");
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
const app = await runMinimalApp([plugin]);
|
|
203
|
+
expect(order).toEqual(["first", "second", "third"]);
|
|
204
|
+
await app.shutdown();
|
|
205
|
+
});
|
|
206
|
+
it("shutdown callbacks run in REVERSE declaration order", async () => {
|
|
207
|
+
const order = [];
|
|
208
|
+
const plugin = definePlugin("shutdown-order", ({ shutdown }) => {
|
|
209
|
+
shutdown(() => {
|
|
210
|
+
order.push("first");
|
|
211
|
+
});
|
|
212
|
+
shutdown(() => {
|
|
213
|
+
order.push("second");
|
|
214
|
+
});
|
|
215
|
+
shutdown(() => {
|
|
216
|
+
order.push("third");
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
const app = await runMinimalApp([plugin]);
|
|
220
|
+
await app.shutdown();
|
|
221
|
+
// Reverse so "third" gets the resources first, undoes its work,
|
|
222
|
+
// then "second" can undo theirs without missing dependencies.
|
|
223
|
+
expect(order).toEqual(["third", "second", "first"]);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
describe("definePlugin — composability", () => {
|
|
227
|
+
it("multiple plugins compose freely; each contribution flows through", async () => {
|
|
228
|
+
/**
|
|
229
|
+
* Realistic scenario: postgres plugin provides db; audit plugin uses
|
|
230
|
+
* AppBooted to log start; tracing plugin subscribes to AppShuttingDown.
|
|
231
|
+
* All compose into one app boot.
|
|
232
|
+
*/
|
|
233
|
+
const logs = [];
|
|
234
|
+
const postgres = definePlugin("postgres", ({ provide }) => {
|
|
235
|
+
provide("db", {
|
|
236
|
+
boot: () => ({ kind: "fake-db" }),
|
|
237
|
+
shutdown: () => {
|
|
238
|
+
logs.push("db-closed");
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
const audit = definePlugin("audit", ({ on, boot }) => {
|
|
243
|
+
on(AppBooted, ({ appName }) => {
|
|
244
|
+
logs.push(`audit-start:${appName}`);
|
|
245
|
+
});
|
|
246
|
+
boot(() => {
|
|
247
|
+
logs.push("audit-init");
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
const tracing = definePlugin("tracing", ({ on }) => {
|
|
251
|
+
on(AppShuttingDown, ({ reason }) => {
|
|
252
|
+
logs.push(`trace-end:${reason ?? "unknown"}`);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
const app = await runMinimalApp([postgres, audit, tracing]);
|
|
256
|
+
expect(logs).toEqual([
|
|
257
|
+
"audit-init", // boot callback fires after providers register
|
|
258
|
+
"audit-start:test", // AppBooted observer fires
|
|
259
|
+
]);
|
|
260
|
+
await app.shutdown();
|
|
261
|
+
expect(logs).toEqual([
|
|
262
|
+
"audit-init",
|
|
263
|
+
"audit-start:test",
|
|
264
|
+
"trace-end:unknown", // AppShuttingDown observer fires first
|
|
265
|
+
"db-closed", // db.shutdown(value) runs in reverse boot order
|
|
266
|
+
]);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
//# sourceMappingURL=define-plugin.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-plugin.test.js","sourceRoot":"","sources":["../../src/__tests__/define-plugin.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,eAAe,GAGhB,MAAM,QAAQ,CAAC;AAEhB;;;;GAIG;AACH,KAAK,UAAU,aAAa,CAAC,OAA0C;IACrE,MAAM,SAAS,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;IAEpD;;;OAGG;IACH,MAAM,QAAQ,GAAkE,EAAE,CAAC;IACnF,MAAM,KAAK,GAAsC,EAAE,CAAC;IACpD,MAAM,SAAS,GAAsC,EAAE,CAAC;IACxD;;;OAGG;IACH,MAAM,MAAM,GAAgF,EAAE,CAAC;IAE/F,MAAM,GAAG,GAAqB;QAC5B,SAAS;QACT,GAAG;QACH,OAAO,CAAI,IAAY,EAAE,SAA8B;YACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAsC,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ;YACzB,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,EAAE;YACL,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QACD,QAAQ,CAAC,EAAE;YACT,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;KACF,CAAC;IAEF,gCAAgC;IAChC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,qCAAqC;IACrC,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAClE,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;IAE/C,qDAAqD;IACrD,KAAK,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACrC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI;YACJ,KAAK;YACL,QAAQ,EAAE,SAAS,CAAC,QAAiD;SACtE,CAAC,CAAC;IACL,CAAC;IAED,0CAA0C;IAC1C,KAAK,MAAM,EAAE,IAAI,KAAK;QAAE,MAAM,EAAE,EAAE,CAAC;IAEnC,iCAAiC;IACjC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAEnF,2DAA2D;IAC3D,OAAO;QACL,SAAS;QACT,GAAG;QACH,KAAK,CAAC,QAAQ;YACZ,0CAA0C;YAC1C,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACnE,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAE/C,gDAAgD;YAChD,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,MAAM,SAAS,CAAC,CAAC,CAAE,EAAE,CAAC;YACxB,CAAC;YAED,gEAAgE;YAChE,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;gBACrB,IAAI,CAAC,CAAC,QAAQ;oBAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,QAAQ;YACZ,IAAI;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;SACF;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YAChD,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,QAAQ,EAAE,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAW,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YAC1C,OAAO,CAAC,GAAG,EAAE;gBACX,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;gBACrB,QAAQ,EAAE,GAAG,EAAE;oBACb,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC3B,CAAC;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YAC1C,OAAO,CAAC,GAAG,EAAE;gBACX,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;gBACrB,QAAQ,EAAE,GAAG,EAAE;oBACb,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC3B,CAAC;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,yDAAyD;QACzD,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,IAAI,GAAa,EAAE,CAAC;QAE1B,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;YACjD,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;QACtC,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;YAC7C,EAAE,CACA,eAAe,EACf,GAAG,EAAE;gBACH,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC,EACD,CAAC,CACF,CAAC;YACF,EAAE,CACA,eAAe,EACf,GAAG,EAAE;gBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC,EACD,GAAG,CACJ,CAAC;YACF,EAAE,CACA,eAAe,EACf,GAAG,EAAE;gBACH,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC,EACD,CAAC,GAAG,CACL,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;YAChD,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;YACrD,IAAI,CAAC,GAAG,EAAE;gBACR,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,EAAE;gBACR,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,IAAI,EAAE;gBACd,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QACpD,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,MAAM,GAAG,YAAY,CAAC,gBAAgB,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC7D,QAAQ,CAAC,GAAG,EAAE;gBACZ,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;YACH,QAAQ,CAAC,GAAG,EAAE;gBACZ,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;YACH,QAAQ,CAAC,GAAG,EAAE;gBACZ,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,gEAAgE;QAChE,8DAA8D;QAC9D,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF;;;;WAIG;QACH,MAAM,IAAI,GAAa,EAAE,CAAC;QAE1B,MAAM,QAAQ,GAAG,YAAY,CAAC,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACxD,OAAO,CAAC,IAAI,EAAE;gBACZ,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;gBACjC,QAAQ,EAAE,GAAG,EAAE;oBACb,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACzB,CAAC;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YACnD,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC5B,IAAI,CAAC,IAAI,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,EAAE;gBACR,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;YACjD,EAAE,CAAC,eAAe,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;gBACjC,IAAI,CAAC,IAAI,CAAC,aAAa,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,YAAY,EAAE,+CAA+C;YAC7D,kBAAkB,EAAE,2BAA2B;SAChD,CAAC,CAAC;QAEH,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,YAAY;YACZ,kBAAkB;YAClB,mBAAmB,EAAE,uCAAuC;YAC5D,WAAW,EAAE,gDAAgD;SAC9D,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the extracted framework-events surface in `@nwire/app`.
|
|
3
|
+
*
|
|
4
|
+
* What we exercise:
|
|
5
|
+
*
|
|
6
|
+
* - `defineFrameworkEvent` returns a discriminable definition
|
|
7
|
+
* - `FrameworkEventBus.fire()` dispatches per mode (parallel / series / series-bail)
|
|
8
|
+
* - `series-bail` honors `false` returns (clean veto) vs throws (failure)
|
|
9
|
+
* - Subscription priority ordering (higher = earlier)
|
|
10
|
+
* - Unsubscribe + handler-count introspection
|
|
11
|
+
* - Built-in lifecycle events have the expected names/modes
|
|
12
|
+
*
|
|
13
|
+
* These tests stand alone — they use only @nwire/app + @nwire/logger.
|
|
14
|
+
* That standalone-ness is the point: framework events are a generic
|
|
15
|
+
* pub/sub primitive useful anywhere, not coupled to forge.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=framework-events.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-events.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/framework-events.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the extracted framework-events surface in `@nwire/app`.
|
|
3
|
+
*
|
|
4
|
+
* What we exercise:
|
|
5
|
+
*
|
|
6
|
+
* - `defineFrameworkEvent` returns a discriminable definition
|
|
7
|
+
* - `FrameworkEventBus.fire()` dispatches per mode (parallel / series / series-bail)
|
|
8
|
+
* - `series-bail` honors `false` returns (clean veto) vs throws (failure)
|
|
9
|
+
* - Subscription priority ordering (higher = earlier)
|
|
10
|
+
* - Unsubscribe + handler-count introspection
|
|
11
|
+
* - Built-in lifecycle events have the expected names/modes
|
|
12
|
+
*
|
|
13
|
+
* These tests stand alone — they use only @nwire/app + @nwire/logger.
|
|
14
|
+
* That standalone-ness is the point: framework events are a generic
|
|
15
|
+
* pub/sub primitive useful anywhere, not coupled to forge.
|
|
16
|
+
*/
|
|
17
|
+
import { describe, it, expect } from "vitest";
|
|
18
|
+
import { NoopLogger } from "@nwire/logger";
|
|
19
|
+
import { defineFrameworkEvent, FrameworkEventBus, AppRegistering, AppBooting, AppBooted, AppShuttingDown, AppShutdown, builtInLifecycleEvents, } from "../app.js";
|
|
20
|
+
describe("defineFrameworkEvent", () => {
|
|
21
|
+
it("produces a discriminable definition with the requested mode", () => {
|
|
22
|
+
const evt = defineFrameworkEvent("test.event", "parallel");
|
|
23
|
+
expect(evt.$kind).toBe("framework-event");
|
|
24
|
+
expect(evt.name).toBe("test.event");
|
|
25
|
+
expect(evt.mode).toBe("parallel");
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe("FrameworkEventBus — dispatch modes", () => {
|
|
29
|
+
it("parallel: every handler runs, errors don't stop siblings", async () => {
|
|
30
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
31
|
+
const evt = defineFrameworkEvent("t.parallel", "parallel");
|
|
32
|
+
const seen = [];
|
|
33
|
+
bus.on(evt, () => {
|
|
34
|
+
seen.push(1);
|
|
35
|
+
});
|
|
36
|
+
bus.on(evt, () => {
|
|
37
|
+
throw new Error("ignored");
|
|
38
|
+
});
|
|
39
|
+
bus.on(evt, () => {
|
|
40
|
+
seen.push(2);
|
|
41
|
+
});
|
|
42
|
+
await bus.fire(evt, undefined);
|
|
43
|
+
expect(seen.sort()).toEqual([1, 2]);
|
|
44
|
+
});
|
|
45
|
+
it("series: handlers run sequentially; one throw kills the chain", async () => {
|
|
46
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
47
|
+
const evt = defineFrameworkEvent("t.series", "series");
|
|
48
|
+
const seen = [];
|
|
49
|
+
bus.on(evt, () => {
|
|
50
|
+
seen.push(1);
|
|
51
|
+
});
|
|
52
|
+
bus.on(evt, () => {
|
|
53
|
+
throw new Error("stop");
|
|
54
|
+
});
|
|
55
|
+
bus.on(evt, () => {
|
|
56
|
+
seen.push(3);
|
|
57
|
+
});
|
|
58
|
+
await expect(bus.fire(evt, undefined)).rejects.toThrow("stop");
|
|
59
|
+
expect(seen).toEqual([1]);
|
|
60
|
+
});
|
|
61
|
+
it("series-bail: false stops the chain cleanly + returns false", async () => {
|
|
62
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
63
|
+
const evt = defineFrameworkEvent("t.bail", "series-bail");
|
|
64
|
+
const seen = [];
|
|
65
|
+
bus.on(evt, () => {
|
|
66
|
+
seen.push(1);
|
|
67
|
+
});
|
|
68
|
+
bus.on(evt, () => false); // veto
|
|
69
|
+
bus.on(evt, () => {
|
|
70
|
+
seen.push(3);
|
|
71
|
+
});
|
|
72
|
+
const ok = await bus.fire(evt, undefined);
|
|
73
|
+
expect(ok).toBe(false);
|
|
74
|
+
expect(seen).toEqual([1]);
|
|
75
|
+
});
|
|
76
|
+
it("series-bail: undefined return continues the chain (fire returns true)", async () => {
|
|
77
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
78
|
+
const evt = defineFrameworkEvent("t.bail2", "series-bail");
|
|
79
|
+
const seen = [];
|
|
80
|
+
bus.on(evt, () => {
|
|
81
|
+
seen.push(1);
|
|
82
|
+
}); // returns undefined — continue
|
|
83
|
+
bus.on(evt, () => {
|
|
84
|
+
seen.push(2);
|
|
85
|
+
});
|
|
86
|
+
const ok = await bus.fire(evt, undefined);
|
|
87
|
+
expect(ok).toBe(true);
|
|
88
|
+
expect(seen).toEqual([1, 2]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("FrameworkEventBus — priority + introspection", () => {
|
|
92
|
+
it("higher priority runs earlier in series + series-bail", async () => {
|
|
93
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
94
|
+
const evt = defineFrameworkEvent("t.priority", "series");
|
|
95
|
+
const order = [];
|
|
96
|
+
bus.on(evt, () => {
|
|
97
|
+
order.push("low");
|
|
98
|
+
}, 0);
|
|
99
|
+
bus.on(evt, () => {
|
|
100
|
+
order.push("highest");
|
|
101
|
+
}, 100);
|
|
102
|
+
bus.on(evt, () => {
|
|
103
|
+
order.push("debug");
|
|
104
|
+
}, -100);
|
|
105
|
+
await bus.fire(evt, undefined);
|
|
106
|
+
expect(order).toEqual(["highest", "low", "debug"]);
|
|
107
|
+
});
|
|
108
|
+
it("unsubscribe removes a handler", async () => {
|
|
109
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
110
|
+
const evt = defineFrameworkEvent("t.unsub", "parallel");
|
|
111
|
+
let calls = 0;
|
|
112
|
+
const off = bus.on(evt, () => {
|
|
113
|
+
calls++;
|
|
114
|
+
});
|
|
115
|
+
await bus.fire(evt, undefined);
|
|
116
|
+
expect(calls).toBe(1);
|
|
117
|
+
off();
|
|
118
|
+
await bus.fire(evt, undefined);
|
|
119
|
+
expect(calls).toBe(1); // didn't increment after unsubscribe
|
|
120
|
+
});
|
|
121
|
+
it("subscriberCount reports the current count", () => {
|
|
122
|
+
const bus = new FrameworkEventBus(new NoopLogger());
|
|
123
|
+
const evt = defineFrameworkEvent("t.count", "parallel");
|
|
124
|
+
expect(bus.subscriberCount(evt)).toBe(0);
|
|
125
|
+
bus.on(evt, () => undefined);
|
|
126
|
+
bus.on(evt, () => undefined);
|
|
127
|
+
expect(bus.subscriberCount(evt)).toBe(2);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe("Built-in lifecycle events", () => {
|
|
131
|
+
/**
|
|
132
|
+
* The names + modes are an API contract — Studio, log aggregators, and
|
|
133
|
+
* external plugins subscribe to specific event names. Pinning them in a
|
|
134
|
+
* test catches accidental renames.
|
|
135
|
+
*/
|
|
136
|
+
it("expose the expected names + modes", () => {
|
|
137
|
+
expect(AppRegistering.name).toBe("nwire.app.registering");
|
|
138
|
+
expect(AppRegistering.mode).toBe("series-bail");
|
|
139
|
+
expect(AppBooting.name).toBe("nwire.app.booting");
|
|
140
|
+
expect(AppBooting.mode).toBe("series-bail");
|
|
141
|
+
expect(AppBooted.name).toBe("nwire.app.booted");
|
|
142
|
+
expect(AppBooted.mode).toBe("parallel");
|
|
143
|
+
expect(AppShuttingDown.name).toBe("nwire.app.shutting-down");
|
|
144
|
+
expect(AppShuttingDown.mode).toBe("series-bail");
|
|
145
|
+
expect(AppShutdown.name).toBe("nwire.app.shutdown");
|
|
146
|
+
expect(AppShutdown.mode).toBe("parallel");
|
|
147
|
+
});
|
|
148
|
+
it("are all in the builtInLifecycleEvents catalog", () => {
|
|
149
|
+
expect(builtInLifecycleEvents).toContain(AppRegistering);
|
|
150
|
+
expect(builtInLifecycleEvents).toContain(AppBooting);
|
|
151
|
+
expect(builtInLifecycleEvents).toContain(AppBooted);
|
|
152
|
+
expect(builtInLifecycleEvents).toContain(AppShuttingDown);
|
|
153
|
+
expect(builtInLifecycleEvents).toContain(AppShutdown);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
//# sourceMappingURL=framework-events.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-events.test.js","sourceRoot":"","sources":["../../src/__tests__/framework-events.test.ts"],"names":[],"mappings":"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"}
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nwire/app` — managed Container with plugin lifecycle and framework events.
|
|
3
|
+
*
|
|
4
|
+
* The "app" layer of the sealed architecture. Composes modules + plugins,
|
|
5
|
+
* boots them in order, exposes a Container, and fires framework events at
|
|
6
|
+
* every lifecycle transition.
|
|
7
|
+
*
|
|
8
|
+
* What it ships:
|
|
9
|
+
*
|
|
10
|
+
* - `defineFrameworkEvent<TPayload>(name, mode)` — declare a typed
|
|
11
|
+
* lifecycle event (`series-bail` / `parallel` / `series` dispatch).
|
|
12
|
+
* - `FrameworkEventBus` — the dispatcher; one per app instance.
|
|
13
|
+
* - `definePlugin(name, setup)` — the only extension primitive.
|
|
14
|
+
* - `App*` events (`AppRegistering` / `AppBooting` / `AppBooted` /
|
|
15
|
+
* `AppReady` / `AppShuttingDown` / `AppShutdown`) plus their plugin
|
|
16
|
+
* counterparts (`PluginRegistered` / `PluginBooting` / `PluginBooted`).
|
|
17
|
+
*
|
|
18
|
+
* `createApp` (the composition root) currently lives in `@nwire/forge`; it
|
|
19
|
+
* will move here in a follow-up. Forge re-exports the framework-event types
|
|
20
|
+
* so consumers don't need to update imports.
|
|
21
|
+
*/
|
|
22
|
+
export { defineFrameworkEvent, AppRegistering, AppBooting, AppBooted, AppReady, AppShuttingDown, AppShutdown, PluginRegistered, PluginBooting, PluginBooted, PluginShuttingDown, PluginShutdown, WireMounting, WireMounted, WireUnmounted, builtInLifecycleEvents, type FrameworkEventDefinition, type FrameworkEventMode, } from "./framework-events.js";
|
|
23
|
+
export { FrameworkEventBus, type FrameworkEventHandler, type FrameworkEventObserver, type FrameworkEventObservation, } from "./framework-event-bus.js";
|
|
24
|
+
export { definePlugin, isAppPlugin, type AppPluginContext, type AppPluginDefinition, type BindingLifecycle, } from "./define-plugin.js";
|
|
25
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,SAAS,EACT,QAAQ,EACR,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,aAAa,EACb,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,GAC/B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,YAAY,EACZ,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC"}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nwire/app` — managed Container with plugin lifecycle and framework events.
|
|
3
|
+
*
|
|
4
|
+
* The "app" layer of the sealed architecture. Composes modules + plugins,
|
|
5
|
+
* boots them in order, exposes a Container, and fires framework events at
|
|
6
|
+
* every lifecycle transition.
|
|
7
|
+
*
|
|
8
|
+
* What it ships:
|
|
9
|
+
*
|
|
10
|
+
* - `defineFrameworkEvent<TPayload>(name, mode)` — declare a typed
|
|
11
|
+
* lifecycle event (`series-bail` / `parallel` / `series` dispatch).
|
|
12
|
+
* - `FrameworkEventBus` — the dispatcher; one per app instance.
|
|
13
|
+
* - `definePlugin(name, setup)` — the only extension primitive.
|
|
14
|
+
* - `App*` events (`AppRegistering` / `AppBooting` / `AppBooted` /
|
|
15
|
+
* `AppReady` / `AppShuttingDown` / `AppShutdown`) plus their plugin
|
|
16
|
+
* counterparts (`PluginRegistered` / `PluginBooting` / `PluginBooted`).
|
|
17
|
+
*
|
|
18
|
+
* `createApp` (the composition root) currently lives in `@nwire/forge`; it
|
|
19
|
+
* will move here in a follow-up. Forge re-exports the framework-event types
|
|
20
|
+
* so consumers don't need to update imports.
|
|
21
|
+
*/
|
|
22
|
+
export { defineFrameworkEvent, AppRegistering, AppBooting, AppBooted, AppReady, AppShuttingDown, AppShutdown, PluginRegistered, PluginBooting, PluginBooted, PluginShuttingDown, PluginShutdown, WireMounting, WireMounted, WireUnmounted, builtInLifecycleEvents, } from "./framework-events.js";
|
|
23
|
+
export { FrameworkEventBus, } from "./framework-event-bus.js";
|
|
24
|
+
export { definePlugin, isAppPlugin, } from "./define-plugin.js";
|
|
25
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,SAAS,EACT,QAAQ,EACR,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,aAAa,EACb,sBAAsB,GAGvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,iBAAiB,GAIlB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,YAAY,EACZ,WAAW,GAIZ,MAAM,iBAAiB,CAAC"}
|