@nwire/forge 0.13.1 → 0.13.2

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.
@@ -23,7 +23,9 @@
23
23
  */
24
24
  export declare class InvariantError extends Error {
25
25
  readonly failures: readonly string[];
26
- constructor(failures: readonly string[]);
26
+ /** Accepts a single failure message or an array — `new InvariantError("…")`
27
+ * and `new InvariantError(["…", "…"])` both work. */
28
+ constructor(failures: string | readonly string[]);
27
29
  }
28
30
  /** A predicate: returns `true` if the invariant holds, or a failure message string. */
29
31
  export type Invariant<TInput, TState = unknown> = (input: TInput, state: TState) => true | string;
@@ -23,10 +23,13 @@
23
23
  */
24
24
  export class InvariantError extends Error {
25
25
  failures;
26
+ /** Accepts a single failure message or an array — `new InvariantError("…")`
27
+ * and `new InvariantError(["…", "…"])` both work. */
26
28
  constructor(failures) {
27
- super(`Invariant failed: ${failures.join("; ")}`);
29
+ const list = typeof failures === "string" ? [failures] : failures;
30
+ super(`Invariant failed: ${list.join("; ")}`);
28
31
  this.name = "InvariantError";
29
- this.failures = failures;
32
+ this.failures = list;
30
33
  }
31
34
  }
