@nwire/forge 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/README.md +133 -155
  2. package/dist/foundation.d.ts +0 -13
  3. package/dist/foundation.js +2 -13
  4. package/dist/framework-events.d.ts +51 -54
  5. package/dist/framework-events.js +18 -65
  6. package/dist/{cli-runner.d.ts → helpers/cli-runner.d.ts} +2 -3
  7. package/dist/{cli-runner.js → helpers/cli-runner.js} +11 -27
  8. package/dist/{public-marker.d.ts → helpers/public-marker.d.ts} +0 -1
  9. package/dist/{public-marker.js → helpers/public-marker.js} +0 -1
  10. package/dist/{response.d.ts → helpers/response.d.ts} +0 -1
  11. package/dist/{response.js → helpers/response.js} +0 -1
  12. package/dist/helpers/retry-helpers.d.ts +22 -0
  13. package/dist/helpers/retry-helpers.js +43 -0
  14. package/dist/{validate.d.ts → helpers/validate.d.ts} +0 -1
  15. package/dist/{validate.js → helpers/validate.js} +0 -1
  16. package/dist/index.d.ts +42 -48
  17. package/dist/index.js +47 -55
  18. package/dist/{event-message.d.ts → messages/event-message.d.ts} +0 -1
  19. package/dist/{event-message.js → messages/event-message.js} +0 -1
  20. package/dist/{dev-logger.d.ts → observability/dev-logger.d.ts} +2 -2
  21. package/dist/{dev-logger.js → observability/dev-logger.js} +0 -30
  22. package/dist/{define-action.d.ts → primitives/define-action.d.ts} +0 -1
  23. package/dist/{define-action.js → primitives/define-action.js} +0 -1
  24. package/dist/{define-actor.d.ts → primitives/define-actor.d.ts} +0 -1
  25. package/dist/{define-actor.js → primitives/define-actor.js} +0 -1
  26. package/dist/{define-cron.d.ts → primitives/define-cron.d.ts} +0 -1
  27. package/dist/{define-cron.js → primitives/define-cron.js} +0 -1
  28. package/dist/{define-error.d.ts → primitives/define-error.d.ts} +0 -1
  29. package/dist/{define-error.js → primitives/define-error.js} +0 -1
  30. package/dist/{define-external-call.d.ts → primitives/define-external-call.d.ts} +0 -1
  31. package/dist/{define-external-call.js → primitives/define-external-call.js} +0 -1
  32. package/dist/{define-handler.d.ts → primitives/define-handler.d.ts} +29 -2
  33. package/dist/{define-handler.js → primitives/define-handler.js} +13 -2
  34. package/dist/{define-inbound-webhook.d.ts → primitives/define-inbound-webhook.d.ts} +1 -2
  35. package/dist/{define-inbound-webhook.js → primitives/define-inbound-webhook.js} +1 -2
  36. package/dist/{define-inbox.d.ts → primitives/define-inbox.d.ts} +0 -1
  37. package/dist/{define-inbox.js → primitives/define-inbox.js} +0 -1
  38. package/dist/{define-outbox.d.ts → primitives/define-outbox.d.ts} +0 -1
  39. package/dist/{define-outbox.js → primitives/define-outbox.js} +0 -1
  40. package/dist/{define-projection.d.ts → primitives/define-projection.d.ts} +0 -1
  41. package/dist/{define-projection.js → primitives/define-projection.js} +0 -1
  42. package/dist/{define-query.d.ts → primitives/define-query.d.ts} +1 -2
  43. package/dist/{define-query.js → primitives/define-query.js} +1 -2
  44. package/dist/{define-schema.d.ts → primitives/define-schema.d.ts} +1 -2
  45. package/dist/{define-schema.js → primitives/define-schema.js} +1 -2
  46. package/dist/{define-upcaster.d.ts → primitives/define-upcaster.d.ts} +0 -1
  47. package/dist/{define-upcaster.js → primitives/define-upcaster.js} +0 -1
  48. package/dist/{define-workflow.d.ts → primitives/define-workflow.d.ts} +2 -3
  49. package/dist/{define-workflow.js → primitives/define-workflow.js} +2 -3
  50. package/dist/runtime/create-forge-app.d.ts +64 -0
  51. package/dist/runtime/create-forge-app.js +78 -0
  52. package/dist/runtime/forge-dispatcher.d.ts +148 -0
  53. package/dist/{runtime.js → runtime/forge-dispatcher.js} +242 -571
  54. package/dist/runtime/forge-plugin.d.ts +59 -0
  55. package/dist/runtime/forge-plugin.js +121 -0
  56. package/dist/runtime/forge-types.d.ts +204 -0
  57. package/dist/runtime/forge-types.js +5 -0
  58. package/dist/{actor-store.d.ts → stores/actor-store.d.ts} +1 -2
  59. package/dist/{actor-store.js → stores/actor-store.js} +0 -1
  60. package/dist/{idempotency-store.d.ts → stores/idempotency-store.d.ts} +0 -1
  61. package/dist/{idempotency-store.js → stores/idempotency-store.js} +0 -1
  62. package/dist/{projection-store.d.ts → stores/projection-store.d.ts} +0 -1
  63. package/dist/{projection-store.js → stores/projection-store.js} +0 -1
  64. package/dist/{workflow-timer-store.d.ts → stores/workflow-timer-store.d.ts} +0 -1
  65. package/dist/{workflow-timer-store.js → stores/workflow-timer-store.js} +0 -1
  66. package/package.json +11 -11
  67. package/dist/__tests__/action-hooks.test.d.ts +0 -8
  68. package/dist/__tests__/action-hooks.test.d.ts.map +0 -1
  69. package/dist/__tests__/action-hooks.test.js +0 -95
  70. package/dist/__tests__/action-hooks.test.js.map +0 -1
  71. package/dist/__tests__/actor-methods.test.d.ts +0 -9
  72. package/dist/__tests__/actor-methods.test.d.ts.map +0 -1
  73. package/dist/__tests__/actor-methods.test.js +0 -210
  74. package/dist/__tests__/actor-methods.test.js.map +0 -1
  75. package/dist/__tests__/actor-schema-bound.test.d.ts +0 -6
  76. package/dist/__tests__/actor-schema-bound.test.d.ts.map +0 -1
  77. package/dist/__tests__/actor-schema-bound.test.js +0 -112
  78. package/dist/__tests__/actor-schema-bound.test.js.map +0 -1
  79. package/dist/__tests__/actor-workflow-hooks.test.d.ts +0 -8
  80. package/dist/__tests__/actor-workflow-hooks.test.d.ts.map +0 -1
  81. package/dist/__tests__/actor-workflow-hooks.test.js +0 -106
  82. package/dist/__tests__/actor-workflow-hooks.test.js.map +0 -1
  83. package/dist/__tests__/app-capabilities.test.d.ts +0 -19
  84. package/dist/__tests__/app-capabilities.test.d.ts.map +0 -1
  85. package/dist/__tests__/app-capabilities.test.js +0 -57
  86. package/dist/__tests__/app-capabilities.test.js.map +0 -1
  87. package/dist/__tests__/cli-runner.test.d.ts +0 -6
  88. package/dist/__tests__/cli-runner.test.d.ts.map +0 -1
  89. package/dist/__tests__/cli-runner.test.js +0 -158
  90. package/dist/__tests__/cli-runner.test.js.map +0 -1
  91. package/dist/__tests__/create-app.test.d.ts +0 -18
  92. package/dist/__tests__/create-app.test.d.ts.map +0 -1
  93. package/dist/__tests__/create-app.test.js +0 -189
  94. package/dist/__tests__/create-app.test.js.map +0 -1
  95. package/dist/__tests__/cross-service-bus.test.d.ts +0 -8
  96. package/dist/__tests__/cross-service-bus.test.d.ts.map +0 -1
  97. package/dist/__tests__/cross-service-bus.test.js +0 -139
  98. package/dist/__tests__/cross-service-bus.test.js.map +0 -1
  99. package/dist/__tests__/define-schema.test.d.ts +0 -5
  100. package/dist/__tests__/define-schema.test.d.ts.map +0 -1
  101. package/dist/__tests__/define-schema.test.js +0 -83
  102. package/dist/__tests__/define-schema.test.js.map +0 -1
  103. package/dist/__tests__/dev-logger.test.d.ts +0 -9
  104. package/dist/__tests__/dev-logger.test.d.ts.map +0 -1
  105. package/dist/__tests__/dev-logger.test.js +0 -126
  106. package/dist/__tests__/dev-logger.test.js.map +0 -1
  107. package/dist/__tests__/external-call.test.d.ts +0 -14
  108. package/dist/__tests__/external-call.test.d.ts.map +0 -1
  109. package/dist/__tests__/external-call.test.js +0 -99
  110. package/dist/__tests__/external-call.test.js.map +0 -1
  111. package/dist/__tests__/framework-events.test.d.ts +0 -13
  112. package/dist/__tests__/framework-events.test.d.ts.map +0 -1
  113. package/dist/__tests__/framework-events.test.js +0 -204
  114. package/dist/__tests__/framework-events.test.js.map +0 -1
  115. package/dist/__tests__/inline-handler.test.d.ts +0 -8
  116. package/dist/__tests__/inline-handler.test.d.ts.map +0 -1
  117. package/dist/__tests__/inline-handler.test.js +0 -101
  118. package/dist/__tests__/inline-handler.test.js.map +0 -1
  119. package/dist/__tests__/lifecycle-logging.test.d.ts +0 -12
  120. package/dist/__tests__/lifecycle-logging.test.d.ts.map +0 -1
  121. package/dist/__tests__/lifecycle-logging.test.js +0 -114
  122. package/dist/__tests__/lifecycle-logging.test.js.map +0 -1
  123. package/dist/__tests__/middleware.test.d.ts +0 -7
  124. package/dist/__tests__/middleware.test.d.ts.map +0 -1
  125. package/dist/__tests__/middleware.test.js +0 -109
  126. package/dist/__tests__/middleware.test.js.map +0 -1
  127. package/dist/__tests__/module-needs.test.d.ts +0 -10
  128. package/dist/__tests__/module-needs.test.d.ts.map +0 -1
  129. package/dist/__tests__/module-needs.test.js +0 -77
  130. package/dist/__tests__/module-needs.test.js.map +0 -1
  131. package/dist/__tests__/module-topo-sort.test.d.ts +0 -15
  132. package/dist/__tests__/module-topo-sort.test.d.ts.map +0 -1
  133. package/dist/__tests__/module-topo-sort.test.js +0 -105
  134. package/dist/__tests__/module-topo-sort.test.js.map +0 -1
  135. package/dist/__tests__/multi-tenancy.test.d.ts +0 -10
  136. package/dist/__tests__/multi-tenancy.test.d.ts.map +0 -1
  137. package/dist/__tests__/multi-tenancy.test.js +0 -122
  138. package/dist/__tests__/multi-tenancy.test.js.map +0 -1
  139. package/dist/__tests__/needs-topology.test.d.ts +0 -11
  140. package/dist/__tests__/needs-topology.test.d.ts.map +0 -1
  141. package/dist/__tests__/needs-topology.test.js +0 -82
  142. package/dist/__tests__/needs-topology.test.js.map +0 -1
  143. package/dist/__tests__/plugin-app-narrow.test.d.ts +0 -12
  144. package/dist/__tests__/plugin-app-narrow.test.d.ts.map +0 -1
  145. package/dist/__tests__/plugin-app-narrow.test.js +0 -77
  146. package/dist/__tests__/plugin-app-narrow.test.js.map +0 -1
  147. package/dist/__tests__/plugin-closure.test.d.ts +0 -15
  148. package/dist/__tests__/plugin-closure.test.d.ts.map +0 -1
  149. package/dist/__tests__/plugin-closure.test.js +0 -140
  150. package/dist/__tests__/plugin-closure.test.js.map +0 -1
  151. package/dist/__tests__/plugin-stress.test.d.ts +0 -21
  152. package/dist/__tests__/plugin-stress.test.d.ts.map +0 -1
  153. package/dist/__tests__/plugin-stress.test.js +0 -203
  154. package/dist/__tests__/plugin-stress.test.js.map +0 -1
  155. package/dist/__tests__/plugin.test.d.ts +0 -10
  156. package/dist/__tests__/plugin.test.d.ts.map +0 -1
  157. package/dist/__tests__/plugin.test.js +0 -225
  158. package/dist/__tests__/plugin.test.js.map +0 -1
  159. package/dist/__tests__/primitives.test.d.ts +0 -9
  160. package/dist/__tests__/primitives.test.d.ts.map +0 -1
  161. package/dist/__tests__/primitives.test.js +0 -434
  162. package/dist/__tests__/primitives.test.js.map +0 -1
  163. package/dist/__tests__/production-readiness.test.d.ts +0 -22
  164. package/dist/__tests__/production-readiness.test.d.ts.map +0 -1
  165. package/dist/__tests__/production-readiness.test.js +0 -196
  166. package/dist/__tests__/production-readiness.test.js.map +0 -1
  167. package/dist/__tests__/provider.test.d.ts +0 -6
  168. package/dist/__tests__/provider.test.d.ts.map +0 -1
  169. package/dist/__tests__/provider.test.js +0 -122
  170. package/dist/__tests__/provider.test.js.map +0 -1
  171. package/dist/__tests__/public-marker.test.d.ts +0 -7
  172. package/dist/__tests__/public-marker.test.d.ts.map +0 -1
  173. package/dist/__tests__/public-marker.test.js +0 -58
  174. package/dist/__tests__/public-marker.test.js.map +0 -1
  175. package/dist/__tests__/retry-dlq.test.d.ts +0 -6
  176. package/dist/__tests__/retry-dlq.test.d.ts.map +0 -1
  177. package/dist/__tests__/retry-dlq.test.js +0 -68
  178. package/dist/__tests__/retry-dlq.test.js.map +0 -1
  179. package/dist/__tests__/validate.test.d.ts +0 -5
  180. package/dist/__tests__/validate.test.d.ts.map +0 -1
  181. package/dist/__tests__/validate.test.js +0 -53
  182. package/dist/__tests__/validate.test.js.map +0 -1
  183. package/dist/__tests__/workflow-saga.test.d.ts +0 -7
  184. package/dist/__tests__/workflow-saga.test.d.ts.map +0 -1
  185. package/dist/__tests__/workflow-saga.test.js +0 -265
  186. package/dist/__tests__/workflow-saga.test.js.map +0 -1
  187. package/dist/actor-store.d.ts.map +0 -1
  188. package/dist/actor-store.js.map +0 -1
  189. package/dist/cli-runner.d.ts.map +0 -1
  190. package/dist/cli-runner.js.map +0 -1
  191. package/dist/create-app.d.ts +0 -146
  192. package/dist/create-app.d.ts.map +0 -1
  193. package/dist/create-app.js +0 -703
  194. package/dist/create-app.js.map +0 -1
  195. package/dist/define-action.d.ts.map +0 -1
  196. package/dist/define-action.js.map +0 -1
  197. package/dist/define-actor.d.ts.map +0 -1
  198. package/dist/define-actor.js.map +0 -1
  199. package/dist/define-app.d.ts +0 -104
  200. package/dist/define-app.d.ts.map +0 -1
  201. package/dist/define-app.js +0 -49
  202. package/dist/define-app.js.map +0 -1
  203. package/dist/define-cron.d.ts.map +0 -1
  204. package/dist/define-cron.js.map +0 -1
  205. package/dist/define-error.d.ts.map +0 -1
  206. package/dist/define-error.js.map +0 -1
  207. package/dist/define-external-call.d.ts.map +0 -1
  208. package/dist/define-external-call.js.map +0 -1
  209. package/dist/define-handler.d.ts.map +0 -1
  210. package/dist/define-handler.js.map +0 -1
  211. package/dist/define-inbound-webhook.d.ts.map +0 -1
  212. package/dist/define-inbound-webhook.js.map +0 -1
  213. package/dist/define-inbox.d.ts.map +0 -1
  214. package/dist/define-inbox.js.map +0 -1
  215. package/dist/define-initializer.d.ts +0 -54
  216. package/dist/define-initializer.d.ts.map +0 -1
  217. package/dist/define-initializer.js +0 -38
  218. package/dist/define-initializer.js.map +0 -1
  219. package/dist/define-middleware.d.ts +0 -8
  220. package/dist/define-middleware.d.ts.map +0 -1
  221. package/dist/define-middleware.js +0 -8
  222. package/dist/define-middleware.js.map +0 -1
  223. package/dist/define-model.d.ts +0 -10
  224. package/dist/define-model.d.ts.map +0 -1
  225. package/dist/define-model.js +0 -13
  226. package/dist/define-model.js.map +0 -1
  227. package/dist/define-module.d.ts +0 -160
  228. package/dist/define-module.d.ts.map +0 -1
  229. package/dist/define-module.js +0 -63
  230. package/dist/define-module.js.map +0 -1
  231. package/dist/define-outbox.d.ts.map +0 -1
  232. package/dist/define-outbox.js.map +0 -1
  233. package/dist/define-plugin.d.ts +0 -195
  234. package/dist/define-plugin.d.ts.map +0 -1
  235. package/dist/define-plugin.js +0 -220
  236. package/dist/define-plugin.js.map +0 -1
  237. package/dist/define-projection.d.ts.map +0 -1
  238. package/dist/define-projection.js.map +0 -1
  239. package/dist/define-provider.d.ts +0 -49
  240. package/dist/define-provider.d.ts.map +0 -1
  241. package/dist/define-provider.js +0 -45
  242. package/dist/define-provider.js.map +0 -1
  243. package/dist/define-query.d.ts.map +0 -1
  244. package/dist/define-query.js.map +0 -1
  245. package/dist/define-resolver.d.ts +0 -111
  246. package/dist/define-resolver.d.ts.map +0 -1
  247. package/dist/define-resolver.js +0 -146
  248. package/dist/define-resolver.js.map +0 -1
  249. package/dist/define-schema.d.ts.map +0 -1
  250. package/dist/define-schema.js.map +0 -1
  251. package/dist/define-upcaster.d.ts.map +0 -1
  252. package/dist/define-upcaster.js.map +0 -1
  253. package/dist/define-workflow.d.ts.map +0 -1
  254. package/dist/define-workflow.js.map +0 -1
  255. package/dist/dev-logger.d.ts.map +0 -1
  256. package/dist/dev-logger.js.map +0 -1
  257. package/dist/event-message.d.ts.map +0 -1
  258. package/dist/event-message.js.map +0 -1
  259. package/dist/foundation.d.ts.map +0 -1
  260. package/dist/foundation.js.map +0 -1
  261. package/dist/framework-event-bus.d.ts +0 -13
  262. package/dist/framework-event-bus.d.ts.map +0 -1
  263. package/dist/framework-event-bus.js +0 -13
  264. package/dist/framework-event-bus.js.map +0 -1
  265. package/dist/framework-events.d.ts.map +0 -1
  266. package/dist/framework-events.js.map +0 -1
  267. package/dist/idempotency-store.d.ts.map +0 -1
  268. package/dist/idempotency-store.js.map +0 -1
  269. package/dist/index.d.ts.map +0 -1
  270. package/dist/index.js.map +0 -1
  271. package/dist/module-surface.d.ts +0 -47
  272. package/dist/module-surface.d.ts.map +0 -1
  273. package/dist/module-surface.js +0 -65
  274. package/dist/module-surface.js.map +0 -1
  275. package/dist/projection-store.d.ts.map +0 -1
  276. package/dist/projection-store.js.map +0 -1
  277. package/dist/public-marker.d.ts.map +0 -1
  278. package/dist/public-marker.js.map +0 -1
  279. package/dist/response.d.ts.map +0 -1
  280. package/dist/response.js.map +0 -1
  281. package/dist/runtime.d.ts +0 -621
  282. package/dist/runtime.d.ts.map +0 -1
  283. package/dist/runtime.js.map +0 -1
  284. package/dist/validate.d.ts.map +0 -1
  285. package/dist/validate.js.map +0 -1
  286. package/dist/when.d.ts +0 -101
  287. package/dist/when.d.ts.map +0 -1
  288. package/dist/when.js +0 -57
  289. package/dist/when.js.map +0 -1
  290. package/dist/workflow-timer-store.d.ts.map +0 -1
  291. package/dist/workflow-timer-store.js.map +0 -1