32
35
  export function validate(input, predicates, state) {
@@ -33,4 +33,4 @@ export interface ActorsPluginOptions {
33
33
  /** Override the actor store. Defaults to `InMemoryActorStore`. */
34
34
  readonly actorStore?: ActorStore;
35
35
  }
36
- export declare function actorsPlugin(actorTypes: readonly ActorDefinition[], opts?: ActorsPluginOptions): PluginDefinition;
36
+ export declare function actorsPlugin(actorTypes?: readonly ActorDefinition[], opts?: ActorsPluginOptions): PluginDefinition;
@@ -30,7 +30,7 @@ import { ActorChainRunner } from "./actors-chain.js";
30
30
  import { FORGE_PUBLISH_BINDING } from "./actions-plugin.js";
31
31
  export const FORGE_ACTOR_CHAIN_BINDING = "forge.actorChain";
32
32
  export const FORGE_ACTOR_STORE_BINDING = "forge.actorStore";
33
- export function actorsPlugin(actorTypes, opts = {}) {
33
+ export function actorsPlugin(actorTypes = [], opts = {}) {
34
34
  return {
35
35
  name: "forge.actors",
36
36
  register({ bind }) {
@@ -40,7 +40,16 @@ export function actorsPlugin(actorTypes, opts = {}) {
40
40
  setup({ runtime, container }) {
41
41
  const store = container.resolve(FORGE_ACTOR_STORE_BINDING);
42
42
  const chain = new ActorChainRunner(runtime, store);
43
- for (const actor of actorTypes)
43
+ // The app registers every actor via `runtime.register`; scan the by-kind
44
+ // registry and merge any explicitly-passed actors (explicit wins on
45
+ // name). `actorsPlugin()` picks up everything discovered; `actorsPlugin([X])`
46
+ // still adds X.
47
+ const byName = new Map();
48
+ for (const a of runtime.byKind("actor"))
49
+ byName.set(a.name, a);
50
+ for (const a of actorTypes)
51
+ byName.set(a.name, a);
52
+ for (const actor of byName.values())
44
53
  chain.register(actor);
45
54
  container.register(FORGE_ACTOR_CHAIN_BINDING, chain);
46
55
  runtime.hooks.LocalDelivery.use(async (payload, next) => {
@@ -33,4 +33,4 @@ export interface ProjectionsPluginOptions {
33
33
  /** Override the projection store. Defaults to `InMemoryProjectionStore`. */
34
34
  readonly projectionStore?: ProjectionStore;
35
35
  }
36
- export declare function projectionsPlugin(projections: readonly ProjectionDefinition<any>[], opts?: ProjectionsPluginOptions): PluginDefinition;
36
+ export declare function projectionsPlugin(projections?: readonly ProjectionDefinition<any>[], opts?: ProjectionsPluginOptions): PluginDefinition;
@@ -31,7 +31,7 @@ export const FORGE_PROJECTION_CHAIN_BINDING = "forge.projectionChain";
31
31
  export const FORGE_PROJECTION_STORE_BINDING = "forge.projectionStore";
32
32
  export function projectionsPlugin(
33
33
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
- projections, opts = {}) {
34
+ projections = [], opts = {}) {
35
35
  return {
36
36
  name: "forge.projections",
37
37
  register({ bind }) {
@@ -41,9 +41,16 @@ projections, opts = {}) {
41
41
  setup({ runtime, container }) {
42
42
  const store = container.resolve(FORGE_PROJECTION_STORE_BINDING);
43
43
  const chain = new ProjectionChainRunner(runtime, store);
44
- for (const projection of projections) {
45
- chain.register(projection);
44
+ // Scan the by-kind registry; merge explicitly-passed projections (explicit
45
+ // wins on name). `projectionsPlugin()` picks up everything discovered.
46
+ const byName = new Map();
47
+ for (const p of runtime.byKind("projection")) {
48
+ byName.set(p.name, p);
46
49
  }
50
+ for (const p of projections)
51
+ byName.set(p.name, p);
52
+ for (const projection of byName.values())
53
+ chain.register(projection);
47
54
  container.register(FORGE_PROJECTION_CHAIN_BINDING, chain);
48
55
  runtime.hooks.LocalDelivery.use(async (payload, next) => {
49
56
  await chain.apply({ eventName: payload.eventName, payload: payload.payload }, payload.envelope);
@@ -24,4 +24,13 @@
24
24
  */
25
25
  import type { PluginDefinition } from "@nwire/app";
26
26
  export declare const FORGE_QUERY_RUNNER_BINDING: "forge.queryRunner";
27
+ declare module "@nwire/handler" {
28
+ interface CtxCapabilities {
29
+ /** Read through a projection-backed (or handler-form) query by its
30
+ * definition: `await ctx.query(getUser, input)`. */
31
+ query<TResult = unknown>(query: {
32
+ readonly name: string;
33
+ }, input?: unknown): Promise<TResult>;
34
+ }
35
+ }
27
36
  export declare function queriesPlugin(): PluginDefinition;
@@ -44,4 +44,4 @@ export interface WorkflowsPluginOptions {
44
44
  */
45
45
  readonly bus?: EventBus;
46
46
  }
47
- export declare function workflowsPlugin(workflows: readonly WorkflowDefinition[], opts?: WorkflowsPluginOptions): PluginDefinition;
47
+ export declare function workflowsPlugin(workflows?: readonly WorkflowDefinition[], opts?: WorkflowsPluginOptions): PluginDefinition;
@@ -34,7 +34,7 @@ import { EVENT_PUBLISHING_PRIORITIES } from "../framework-events.js";
34
34
  import { WorkflowChainRunner } from "./workflows-chain.js";
35
35
  export const FORGE_WORKFLOW_CHAIN_BINDING = "forge.workflowChain";
36
36
  export const FORGE_WORKFLOW_TIMER_STORE_BINDING = "forge.workflowTimerStore";
37
- export function workflowsPlugin(workflows, opts = {}) {
37
+ export function workflowsPlugin(workflows = [], opts = {}) {
38
38
  return {
39
39
  name: "forge.workflows",
40
40
  register({ bind }) {
@@ -61,7 +61,15 @@ export function workflowsPlugin(workflows, opts = {}) {
61
61
  };
62
62
  return effects;
63
63
  });
64
- for (const workflow of workflows)
64
+ // Scan the by-kind registry; merge explicitly-passed workflows (explicit
65
+ // wins on name). `workflowsPlugin()` picks up everything discovered.
66
+ const byName = new Map();
67
+ for (const w of runtime.byKind("workflow")) {
68
+ byName.set(w.name, w);
69
+ }
70
+ for (const w of workflows)
71
+ byName.set(w.name, w);
72
+ for (const workflow of byName.values())
65
73
  chain.register(workflow);
66
74
  container.register(FORGE_WORKFLOW_CHAIN_BINDING, chain);
67
75
  runtime.hooks.LocalDelivery.use(async (payload, next) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nwire/forge",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "description": "Nwire — the CQRS battery. Actors, projections, workflows, queries, and the action pipeline, plus outbox/inbox/cron, invariants, and DLQ wiring — installed via forgePlugins / withForge. Opt-in; an app boots without it. The runtime is the bus.",
5
5
  "keywords": [
6
6
  "actions",
@@ -34,16 +34,16 @@
34
34
  "emittery": "1.0.1",
35
35
  "koa": "^2.16.4",
36
36
  "zod": "^4.0.0",
37
- "@nwire/envelope": "0.13.1",
38
- "@nwire/dead-letter": "0.13.1",
39
- "@nwire/container": "0.13.1",
40
- "@nwire/app": "0.13.1",
41
- "@nwire/logger": "0.13.1",
42
- "@nwire/wires": "0.13.1",
43
- "@nwire/bus": "0.13.1",
44
- "@nwire/hooks": "0.13.1",
45
- "@nwire/messages": "0.13.1",
46
- "@nwire/handler": "0.13.1"
37
+ "@nwire/app": "0.13.2",
38
+ "@nwire/envelope": "0.13.2",
39
+ "@nwire/bus": "0.13.2",
40
+ "@nwire/handler": "0.13.2",
41
+ "@nwire/dead-letter": "0.13.2",
42
+ "@nwire/logger": "0.13.2",
43
+ "@nwire/messages": "0.13.2",
44
+ "@nwire/wires": "0.13.2",
45
+ "@nwire/container": "0.13.2",
46
+ "@nwire/hooks": "0.13.2"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/koa": "^2.15.0",