@@ -1,203 +0,0 @@
1
- /**
2
- * Plugin + module lifecycle stress test.
3
- *
4
- * Covers the failure modes that aren't exercised by `plugin.test.ts` /
5
- * `plugin-closure.test.ts` / `lifecycle-logging.test.ts`:
6
- *
7
- * 1. Cross-plugin DI — plugin B reads plugin A's binding in its boot.
8
- * 2. Slow boot timing — PluginBooted carries a real `durationMs`.
9
- * 3. Boot failure recovery — A boots, B throws, stop() still cleans A.
10
- * 4. Shutdown isolation — first plugin's shutdown throws but second still runs;
11
- * the error surfaces from app.stop().
12
- * 5. Ordering at scale — 10 plugins boot in registration order, shutdown reverse.
13
- * 6. Module + plugin mixed — PluginRegistered fires with `kind:"module"` for
14
- * modules first (topo order) then `kind:"plugin"` for plugins.
15
- *
16
- * Style follows `lifecycle-logging.test.ts` — real `createApp`, real
17
- * `app.start()/stop()`, observe via the runtime's framework event bus
18
- * (`runtime.frameworkEvents.onFire(...)`) and per-event subscriptions.
19
- */
20
- import { describe, it, expect } from "vitest";
21
- import { createApp, defineModule, definePlugin } from "../foundation.js";
22
- import { PluginRegistered, PluginBooted } from "../framework-events.js";
23
- import { createContainer } from "@nwire/container";
24
- describe("plugin + module lifecycle stress", () => {
25
- it("cross-plugin DI: plugin B's boot resolves a binding plugin A provided", async () => {
26
- const pluginA = definePlugin("provider", ({ bind }) => {
27
- bind("config-service", () => ({ name: "from-A" }));
28
- });
29
- const seen = [];
30
- const pluginB = definePlugin("consumer", {
31
- boot: (container) => {
32
- seen.push(container.resolve("config-service"));
33
- },
34
- });
35
- const app = createApp({
36
- container: createContainer(),
37
- modules: [],
38
- plugins: [pluginA, pluginB],
39
- devLogs: false,
40
- });
41
- await app.start();
42
- await app.stop();
43
- expect(seen).toHaveLength(1);
44
- expect(seen[0]).toEqual({ name: "from-A" });
45
- });
46
- it("slow boot timing: PluginBooted carries a durationMs >= the sleep", async () => {
47
- const SLEEP_MS = 150;
48
- const TOLERANCE_MS = 120;
49
- const slow = definePlugin("slow-boot", {
50
- boot: async () => {
51
- await new Promise((resolve) => setTimeout(resolve, SLEEP_MS));
52
- },
53
- });
54
- const app = createApp({
55
- container: createContainer(),
56
- modules: [],
57
- plugins: [slow],
58
- devLogs: false,
59
- });
60
- const observed = [];
61
- app.runtime.frameworkEvents.on(PluginBooted, (payload) => {
62
- observed.push({ name: payload.pluginName, durationMs: payload.durationMs });
63
- });
64
- await app.start();
65
- await app.stop();
66
- const slowRecord = observed.find((r) => r.name === "slow-boot");
67
- expect(slowRecord).toBeDefined();
68
- expect(slowRecord.durationMs).toBeGreaterThanOrEqual(TOLERANCE_MS);
69
- });
70
- it("boot failure recovery: B throws, A booted, stop() still cleans up A", async () => {
71
- const bootErr = new Error("plugin B boot exploded");
72
- const pluginA = definePlugin("a", {
73
- boot: () => {
74
- /* succeeds */
75
- },
76
- });
77
- const pluginB = definePlugin("b", {
78
- boot: () => {
79
- throw bootErr;
80
- },
81
- });
82
- const pluginC = definePlugin("c", {
83
- boot: () => {
84
- /* should never run — B's failure aborts boot */
85
- },
86
- });
87
- const app = createApp({
88
- container: createContainer(),
89
- modules: [],
90
- plugins: [pluginA, pluginB, pluginC],
91
- devLogs: false,
92
- });
93
- const bootedNames = [];
94
- app.runtime.frameworkEvents.on(PluginBooted, (payload) => {
95
- bootedNames.push(payload.pluginName);
96
- });
97
- const shutdownNames = [];
98
- // Use the catch-all observer the dev logger / Studio use, so we see
99
- // every firing regardless of subscriber count.
100
- app.runtime.frameworkEvents.onFire((rec) => {
101
- if (rec.eventName === "nwire.plugin.shutdown") {
102
- const p = rec.payload;
103
- shutdownNames.push(p.pluginName);
104
- }
105
- });
106
- await expect(app.start()).rejects.toBe(bootErr);
107
- // A booted before B threw. C should NOT have booted.
108
- expect(bootedNames).toContain("a");
109
- expect(bootedNames).not.toContain("c");
110
- // Now tear the app down — shutdown should still emit PluginShutdown
111
- // events in reverse declaration order so observers see a clean close.
112
- await app.stop();
113
- // A must appear in the shutdown sweep regardless of B's boot failure.
114
- expect(shutdownNames).toContain("a");
115
- // Reverse order: C is iterated first, then B, then A. (Their
116
- // shutdown callbacks are no-ops because none was registered, but
117
- // the framework still fires the lifecycle events.)
118
- const aIdx = shutdownNames.indexOf("a");
119
- const cIdx = shutdownNames.indexOf("c");
120
- if (cIdx >= 0) {
121
- // When C appears (framework also fires shutdown events for plugins
122
- // that never booted), it must come BEFORE A.
123
- expect(cIdx).toBeLessThan(aIdx);
124
- }
125
- });
126
- it("shutdown isolation: first plugin's shutdown throws, second still runs, error surfaces from stop()", async () => {
127
- const shutErr = new Error("plugin A shutdown failed");
128
- const cleanupRan = [];
129
- const pluginA = definePlugin("a", {
130
- shutdown: () => {
131
- cleanupRan.push("a-attempted");
132
- throw shutErr;
133
- },
134
- });
135
- const pluginB = definePlugin("b", {
136
- shutdown: () => {
137
- cleanupRan.push("b-ran");
138
- },
139
- });
140
- const app = createApp({
141
- container: createContainer(),
142
- modules: [],
143
- plugins: [pluginA, pluginB],
144
- devLogs: false,
145
- });
146
- await app.start();
147
- // Shutdown order is reverse: B first, then A. B should run cleanly;
148
- // then A throws. The framework must surface A's error but only AFTER
149
- // every other shutdown step has run.
150
- await expect(app.stop()).rejects.toBe(shutErr);
151
- expect(cleanupRan).toEqual(["b-ran", "a-attempted"]);
152
- });
153
- it("ordering at scale: 10 plugins boot in registration order, shutdown reverse", async () => {
154
- const boots = [];
155
- const shutdowns = [];
156
- const plugins = Array.from({ length: 10 }, (_, i) => {
157
- const name = `p${i}`;
158
- return definePlugin(name, {
159
- boot: () => {
160
- boots.push(name);
161
- },
162
- shutdown: () => {
163
- shutdowns.push(name);
164
- },
165
- });
166
- });
167
- const app = createApp({
168
- container: createContainer(),
169
- modules: [],
170
- plugins,
171
- devLogs: false,
172
- });
173
- await app.start();
174
- await app.stop();
175
- expect(boots).toEqual(["p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9"]);
176
- expect(shutdowns).toEqual(["p9", "p8", "p7", "p6", "p5", "p4", "p3", "p2", "p1", "p0"]);
177
- });
178
- it("module + plugin mixed: PluginRegistered fires for modules first (topo) then plugins, with correct kind", async () => {
179
- const moduleA = defineModule("mod-a", {});
180
- const moduleB = defineModule("mod-b", {});
181
- const pluginX = definePlugin("plug-x", {});
182
- const pluginY = definePlugin("plug-y", {});
183
- const app = createApp({
184
- container: createContainer(),
185
- modules: [moduleA, moduleB],
186
- plugins: [pluginX, pluginY],
187
- devLogs: false,
188
- });
189
- const registrations = [];
190
- app.runtime.frameworkEvents.on(PluginRegistered, (payload) => {
191
- registrations.push({ pluginName: payload.pluginName, kind: payload.kind });
192
- });
193
- await app.start();
194
- await app.stop();
195
- expect(registrations).toEqual([
196
- { pluginName: "mod-a", kind: "module" },
197
- { pluginName: "mod-b", kind: "module" },
198
- { pluginName: "plug-x", kind: "plugin" },
199
- { pluginName: "plug-y", kind: "plugin" },
200
- ]);
201
- });
202
- });
203
- //# sourceMappingURL=plugin-stress.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-stress.test.js","sourceRoot":"","sources":["../../src/__tests__/plugin-stress.test.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- /**
2
- * `definePlugin` — the only extension primitive.
3
- *
4
- * Plugins compose alongside modules. They bind values on the container,
5
- * subscribe to framework events, contribute middleware + actor hooks, and
6
- * own boot/shutdown lifecycle. Both authoring forms (object + closure)
7
- * route through the same registration loop.
8
- */
9
- export {};
10
- //# sourceMappingURL=plugin.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/plugin.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -1,225 +0,0 @@
1
- /**
2
- * `definePlugin` — the only extension primitive.
3
- *
4
- * Plugins compose alongside modules. They bind values on the container,
5
- * subscribe to framework events, contribute middleware + actor hooks, and
6
- * own boot/shutdown lifecycle. Both authoring forms (object + closure)
7
- * route through the same registration loop.
8
- */
9
- import { describe, it, expect } from "vitest";
10
- import { z } from "zod";
11
- import { defineEvent } from "@nwire/messages";
12
- import { definePlugin, defineAction, defineActor, defineModule, createApp, eventFactory, } from "../foundation.js";
13
- describe("definePlugin", () => {
14
- it("object-form register/boot/shutdown lifecycle fires in correct order", async () => {
15
- const order = [];
16
- const plugin = definePlugin("audit", {
17
- register: (container) => {
18
- order.push("plugin.register");
19
- container.register("auditLog", { tag: "audit" });
20
- },
21
- boot: async () => {
22
- order.push("plugin.boot");
23
- },
24
- shutdown: async () => {
25
- order.push("plugin.shutdown");
26
- },
27
- });
28
- const app = createApp({ modules: [], plugins: [plugin] });
29
- await app.start();
30
- await app.stop();
31
- expect(order).toEqual(["plugin.register", "plugin.boot", "plugin.shutdown"]);
32
- });
33
- it("closure-form: bind / boot / shutdown / resolve compose end-to-end", async () => {
34
- const counterPlugin = definePlugin("counter", ({ bind }) => {
35
- bind("counter", () => {
36
- const counter = {
37
- value: 0,
38
- incr() {
39
- counter.value += 1;
40
- },
41
- };
42
- return counter;
43
- });
44
- });
45
- let observed = -1;
46
- const bump = defineAction({
47
- name: "bump",
48
- schema: z.object({}),
49
- handler: async (_input, ctx) => {
50
- const counter = ctx.resolve("counter");
51
- counter.incr();
52
- observed = counter.value;
53
- return undefined;
54
- },
55
- });
56
- const app = createApp({
57
- modules: [defineModule("m", { actions: [bump] })],
58
- plugins: [counterPlugin],
59
- });
60
- await app.start();
61
- await app.runtime.dispatch(bump, {});
62
- await app.runtime.dispatch(bump, {});
63
- expect(observed).toBe(2);
64
- await app.stop();
65
- });
66
- it("middleware composes around dispatch", async () => {
67
- const trace = [];
68
- const action = defineAction({
69
- name: "ping",
70
- schema: z.object({}),
71
- handler: async () => {
72
- trace.push("handler");
73
- return undefined;
74
- },
75
- });
76
- const plugin = definePlugin("trace", {
77
- middleware: [
78
- async (next) => {
79
- trace.push("mw:before");
80
- const r = await next();
81
- trace.push("mw:after");
82
- return r;
83
- },
84
- ],
85
- });
86
- const app = createApp({
87
- modules: [defineModule("m", { actions: [action] })],
88
- plugins: [plugin],
89
- });
90
- await app.start();
91
- await app.runtime.dispatch(action, {});
92
- await app.stop();
93
- expect(trace).toEqual(["mw:before", "handler", "mw:after"]);
94
- });
95
- it("actorHooks.afterTransition fires AFTER actor state change persists", async () => {
96
- const TickSchema = z.object({ counter: z.number() });
97
- const TickedEventDef = defineEvent({
98
- name: "tick.ticked",
99
- schema: z.object({ tickId: z.string() }),
100
- });
101
- const Ticked = eventFactory(TickedEventDef);
102
- const Tick = defineActor("tick", {
103
- schema: TickSchema,
104
- key: "tickId",
105
- initial: "fresh",
106
- states: {
107
- fresh: {
108
- on: {
109
- [TickedEventDef.name]: {
110
- target: "done",
111
- assign: (state) => ({ counter: (state.counter ?? 0) + 1 }),
112
- },
113
- },
114
- },
115
- done: { final: true },
116
- },
117
- });
118
- const tickIt = defineAction({
119
- name: "tick.it",
120
- schema: z.object({ tickId: z.string() }),
121
- handler: async (input) => Ticked({ tickId: input.tickId }),
122
- });
123
- const observed = [];
124
- const observer = definePlugin("observer", {
125
- actorHooks: {
126
- afterTransition: (_actor, _key, fromState, toState) => {
127
- observed.push({ from: fromState, to: toState });
128
- },
129
- },
130
- });
131
- const app = createApp({
132
- modules: [
133
- defineModule("m", {
134
- actions: [tickIt],
135
- actors: [Tick],
136
- events: [TickedEventDef],
137
- }),
138
- ],
139
- plugins: [observer],
140
- });
141
- await app.start();
142
- await app.runtime.dispatch(tickIt, { tickId: "t1" });
143
- await app.stop();
144
- expect(observed).toEqual([{ from: "fresh", to: "done" }]);
145
- });
146
- it("plugins boot in declaration order; shutdown in REVERSE", async () => {
147
- const order = [];
148
- const a = definePlugin("a", {
149
- boot: async () => {
150
- order.push("a.boot");
151
- },
152
- shutdown: async () => {
153
- order.push("a.shutdown");
154
- },
155
- });
156
- const b = definePlugin("b", {
157
- boot: async () => {
158
- order.push("b.boot");
159
- },
160
- shutdown: async () => {
161
- order.push("b.shutdown");
162
- },
163
- });
164
- const app = createApp({ modules: [], plugins: [a, b] });
165
- await app.start();
166
- await app.stop();
167
- expect(order).toEqual(["a.boot", "b.boot", "b.shutdown", "a.shutdown"]);
168
- });
169
- it("shutdown errors propagate (so wires can detect stuck shutdowns)", async () => {
170
- const flaky = definePlugin("flaky", {
171
- boot: async () => undefined,
172
- shutdown: async () => {
173
- throw new Error("shutdown failed");
174
- },
175
- });
176
- const app = createApp({ modules: [], plugins: [flaky] });
177
- await app.start();
178
- await expect(app.stop()).rejects.toThrow(/shutdown failed/);
179
- });
180
- it("a bad plugin's shutdown does NOT block subsequent plugins", async () => {
181
- const order = [];
182
- const bad = definePlugin("bad", {
183
- shutdown: async () => {
184
- order.push("bad.attempted");
185
- throw new Error("boom");
186
- },
187
- });
188
- const good = definePlugin("good", {
189
- shutdown: async () => {
190
- order.push("good.shutdown");
191
- },
192
- });
193
- // Declaration order: bad → good. Reverse shutdown: good → bad. Good
194
- // must run before bad's failure is surfaced.
195
- const app = createApp({ modules: [], plugins: [bad, good] });
196
- await app.start();
197
- await expect(app.stop()).rejects.toThrow(/boom/);
198
- expect(order).toEqual(["good.shutdown", "bad.attempted"]);
199
- });
200
- it("plugin can register values on the container at register time", async () => {
201
- const auditPlugin = definePlugin("audit", {
202
- register: (container) => {
203
- container.register("auditLogger", { tag: "audit" });
204
- },
205
- });
206
- let seen = null;
207
- const action = defineAction({
208
- name: "audited",
209
- schema: z.object({}),
210
- handler: async (_input, ctx) => {
211
- seen = ctx.resolve("auditLogger");
212
- return undefined;
213
- },
214
- });
215
- const app = createApp({
216
- modules: [defineModule("m", { actions: [action] })],
217
- plugins: [auditPlugin],
218
- });
219
- await app.start();
220
- await app.runtime.dispatch(action, {});
221
- expect(seen).toEqual({ tag: "audit" });
222
- await app.stop();
223
- });
224
- });
225
- //# sourceMappingURL=plugin.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.test.js","sourceRoot":"","sources":["../../src/__tests__/plugin.test.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- /**
2
- * Forge contract tests — verify the public surface and the runtime end-to-end.
3
- *
4
- * Each test exercises one design rule. If a test fails, it likely means a
5
- * design rule changed and either the docs or the runtime need to be brought
6
- * back in sync.
7
- */
8
- export {};
9
- //# sourceMappingURL=primitives.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"primitives.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/primitives.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}