hexok 1.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -22
- package/dist/adapter.d.ts +18 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +21 -0
- package/dist/adapter.js.map +1 -0
- package/dist/catalog.d.ts +88 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +79 -0
- package/dist/catalog.js.map +1 -0
- package/dist/{core/coded-error.d.ts → coded-error.d.ts} +9 -4
- package/dist/coded-error.d.ts.map +1 -0
- package/dist/{core/coded-error.js → coded-error.js} +9 -4
- package/dist/coded-error.js.map +1 -0
- package/dist/cow-draft.d.ts.map +1 -0
- package/dist/cow-draft.js.map +1 -0
- package/dist/entity.d.ts +63 -0
- package/dist/entity.d.ts.map +1 -0
- package/dist/{domain/entity.js → entity.js} +52 -80
- package/dist/entity.js.map +1 -0
- package/dist/error-map.d.ts +22 -0
- package/dist/error-map.d.ts.map +1 -0
- package/dist/error-map.js +2 -0
- package/dist/error-map.js.map +1 -0
- package/dist/errors.d.ts +85 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +85 -0
- package/dist/errors.js.map +1 -0
- package/dist/event-handler.d.ts +31 -0
- package/dist/event-handler.d.ts.map +1 -0
- package/dist/event-handler.js +28 -0
- package/dist/event-handler.js.map +1 -0
- package/dist/event.d.ts +37 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +44 -0
- package/dist/event.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/mapper.d.ts +100 -0
- package/dist/mapper.d.ts.map +1 -0
- package/dist/mapper.js +167 -0
- package/dist/mapper.js.map +1 -0
- package/dist/port.d.ts +20 -0
- package/dist/port.d.ts.map +1 -0
- package/dist/port.js +25 -0
- package/dist/port.js.map +1 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js.map +1 -0
- package/dist/schema.d.ts +37 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +50 -0
- package/dist/schema.js.map +1 -0
- package/dist/{core/standard-schema.d.ts → standard-schema.d.ts} +1 -1
- package/dist/standard-schema.d.ts.map +1 -0
- package/dist/standard-schema.js.map +1 -0
- package/dist/use-case.d.ts +183 -0
- package/dist/use-case.d.ts.map +1 -0
- package/dist/use-case.js +221 -0
- package/dist/use-case.js.map +1 -0
- package/dist/{core/schema.d.ts → validate.d.ts} +1 -1
- package/dist/validate.d.ts.map +1 -0
- package/dist/{core/schema.js → validate.js} +1 -1
- package/dist/validate.js.map +1 -0
- package/package.json +7 -26
- package/skills/hexok/SKILL.md +127 -0
- package/skills/hexok/references/adapter.md +66 -0
- package/skills/hexok/references/entity.md +74 -0
- package/skills/hexok/references/error.md +140 -0
- package/skills/hexok/references/event-catalog.md +57 -0
- package/skills/hexok/references/event-handler.md +56 -0
- package/skills/hexok/references/event.md +53 -0
- package/skills/hexok/references/mapper.md +77 -0
- package/skills/hexok/references/port.md +58 -0
- package/skills/hexok/references/schema.md +47 -0
- package/skills/hexok/references/use-case.md +164 -0
- package/dist/app/callable-use-case.d.ts +0 -34
- package/dist/app/callable-use-case.d.ts.map +0 -1
- package/dist/app/callable-use-case.js +0 -41
- package/dist/app/callable-use-case.js.map +0 -1
- package/dist/app/contract.d.ts +0 -46
- package/dist/app/contract.d.ts.map +0 -1
- package/dist/app/contract.js +0 -28
- package/dist/app/contract.js.map +0 -1
- package/dist/app/error-factory.d.ts +0 -9
- package/dist/app/error-factory.d.ts.map +0 -1
- package/dist/app/error-factory.js +0 -30
- package/dist/app/error-factory.js.map +0 -1
- package/dist/app/event-channel.d.ts +0 -133
- package/dist/app/event-channel.d.ts.map +0 -1
- package/dist/app/event-channel.js +0 -49
- package/dist/app/event-channel.js.map +0 -1
- package/dist/app/event-use-case.d.ts +0 -47
- package/dist/app/event-use-case.d.ts.map +0 -1
- package/dist/app/event-use-case.js +0 -54
- package/dist/app/event-use-case.js.map +0 -1
- package/dist/app/execute-ctx.d.ts +0 -92
- package/dist/app/execute-ctx.d.ts.map +0 -1
- package/dist/app/execute-ctx.js +0 -2
- package/dist/app/execute-ctx.js.map +0 -1
- package/dist/app/external-use-case.d.ts +0 -25
- package/dist/app/external-use-case.d.ts.map +0 -1
- package/dist/app/external-use-case.js +0 -25
- package/dist/app/external-use-case.js.map +0 -1
- package/dist/app/index.d.ts +0 -9
- package/dist/app/index.d.ts.map +0 -1
- package/dist/app/index.js +0 -8
- package/dist/app/index.js.map +0 -1
- package/dist/app/internal-use-case.d.ts +0 -26
- package/dist/app/internal-use-case.d.ts.map +0 -1
- package/dist/app/internal-use-case.js +0 -26
- package/dist/app/internal-use-case.js.map +0 -1
- package/dist/app/nest.d.ts +0 -9
- package/dist/app/nest.d.ts.map +0 -1
- package/dist/app/nest.js +0 -28
- package/dist/app/nest.js.map +0 -1
- package/dist/app/types.d.ts +0 -153
- package/dist/app/types.d.ts.map +0 -1
- package/dist/app/types.js +0 -17
- package/dist/app/types.js.map +0 -1
- package/dist/core/coded-error.d.ts.map +0 -1
- package/dist/core/coded-error.js.map +0 -1
- package/dist/core/error-map.d.ts +0 -21
- package/dist/core/error-map.d.ts.map +0 -1
- package/dist/core/error-map.js +0 -5
- package/dist/core/error-map.js.map +0 -1
- package/dist/core/index.d.ts +0 -6
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -5
- package/dist/core/index.js.map +0 -1
- package/dist/core/result.d.ts.map +0 -1
- package/dist/core/result.js.map +0 -1
- package/dist/core/schema.d.ts.map +0 -1
- package/dist/core/schema.js.map +0 -1
- package/dist/core/standard-schema.d.ts.map +0 -1
- package/dist/core/standard-schema.js.map +0 -1
- package/dist/domain/capabilities.d.ts +0 -42
- package/dist/domain/capabilities.d.ts.map +0 -1
- package/dist/domain/capabilities.js +0 -2
- package/dist/domain/capabilities.js.map +0 -1
- package/dist/domain/catalog.d.ts +0 -46
- package/dist/domain/catalog.d.ts.map +0 -1
- package/dist/domain/catalog.js +0 -114
- package/dist/domain/catalog.js.map +0 -1
- package/dist/domain/channel.d.ts +0 -36
- package/dist/domain/channel.d.ts.map +0 -1
- package/dist/domain/channel.js +0 -2
- package/dist/domain/channel.js.map +0 -1
- package/dist/domain/cow-draft.d.ts.map +0 -1
- package/dist/domain/cow-draft.js.map +0 -1
- package/dist/domain/entity.d.ts +0 -120
- package/dist/domain/entity.d.ts.map +0 -1
- package/dist/domain/entity.js.map +0 -1
- package/dist/domain/envelope.d.ts +0 -59
- package/dist/domain/envelope.d.ts.map +0 -1
- package/dist/domain/envelope.js +0 -2
- package/dist/domain/envelope.js.map +0 -1
- package/dist/domain/event.d.ts +0 -44
- package/dist/domain/event.d.ts.map +0 -1
- package/dist/domain/event.js +0 -21
- package/dist/domain/event.js.map +0 -1
- package/dist/domain/index.d.ts +0 -8
- package/dist/domain/index.d.ts.map +0 -1
- package/dist/domain/index.js +0 -5
- package/dist/domain/index.js.map +0 -1
- package/dist/domain/port.d.ts +0 -45
- package/dist/domain/port.d.ts.map +0 -1
- package/dist/domain/port.js +0 -41
- package/dist/domain/port.js.map +0 -1
- package/dist/infra/adapter.d.ts +0 -22
- package/dist/infra/adapter.d.ts.map +0 -1
- package/dist/infra/adapter.js +0 -18
- package/dist/infra/adapter.js.map +0 -1
- package/dist/infra/index.d.ts +0 -3
- package/dist/infra/index.d.ts.map +0 -1
- package/dist/infra/index.js +0 -3
- package/dist/infra/index.js.map +0 -1
- package/dist/infra/mapper.d.ts +0 -48
- package/dist/infra/mapper.d.ts.map +0 -1
- package/dist/infra/mapper.js +0 -77
- package/dist/infra/mapper.js.map +0 -1
- package/dist/runtime/app.d.ts +0 -100
- package/dist/runtime/app.d.ts.map +0 -1
- package/dist/runtime/app.js +0 -292
- package/dist/runtime/app.js.map +0 -1
- package/dist/runtime/channel.d.ts +0 -34
- package/dist/runtime/channel.d.ts.map +0 -1
- package/dist/runtime/channel.js +0 -110
- package/dist/runtime/channel.js.map +0 -1
- package/dist/runtime/client.d.ts +0 -21
- package/dist/runtime/client.d.ts.map +0 -1
- package/dist/runtime/client.js +0 -2
- package/dist/runtime/client.js.map +0 -1
- package/dist/runtime/completeness.d.ts +0 -89
- package/dist/runtime/completeness.d.ts.map +0 -1
- package/dist/runtime/completeness.js +0 -2
- package/dist/runtime/completeness.js.map +0 -1
- package/dist/runtime/envelope.d.ts +0 -7
- package/dist/runtime/envelope.d.ts.map +0 -1
- package/dist/runtime/envelope.js +0 -69
- package/dist/runtime/envelope.js.map +0 -1
- package/dist/runtime/events.d.ts +0 -6
- package/dist/runtime/events.d.ts.map +0 -1
- package/dist/runtime/events.js +0 -48
- package/dist/runtime/events.js.map +0 -1
- package/dist/runtime/http-status.d.ts +0 -3
- package/dist/runtime/http-status.d.ts.map +0 -1
- package/dist/runtime/http-status.js +0 -11
- package/dist/runtime/http-status.js.map +0 -1
- package/dist/runtime/http.d.ts +0 -4
- package/dist/runtime/http.d.ts.map +0 -1
- package/dist/runtime/http.js +0 -58
- package/dist/runtime/http.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -10
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js +0 -6
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/interceptor.d.ts +0 -61
- package/dist/runtime/interceptor.d.ts.map +0 -1
- package/dist/runtime/interceptor.js +0 -7
- package/dist/runtime/interceptor.js.map +0 -1
- package/dist/runtime/invoke.d.ts +0 -34
- package/dist/runtime/invoke.d.ts.map +0 -1
- package/dist/runtime/invoke.js +0 -235
- package/dist/runtime/invoke.js.map +0 -1
- package/dist/runtime/middleware.d.ts +0 -20
- package/dist/runtime/middleware.d.ts.map +0 -1
- package/dist/runtime/middleware.js +0 -2
- package/dist/runtime/middleware.js.map +0 -1
- package/dist/runtime/rpc.d.ts +0 -24
- package/dist/runtime/rpc.d.ts.map +0 -1
- package/dist/runtime/rpc.js +0 -16
- package/dist/runtime/rpc.js.map +0 -1
- package/dist/testing/app-test.d.ts +0 -77
- package/dist/testing/app-test.d.ts.map +0 -1
- package/dist/testing/app-test.js +0 -109
- package/dist/testing/app-test.js.map +0 -1
- package/dist/testing/in-memory-bus.d.ts +0 -19
- package/dist/testing/in-memory-bus.d.ts.map +0 -1
- package/dist/testing/in-memory-bus.js +0 -31
- package/dist/testing/in-memory-bus.js.map +0 -1
- package/dist/testing/in-memory-channel.d.ts +0 -32
- package/dist/testing/in-memory-channel.d.ts.map +0 -1
- package/dist/testing/in-memory-channel.js +0 -65
- package/dist/testing/in-memory-channel.js.map +0 -1
- package/dist/testing/in-memory-queue.d.ts +0 -24
- package/dist/testing/in-memory-queue.d.ts.map +0 -1
- package/dist/testing/in-memory-queue.js +0 -66
- package/dist/testing/in-memory-queue.js.map +0 -1
- package/dist/testing/in-memory-repository.d.ts +0 -44
- package/dist/testing/in-memory-repository.d.ts.map +0 -1
- package/dist/testing/in-memory-repository.js +0 -60
- package/dist/testing/in-memory-repository.js.map +0 -1
- package/dist/testing/index.d.ts +0 -6
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/index.js +0 -6
- package/dist/testing/index.js.map +0 -1
- /package/dist/{domain/cow-draft.d.ts → cow-draft.d.ts} +0 -0
- /package/dist/{domain/cow-draft.js → cow-draft.js} +0 -0
- /package/dist/{core/result.d.ts → result.d.ts} +0 -0
- /package/dist/{core/result.js → result.js} +0 -0
- /package/dist/{core/standard-schema.js → standard-schema.js} +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# UseCase
|
|
2
|
+
|
|
3
|
+
A use case is one thing a caller can do: publish a post, save a draft, subscribe an email address. Name it with `UseCase` and write the story in `execute`. The ports it needs arrive through the constructor.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
class PublishPost extends UseCase('post.publish') {}
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
When every call in a family carries the same extra context, such as a trace id or the caller IP, use `UseCase.context` below. Plain `UseCase(token)` has `execute(input)` and never wraps that method.
|
|
10
|
+
|
|
11
|
+
## Why it exists
|
|
12
|
+
|
|
13
|
+
Publishing a post is a story with a beginning and an end. Load the post, apply the publish rule, save it, and announce that it was published. The use case is that story in one place. Saving and announcing stay behind ports, so the story reads the same when the database or the event transport changes. A refusal throws an error-catalog member. The application catches it at the edge.
|
|
14
|
+
|
|
15
|
+
## How to use it
|
|
16
|
+
|
|
17
|
+
`PublishPost` receives the repository and the event publisher. `execute` is the story. Callers see the input and return types you annotate.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
class PublishPost extends UseCase('post.publish') {
|
|
21
|
+
constructor(
|
|
22
|
+
private readonly posts: PostRepository,
|
|
23
|
+
private readonly events: BlogEventPublisher,
|
|
24
|
+
) {
|
|
25
|
+
super();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async execute(input: { id: string }): Promise<{ id: string }> {
|
|
29
|
+
const post = await this.posts.get(input.id);
|
|
30
|
+
post.publish(new Date());
|
|
31
|
+
await this.posts.save(post);
|
|
32
|
+
await this.events.publish(new PostPublished(post.toProps()));
|
|
33
|
+
return { id: post.props.id };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The application constructs `PublishPost` with concrete adapters and calls `execute` from a gateway. One action is one class and one token. A caller who can save a draft and later publish it gets `SavePost` (`post.save`) and `PublishPost` (`post.publish`).
|
|
39
|
+
|
|
40
|
+
Declare `execute` as a method. A class field, or an assignment after `super()`, is the wrong shape. The class is incomplete until `execute` exists, and the compiler reports the missing method.
|
|
41
|
+
|
|
42
|
+
`execute` receives the input you declare and returns what you declare. Checking that input is the application's job: a guard on a context family, or the first lines of `execute`. Hexok does not validate `execute` and does not read a static key named `input`.
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
`UseCase(token)` returns the class you extend. `token` is a string literal, such as `'post.publish'`.
|
|
47
|
+
|
|
48
|
+
| Member | Role |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| `PublishPost.token` | The name you passed in. |
|
|
51
|
+
| `execute(input)` | Required. Annotate the input and the return type on the subclass. |
|
|
52
|
+
| `constructor` | Receive ports here and call `super()`. |
|
|
53
|
+
|
|
54
|
+
A subclass of plain `UseCase(token)` takes one argument. Adding a context argument there is a type error. Reach for the family factory instead.
|
|
55
|
+
|
|
56
|
+
## UseCase.context
|
|
57
|
+
|
|
58
|
+
`UseCase.context` builds a family of use cases that share one kind of call. Every member receives a context argument. The family can refuse a call in a guard or observe it with hooks. Each member still has its own token, its own ports, and its own `execute`.
|
|
59
|
+
|
|
60
|
+
Use it when the call carries something the story should see, such as a trace id or the actor who published the post. Putting that bag on `execute` as a first argument keeps it out of the post payload. The use case instance stays long-lived. The gateway builds a new context per request.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
type ApiContext = { traceId: string };
|
|
64
|
+
|
|
65
|
+
const ApiUseCase = UseCase.context<ApiContext>().guard((call) => {
|
|
66
|
+
if (call.ctx.traceId.length < 1) throw BlogError.TraceIdMissing();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
class PublishPost extends ApiUseCase('post.publish') {
|
|
70
|
+
constructor(
|
|
71
|
+
private readonly posts: PostRepository,
|
|
72
|
+
private readonly events: BlogEventPublisher,
|
|
73
|
+
) {
|
|
74
|
+
super();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async execute(
|
|
78
|
+
ctx: UseCase.Ctx<typeof ApiUseCase>,
|
|
79
|
+
input: { id: string },
|
|
80
|
+
): Promise<{ id: string }> {
|
|
81
|
+
const post = await this.posts.get(input.id);
|
|
82
|
+
post.publish(new Date());
|
|
83
|
+
await this.posts.save(post);
|
|
84
|
+
await this.events.publish(new PostPublished(post.toProps()));
|
|
85
|
+
return { id: post.props.id };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
await new PublishPost(posts, events).execute({ traceId: 'req-1' }, { id: 'p1' });
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
A member that needs a static contract, such as a permission string or an input schema the application will read, declares that contract as the second type argument. The schema is data the guard can read. Validating the input stays in the guard or in `execute`.
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
const ActorUseCase = UseCase.context<
|
|
96
|
+
{ traceId: string; actorId: string },
|
|
97
|
+
{ permission: string }
|
|
98
|
+
>().guard((call) => {
|
|
99
|
+
if (call.spec.permission.length < 1) throw BlogError.Forbidden();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
class PublishPost extends ActorUseCase('post.publish', {
|
|
103
|
+
permission: 'posts.publish',
|
|
104
|
+
}) {
|
|
105
|
+
async execute(
|
|
106
|
+
ctx: UseCase.Ctx<typeof ActorUseCase>,
|
|
107
|
+
input: { id: string },
|
|
108
|
+
): Promise<{ id: string }> {
|
|
109
|
+
return { id: input.id };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Factory
|
|
115
|
+
|
|
116
|
+
`UseCase.context<Ctx, Spec>(config?)` returns a factory. `Ctx` is required. Omitting it makes the return type the string `'Pass a type argument: UseCase.context<Ctx>()'`. `Spec` defaults to an empty contract, so a member is `Factory(token)` only.
|
|
117
|
+
|
|
118
|
+
`config` accepts no keys yet. Call `UseCase.context<Ctx>()` or `UseCase.context<Ctx>({})`. `guard` and `hooks` are methods on the factory, not fields of that object.
|
|
119
|
+
|
|
120
|
+
`.guard(fn)` and `.hooks(def)` each return the factory again, so the calls can sit in either order and either one can be left off. A further `.guard()` runs after guards already registered. A second `.hooks()` that includes at least one callback throws `hexok: UseCase hooks are already set` when the factory is created. An empty `.hooks({})` adds no callbacks and does not wrap `execute`.
|
|
121
|
+
|
|
122
|
+
When `Spec` has keys, the member is `Factory(token, statics)` and the bag has to satisfy `Spec`. Those entries are copied onto the class as statics. Literals stay narrow. The names `token`, `prototype`, `name`, and `length` stay on the class. Passing one of them is a type error.
|
|
123
|
+
|
|
124
|
+
`execute` is still required. Annotate `ctx` and `input` on the subclass. A member with no input omits the second parameter. Declare `execute` as a method. Assigning it as a class field, or replacing it after `super()`, skips the guard and the hooks.
|
|
125
|
+
|
|
126
|
+
When the family has no guard and no hooks, `execute` stays unwrapped so a missing method is still a class-site error.
|
|
127
|
+
|
|
128
|
+
`UseCase.Ctx<typeof ApiUseCase>` is the context type. Pass the factory from `UseCase.context`. A subclass, and a plain `UseCase(token)` class, resolve to `never`. Annotate member `execute` parameters with it. A guard passed into the factory names `ctx` and `spec` from the application's own types. A function passed into the factory must not mention `UseCase.Ctx` or `UseCase.GuardParameters` of that still-inferred factory.
|
|
129
|
+
|
|
130
|
+
### The call
|
|
131
|
+
|
|
132
|
+
A guard and `preExecute` receive `{ ctx, spec, token, input }`.
|
|
133
|
+
|
|
134
|
+
| Field | Meaning |
|
|
135
|
+
| --- | --- |
|
|
136
|
+
| `ctx` | The context the caller passed. |
|
|
137
|
+
| `spec` | The static contract, typed as `Spec`. A guard sees `permission: string` even when one member passed the literal `'posts.publish'`. |
|
|
138
|
+
| `token` | This member's token. |
|
|
139
|
+
| `input` | The second argument the caller passed to `execute`. Typed `unknown`. The method receives that same value. |
|
|
140
|
+
|
|
141
|
+
`UseCase.GuardParameters<typeof ApiUseCase>` is that call. `UseCase.Ctx<typeof ApiUseCase>` is `ctx`.
|
|
142
|
+
|
|
143
|
+
Family hook `input` stays `unknown` on purpose. One factory hook is checked against every member. `SavePost` and `SubscribeToPosts` do not share an input type. Member annotations are what callers of that class see. Read `ctx` and `spec` in a family hook. Input-field logic belongs on `execute` or in a guard that already knows the member.
|
|
144
|
+
|
|
145
|
+
### Guards
|
|
146
|
+
|
|
147
|
+
A guard is `(call) => void | Promise<void>`. Guards run before `execute`, and outside the hook `try`. A throw from a guard skips `preExecute`, `postExecute`, `onCatch`, and `onFinally`. A zero-argument guard typechecks. A one-argument guard receives the call, not the bare context.
|
|
148
|
+
|
|
149
|
+
### Hooks
|
|
150
|
+
|
|
151
|
+
`.hooks(definition)` registers one set of callbacks for the family. `State` is inferred from `preExecute`'s return. It is `void` when `preExecute` is omitted. Later hooks receive `Awaited<State>`. `onCatch` and `onFinally` receive `Awaited<State> | undefined` because `preExecute` may have thrown or been omitted.
|
|
152
|
+
|
|
153
|
+
| Hook | When it runs | Extra fields |
|
|
154
|
+
| --- | --- | --- |
|
|
155
|
+
| `preExecute(call)` | After the guards, before the method. | Its return value is `state` for the later hooks. |
|
|
156
|
+
| `postExecute(call, state)` | After the method returns. | `call.result` is the method's return value. |
|
|
157
|
+
| `onCatch(call, state)` | When `preExecute`, the method, or `postExecute` throws. | `call.error` is that error. The return value is ignored. The original error is thrown again. |
|
|
158
|
+
| `onFinally(call, state)` | After a successful return or a caught failure. | `call.status` is `'success'` with `result`, or `'failure'` with `error`. |
|
|
159
|
+
|
|
160
|
+
The pipeline is: guards, then `preExecute`, then the method with the caller's argument, then `postExecute`, then `onCatch` which rethrows, then `onFinally`. `postExecute` runs only after `preExecute` returns. `onFinally` always runs for attempts that entered the hooks. State is local to that invocation. Overlapping `execute` calls do not share it.
|
|
161
|
+
|
|
162
|
+
The method receives the caller's input, and the caller receives the method's return value. Hooks do not replace either one. Record success in `postExecute` and the failure in `onCatch`. Finish a span in `onFinally`, which runs for both outcomes. A throw inside `onCatch` replaces the error after `onFinally` has seen the original one.
|
|
163
|
+
|
|
164
|
+
There is no `around` hook. Leave `AsyncLocalStorage` to the application.
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { type ErrorMap, type Result } from '../core/index.js';
|
|
2
|
-
import type { AnyEventCatalog, PortToken } from '../domain/index.js';
|
|
3
|
-
import type { EventChannelCtor } from './types.js';
|
|
4
|
-
/**
|
|
5
|
-
* Request/response base for ExternalUseCase and InternalUseCase.
|
|
6
|
-
* Do not declare `trigger` here — each sibling sets a distinct literal.
|
|
7
|
-
* Not re-exported from hexok/app; application authors extend ExternalUseCase
|
|
8
|
-
* or InternalUseCase.
|
|
9
|
-
*/
|
|
10
|
-
export declare abstract class CallableUseCase {
|
|
11
|
-
/** Use-case id (`incident.close`). Unique among the callable family. */
|
|
12
|
-
static readonly key: string;
|
|
13
|
-
/** Request Standard Schema. Validated before `execute`. */
|
|
14
|
-
static readonly input: unknown;
|
|
15
|
-
/** Success Standard Schema. Types `execute`, `run`, and the contract. */
|
|
16
|
-
static readonly output: unknown;
|
|
17
|
-
/** Declared refusals. Keys become `errors.CODE()` factories on `ExecuteCtx`. */
|
|
18
|
-
static readonly errors: ErrorMap;
|
|
19
|
-
/** Port tokens keyed by the alias used in `execute`. Required by `App.from`. */
|
|
20
|
-
static readonly ports?: Record<string, PortToken<unknown>>;
|
|
21
|
-
/** `static publishes = [DomainEvents] as const` — without `as const`, Events widens to EventClass. */
|
|
22
|
-
static readonly publishes?: readonly AnyEventCatalog[];
|
|
23
|
-
/** `static channels = [ClientChannel] as const` — without `as const`, catalog keys widen. */
|
|
24
|
-
static readonly channels?: readonly EventChannelCtor[];
|
|
25
|
-
protected constructor();
|
|
26
|
-
/** Typed `never` so subclasses may take `ExecuteCtx` (tighter `publish`). */
|
|
27
|
-
abstract execute(ctx: never): Promise<unknown>;
|
|
28
|
-
/**
|
|
29
|
-
* Same one-liner as `if (!result.ok) throw new CodedError({ code: result.code })`.
|
|
30
|
-
* For `validate` / custom Results. Entity methods throw themselves.
|
|
31
|
-
*/
|
|
32
|
-
unwrap<T, E extends string>(result: Result<T, E>): T;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=callable-use-case.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"callable-use-case.d.ts","sourceRoot":"","sources":["../../src/app/callable-use-case.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;GAKG;AACH,8BAAsB,eAAe;IACnC,wEAAwE;IACxE,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAC5B,2DAA2D;IAC3D,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAC/B,yEAAyE;IACzE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAChC,gFAAgF;IAChF,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAM;IACtC,gFAAgF;IAChF,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D,sGAAsG;IACtG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACvD,6FAA6F;IAC7F,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAEvD,SAAS;IAET,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAE9C;;;OAGG;IACH,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;CAYrD"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { CodedError } from '../core/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Request/response base for ExternalUseCase and InternalUseCase.
|
|
4
|
-
* Do not declare `trigger` here — each sibling sets a distinct literal.
|
|
5
|
-
* Not re-exported from hexok/app; application authors extend ExternalUseCase
|
|
6
|
-
* or InternalUseCase.
|
|
7
|
-
*/
|
|
8
|
-
export class CallableUseCase {
|
|
9
|
-
/** Use-case id (`incident.close`). Unique among the callable family. */
|
|
10
|
-
static key;
|
|
11
|
-
/** Request Standard Schema. Validated before `execute`. */
|
|
12
|
-
static input;
|
|
13
|
-
/** Success Standard Schema. Types `execute`, `run`, and the contract. */
|
|
14
|
-
static output;
|
|
15
|
-
/** Declared refusals. Keys become `errors.CODE()` factories on `ExecuteCtx`. */
|
|
16
|
-
static errors = {};
|
|
17
|
-
/** Port tokens keyed by the alias used in `execute`. Required by `App.from`. */
|
|
18
|
-
static ports;
|
|
19
|
-
/** `static publishes = [DomainEvents] as const` — without `as const`, Events widens to EventClass. */
|
|
20
|
-
static publishes;
|
|
21
|
-
/** `static channels = [ClientChannel] as const` — without `as const`, catalog keys widen. */
|
|
22
|
-
static channels;
|
|
23
|
-
constructor() { }
|
|
24
|
-
/**
|
|
25
|
-
* Same one-liner as `if (!result.ok) throw new CodedError({ code: result.code })`.
|
|
26
|
-
* For `validate` / custom Results. Entity methods throw themselves.
|
|
27
|
-
*/
|
|
28
|
-
unwrap(result) {
|
|
29
|
-
if (!result.ok) {
|
|
30
|
-
throw new CodedError({
|
|
31
|
-
code: result.code,
|
|
32
|
-
message: result.code,
|
|
33
|
-
...(result.issues !== undefined
|
|
34
|
-
? { data: { issues: result.issues } }
|
|
35
|
-
: {}),
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
return result.value;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=callable-use-case.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"callable-use-case.js","sourceRoot":"","sources":["../../src/app/callable-use-case.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA8B,MAAM,kBAAkB,CAAC;AAI1E;;;;;GAKG;AACH,MAAM,OAAgB,eAAe;IACnC,wEAAwE;IACxE,MAAM,CAAU,GAAG,CAAS;IAC5B,2DAA2D;IAC3D,MAAM,CAAU,KAAK,CAAU;IAC/B,yEAAyE;IACzE,MAAM,CAAU,MAAM,CAAU;IAChC,gFAAgF;IAChF,MAAM,CAAU,MAAM,GAAa,EAAE,CAAC;IACtC,gFAAgF;IAChF,MAAM,CAAU,KAAK,CAAsC;IAC3D,sGAAsG;IACtG,MAAM,CAAU,SAAS,CAA8B;IACvD,6FAA6F;IAC7F,MAAM,CAAU,QAAQ,CAA+B;IAEvD,gBAAyB,CAAC;IAK1B;;;OAGG;IACH,MAAM,CAAsB,MAAoB;QAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,UAAU,CAAC;gBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,IAAI;gBACpB,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS;oBAC7B,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE;oBACrC,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC"}
|
package/dist/app/contract.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { ErrorMap, StandardSchemaV1 } from '../core/index.js';
|
|
2
|
-
import type { PathTo, UnionToIntersection } from './nest.js';
|
|
3
|
-
import { type ExternalKeysOf, type UseCaseBag } from './types.js';
|
|
4
|
-
/** One external use case in the runtime catalog. Transport-neutral, wide. */
|
|
5
|
-
export type CatalogEntry = {
|
|
6
|
-
/** Use-case `key` (`incident.close`). */
|
|
7
|
-
key: string;
|
|
8
|
-
/** Request schema. */
|
|
9
|
-
input: StandardSchemaV1;
|
|
10
|
-
/** Success schema. */
|
|
11
|
-
output: StandardSchemaV1;
|
|
12
|
-
/** Declared error map. */
|
|
13
|
-
errors: ErrorMap;
|
|
14
|
-
};
|
|
15
|
-
/** Flat catalog from `deriveContract`. Event and internal use cases are omitted. */
|
|
16
|
-
export type UseCaseContract = {
|
|
17
|
-
/** Entries keyed by use-case `key`. */
|
|
18
|
-
entries: Record<string, CatalogEntry>;
|
|
19
|
-
};
|
|
20
|
-
type UseCaseWithKey<Bag, Key> = Extract<Bag[keyof Bag], {
|
|
21
|
-
trigger: 'external';
|
|
22
|
-
key: Key;
|
|
23
|
-
}>;
|
|
24
|
-
type RouteView<C> = C extends {
|
|
25
|
-
key: infer Key extends string;
|
|
26
|
-
input: infer Input;
|
|
27
|
-
output: infer Output;
|
|
28
|
-
errors: infer Errors;
|
|
29
|
-
} ? {
|
|
30
|
-
readonly key: Key;
|
|
31
|
-
readonly input: Input;
|
|
32
|
-
readonly output: Output;
|
|
33
|
-
readonly errors: Errors;
|
|
34
|
-
} : never;
|
|
35
|
-
/**
|
|
36
|
-
* Nested by use-case `key` (`incident.close` → `{ incident: { close } }`).
|
|
37
|
-
* Event and internal use cases are omitted.
|
|
38
|
-
*/
|
|
39
|
-
export type DerivedContract<Bag> = UnionToIntersection<ExternalKeysOf<Bag> extends infer Key ? Key extends string ? PathTo<Key, RouteView<UseCaseWithKey<Bag, Key>>> : never : never>;
|
|
40
|
-
/**
|
|
41
|
-
* Build a transport-neutral catalog from a use-case class list.
|
|
42
|
-
* Duplicate `key` throws. Event use cases and InternalUseCase are skipped.
|
|
43
|
-
*/
|
|
44
|
-
export declare function deriveContract(useCases: UseCaseBag): UseCaseContract;
|
|
45
|
-
export { nestByKey } from './nest.js';
|
|
46
|
-
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/app/contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EACL,KAAK,cAAc,EAGnB,KAAK,UAAU,EAEhB,MAAM,YAAY,CAAC;AAEpB,6EAA6E;AAC7E,MAAM,MAAM,YAAY,GAAG;IACzB,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,sBAAsB;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,sBAAsB;IACtB,MAAM,EAAE,gBAAgB,CAAC;IACzB,0BAA0B;IAC1B,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,eAAe,GAAG;IAC5B,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACvC,CAAC;AAEF,KAAK,cAAc,CAAC,GAAG,EAAE,GAAG,IAAI,OAAO,CACrC,GAAG,CAAC,MAAM,GAAG,CAAC,EACd;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,GAAG,CAAA;CAAE,CAClC,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS;IAC5B,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,CAAC;IAC9B,KAAK,EAAE,MAAM,KAAK,CAAC;IACnB,MAAM,EAAE,MAAM,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,MAAM,CAAC;CACtB,GACG;IACE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,GACD,KAAK,CAAC;AAEV;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,GAAG,IAAI,mBAAmB,CACpD,cAAc,CAAC,GAAG,CAAC,SAAS,MAAM,GAAG,GACjC,GAAG,SAAS,MAAM,GAChB,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAChD,KAAK,GACP,KAAK,CACV,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,GAAG,eAAe,CAkBpE;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/app/contract.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { isCallableUseCase, isExternalUseCase, } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Build a transport-neutral catalog from a use-case class list.
|
|
4
|
-
* Duplicate `key` throws. Event use cases and InternalUseCase are skipped.
|
|
5
|
-
*/
|
|
6
|
-
export function deriveContract(useCases) {
|
|
7
|
-
const entries = {};
|
|
8
|
-
const seen = new Set();
|
|
9
|
-
for (const ctor of Object.values(useCases)) {
|
|
10
|
-
if (!isCallableUseCase(ctor))
|
|
11
|
-
continue;
|
|
12
|
-
if (seen.has(ctor.key)) {
|
|
13
|
-
throw new Error(`hexok: duplicate use-case key "${ctor.key}"`);
|
|
14
|
-
}
|
|
15
|
-
seen.add(ctor.key);
|
|
16
|
-
if (!isExternalUseCase(ctor))
|
|
17
|
-
continue;
|
|
18
|
-
entries[ctor.key] = {
|
|
19
|
-
key: ctor.key,
|
|
20
|
-
input: ctor.input,
|
|
21
|
-
output: ctor.output,
|
|
22
|
-
errors: ctor.errors,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
return { entries };
|
|
26
|
-
}
|
|
27
|
-
export { nestByKey } from './nest.js';
|
|
28
|
-
//# sourceMappingURL=contract.js.map
|
package/dist/app/contract.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/app/contract.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,iBAAiB,EACjB,iBAAiB,GAGlB,MAAM,YAAY,CAAC;AAmDpB;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,QAAoB;IACjD,MAAM,OAAO,GAAiC,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAmB,EAAE,CAAC;QAC7D,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAAE,SAAS;QACvC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAAE,SAAS;QACvC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG;YAClB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type ErrorMap, type Infer } from '../core/index.js';
|
|
2
|
-
import type { ErrorFactories } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Build `errors.NOT_FOUND()` factories from an error map.
|
|
5
|
-
* Each factory throws `CodedError` and types as `never`.
|
|
6
|
-
*/
|
|
7
|
-
export declare function errorFactories<M extends ErrorMap>(map: M): ErrorFactories<M>;
|
|
8
|
-
export type { Infer };
|
|
9
|
-
//# sourceMappingURL=error-factory.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error-factory.d.ts","sourceRoot":"","sources":["../../src/app/error-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,KAAK,EAGX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAqB5E;AAED,YAAY,EAAE,KAAK,EAAE,CAAC"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { CodedError, validate, } from '../core/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Build `errors.NOT_FOUND()` factories from an error map.
|
|
4
|
-
* Each factory throws `CodedError` and types as `never`.
|
|
5
|
-
*/
|
|
6
|
-
export function errorFactories(map) {
|
|
7
|
-
const factories = {};
|
|
8
|
-
for (const code of Object.keys(map)) {
|
|
9
|
-
const def = map[code];
|
|
10
|
-
if (def === undefined)
|
|
11
|
-
continue;
|
|
12
|
-
factories[code] = (data) => {
|
|
13
|
-
let payload;
|
|
14
|
-
if (def.data !== undefined && data !== undefined) {
|
|
15
|
-
const parsed = validate(def.data, data);
|
|
16
|
-
payload = parsed.ok ? parsed.value : data;
|
|
17
|
-
}
|
|
18
|
-
else if (data !== undefined) {
|
|
19
|
-
payload = data;
|
|
20
|
-
}
|
|
21
|
-
throw new CodedError({
|
|
22
|
-
code,
|
|
23
|
-
message: def.message ?? code,
|
|
24
|
-
...(payload !== undefined ? { data: payload } : {}),
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
return factories;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=error-factory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error-factory.js","sourceRoot":"","sources":["../../src/app/error-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAIV,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAG1B;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAqB,GAAM;IACvD,MAAM,SAAS,GAAG,EAA+C,CAAC;IAClE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAChC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAc,EAAE,EAAE;YACnC,IAAI,OAAgB,CAAC;YACrB,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAwB,EAAE,IAAI,CAAC,CAAC;gBAC5D,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5C,CAAC;iBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9B,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;YACD,MAAM,IAAI,UAAU,CAAC;gBACnB,IAAI;gBACJ,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;gBAC5B,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,SAA8B,CAAC;AACxC,CAAC"}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { type ErrorMap, type Infer, type Result, type StandardSchemaV1 } from '../core/index.js';
|
|
2
|
-
import type { AnyEventCatalog, Envelope, EventCatalog, PortToken } from '../domain/index.js';
|
|
3
|
-
import type { ErrorFactories, ResolvedPorts } from './types.js';
|
|
4
|
-
/**
|
|
5
|
-
* Catalog-scoped delivery policy. Join, refresh, and route are app authority.
|
|
6
|
-
* Presence I/O is a ChannelAdapter passed to `.route()`.
|
|
7
|
-
*
|
|
8
|
-
* ```ts
|
|
9
|
-
* class ClientChannel extends EventChannel {
|
|
10
|
-
* static readonly catalog = ClientEvents
|
|
11
|
-
* static readonly joinInput = actorSchema
|
|
12
|
-
* async join({ input }: JoinCtx<typeof ClientChannel>) { return input }
|
|
13
|
-
* async refresh({ session }: RefreshCtx<typeof ClientChannel>) { return session }
|
|
14
|
-
* async route({ ctx, clients, send }: RouteCtx<typeof ClientChannel>) {
|
|
15
|
-
* for (const { id, session } of clients) {
|
|
16
|
-
* if (visibleTo(session, ctx)) await send(id)
|
|
17
|
-
* }
|
|
18
|
-
* }
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare abstract class EventChannel {
|
|
23
|
-
/** Discriminator for routed channels. Do not override. */
|
|
24
|
-
static readonly trigger: "channel";
|
|
25
|
-
/** Catalog whose events this channel delivers. Must be a bus. */
|
|
26
|
-
static readonly catalog: AnyEventCatalog;
|
|
27
|
-
/** Join-claims Standard Schema. Validated before `join`. */
|
|
28
|
-
static readonly joinInput: unknown;
|
|
29
|
-
/** Port tokens keyed by the alias used in join, refresh, and route. */
|
|
30
|
-
static readonly ports?: Record<string, PortToken<unknown>>;
|
|
31
|
-
/** Declared refusals. Keys become `errors.CODE()` factories on join/refresh. */
|
|
32
|
-
static readonly errors: ErrorMap;
|
|
33
|
-
protected constructor();
|
|
34
|
-
/** Admit a client and return the session to store. Typed `never` so subclasses may take `JoinCtx`. */
|
|
35
|
-
abstract join(ctx: never): Promise<unknown>;
|
|
36
|
-
/** Recompute a session; return `'eject'` to drop the client. Typed `never` so subclasses may take `RefreshCtx`. */
|
|
37
|
-
abstract refresh(ctx: never): Promise<unknown>;
|
|
38
|
-
/** Choose recipients for a catalog event via `send(id)`. Typed `never` so subclasses may take `RouteCtx`. */
|
|
39
|
-
abstract route(ctx: never): Promise<void>;
|
|
40
|
-
/**
|
|
41
|
-
* Same one-liner as `if (!result.ok) throw new CodedError({ code: result.code })`.
|
|
42
|
-
* For `validate` / custom Results. Entity methods throw themselves.
|
|
43
|
-
*/
|
|
44
|
-
unwrap<T, E extends string>(result: Result<T, E>): T;
|
|
45
|
-
}
|
|
46
|
-
/** Session type returned from `join` and later passed to refresh and route. */
|
|
47
|
-
export type ChannelSession<C> = C extends {
|
|
48
|
-
prototype: {
|
|
49
|
-
join: (ctx: never) => Promise<infer S>;
|
|
50
|
-
};
|
|
51
|
-
} ? S : unknown;
|
|
52
|
-
type CatalogKeyOfChannel<C> = C extends {
|
|
53
|
-
catalog: EventCatalog<infer K extends string, infer _Kind, infer _E, infer _Ctx>;
|
|
54
|
-
} ? K : string;
|
|
55
|
-
type CatalogCtxOfChannel<C> = C extends {
|
|
56
|
-
catalog: EventCatalog<string, infer _Kind, infer _E, infer Ctx>;
|
|
57
|
-
} ? Ctx : unknown;
|
|
58
|
-
/** Argument to `EventChannel.join`. Typed from the channel class statics. */
|
|
59
|
-
export type JoinCtx<C> = {
|
|
60
|
-
/** Validated `static joinInput`. */
|
|
61
|
-
input: C extends {
|
|
62
|
-
joinInput: infer S extends StandardSchemaV1;
|
|
63
|
-
} ? Infer<S> : unknown;
|
|
64
|
-
/** Bound adapters from `static ports`. */
|
|
65
|
-
ports: C extends {
|
|
66
|
-
ports: infer P;
|
|
67
|
-
} ? ResolvedPorts<P> : Record<string, never>;
|
|
68
|
-
/** Factories from `static errors`. Throw `errors.FORBIDDEN()`. */
|
|
69
|
-
errors: C extends {
|
|
70
|
-
errors: infer E;
|
|
71
|
-
} ? ErrorFactories<E> : ErrorFactories<never>;
|
|
72
|
-
};
|
|
73
|
-
/** Argument to `EventChannel.refresh`. Typed from the channel class statics. */
|
|
74
|
-
export type RefreshCtx<C> = {
|
|
75
|
-
/** Current session from join or the last successful refresh. */
|
|
76
|
-
session: ChannelSession<C>;
|
|
77
|
-
/** Bound adapters from `static ports`. */
|
|
78
|
-
ports: C extends {
|
|
79
|
-
ports: infer P;
|
|
80
|
-
} ? ResolvedPorts<P> : Record<string, never>;
|
|
81
|
-
/** Factories from `static errors`. Throw `errors.FORBIDDEN()`. */
|
|
82
|
-
errors: C extends {
|
|
83
|
-
errors: infer E;
|
|
84
|
-
} ? ErrorFactories<E> : ErrorFactories<never>;
|
|
85
|
-
};
|
|
86
|
-
/** Argument to `EventChannel.route`. `ctx` here is catalog context, not app request context. */
|
|
87
|
-
export type RouteCtx<C> = {
|
|
88
|
-
/** Envelope just published on this channel's catalog. */
|
|
89
|
-
event: Envelope<string, unknown, CatalogKeyOfChannel<C>, 'bus', CatalogCtxOfChannel<C>>;
|
|
90
|
-
/** Catalog `ctx` from the envelope — not `ExecuteCtx.ctx`. */
|
|
91
|
-
ctx: CatalogCtxOfChannel<C>;
|
|
92
|
-
/** Connected clients and their sessions. */
|
|
93
|
-
clients: ReadonlyArray<{
|
|
94
|
-
id: string;
|
|
95
|
-
session: ChannelSession<C>;
|
|
96
|
-
}>;
|
|
97
|
-
/** Bound adapters from `static ports`. */
|
|
98
|
-
ports: C extends {
|
|
99
|
-
ports: infer P;
|
|
100
|
-
} ? ResolvedPorts<P> : Record<string, never>;
|
|
101
|
-
/** Deliver the serialized event to one client id. */
|
|
102
|
-
send: (id: string) => Promise<void>;
|
|
103
|
-
};
|
|
104
|
-
/** Presence handle for one catalog, from `channels` in `execute`. */
|
|
105
|
-
export type ChannelControl<Session = unknown> = {
|
|
106
|
-
/** Connected clients and their sessions. */
|
|
107
|
-
list(): ReadonlyArray<{
|
|
108
|
-
id: string;
|
|
109
|
-
session: Session;
|
|
110
|
-
}>;
|
|
111
|
-
/** Drop one client by id. */
|
|
112
|
-
eject(id: string): void;
|
|
113
|
-
/** Drop every client whose session matches. */
|
|
114
|
-
ejectWhere(pred: (session: Session) => boolean): void;
|
|
115
|
-
/** Re-run `refresh` for one client. */
|
|
116
|
-
refresh(id: string): Promise<void>;
|
|
117
|
-
/** Re-run `refresh` for matching sessions. */
|
|
118
|
-
refreshWhere(pred: (session: Session) => boolean): Promise<void>;
|
|
119
|
-
/** Replace a session without running `refresh`. */
|
|
120
|
-
update(id: string, session: Session): void;
|
|
121
|
-
};
|
|
122
|
-
type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
123
|
-
type ChannelHandleMap<Ch> = [Ch] extends [never] ? Record<string, never> : UnionToIntersection<Ch extends infer C ? C extends {
|
|
124
|
-
catalog: EventCatalog<infer K extends string, infer _Kind, infer _E, infer _Ctx>;
|
|
125
|
-
} ? {
|
|
126
|
-
[P in K]: ChannelControl<ChannelSession<C>>;
|
|
127
|
-
} : never : never>;
|
|
128
|
-
/** `channels` on execute ctx, keyed by catalog key from `static channels`. */
|
|
129
|
-
export type ChannelProps<C> = C extends {
|
|
130
|
-
channels: readonly (infer Ch)[];
|
|
131
|
-
} ? [Ch] extends [never] ? Record<string, never> : ChannelHandleMap<Ch> : Record<string, never>;
|
|
132
|
-
export {};
|
|
133
|
-
//# sourceMappingURL=event-channel.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"event-channel.d.ts","sourceRoot":"","sources":["../../src/app/event-channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { CodedError, } from '../core/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Catalog-scoped delivery policy. Join, refresh, and route are app authority.
|
|
4
|
-
* Presence I/O is a ChannelAdapter passed to `.route()`.
|
|
5
|
-
*
|
|
6
|
-
* ```ts
|
|
7
|
-
* class ClientChannel extends EventChannel {
|
|
8
|
-
* static readonly catalog = ClientEvents
|
|
9
|
-
* static readonly joinInput = actorSchema
|
|
10
|
-
* async join({ input }: JoinCtx<typeof ClientChannel>) { return input }
|
|
11
|
-
* async refresh({ session }: RefreshCtx<typeof ClientChannel>) { return session }
|
|
12
|
-
* async route({ ctx, clients, send }: RouteCtx<typeof ClientChannel>) {
|
|
13
|
-
* for (const { id, session } of clients) {
|
|
14
|
-
* if (visibleTo(session, ctx)) await send(id)
|
|
15
|
-
* }
|
|
16
|
-
* }
|
|
17
|
-
* }
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export class EventChannel {
|
|
21
|
-
/** Discriminator for routed channels. Do not override. */
|
|
22
|
-
static trigger = 'channel';
|
|
23
|
-
/** Catalog whose events this channel delivers. Must be a bus. */
|
|
24
|
-
static catalog;
|
|
25
|
-
/** Join-claims Standard Schema. Validated before `join`. */
|
|
26
|
-
static joinInput;
|
|
27
|
-
/** Port tokens keyed by the alias used in join, refresh, and route. */
|
|
28
|
-
static ports;
|
|
29
|
-
/** Declared refusals. Keys become `errors.CODE()` factories on join/refresh. */
|
|
30
|
-
static errors = {};
|
|
31
|
-
constructor() { }
|
|
32
|
-
/**
|
|
33
|
-
* Same one-liner as `if (!result.ok) throw new CodedError({ code: result.code })`.
|
|
34
|
-
* For `validate` / custom Results. Entity methods throw themselves.
|
|
35
|
-
*/
|
|
36
|
-
unwrap(result) {
|
|
37
|
-
if (!result.ok) {
|
|
38
|
-
throw new CodedError({
|
|
39
|
-
code: result.code,
|
|
40
|
-
message: result.code,
|
|
41
|
-
...(result.issues !== undefined
|
|
42
|
-
? { data: { issues: result.issues } }
|
|
43
|
-
: {}),
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
return result.value;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
//# sourceMappingURL=event-channel.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"event-channel.js","sourceRoot":"","sources":["../../src/app/event-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,GAKX,MAAM,kBAAkB,CAAC;AAS1B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAgB,YAAY;IAChC,0DAA0D;IAC1D,MAAM,CAAU,OAAO,GAAG,SAAkB,CAAC;IAC7C,iEAAiE;IACjE,MAAM,CAAU,OAAO,CAAkB;IACzC,4DAA4D;IAC5D,MAAM,CAAU,SAAS,CAAU;IACnC,uEAAuE;IACvE,MAAM,CAAU,KAAK,CAAsC;IAC3D,gFAAgF;IAChF,MAAM,CAAU,MAAM,GAAa,EAAE,CAAC;IAEtC,gBAAyB,CAAC;IAS1B;;;OAGG;IACH,MAAM,CAAsB,MAAoB;QAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,UAAU,CAAC;gBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,IAAI;gBACpB,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS;oBAC7B,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE;oBACrC,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { type ErrorMap, type Result } from '../core/index.js';
|
|
2
|
-
import type { AnyEventCatalog, EventClass, PortToken } from '../domain/index.js';
|
|
3
|
-
import type { EventChannelCtor } from './types.js';
|
|
4
|
-
/**
|
|
5
|
-
* Event handler. Mutually exclusive with ExternalUseCase and InternalUseCase.
|
|
6
|
-
* Queue catalogs require `static group`.
|
|
7
|
-
*
|
|
8
|
-
* ```ts
|
|
9
|
-
* class NotifyOnClose extends EventUseCase {
|
|
10
|
-
* static readonly key = 'incident.notifyOnClose'
|
|
11
|
-
* static readonly on = IncidentClosed
|
|
12
|
-
* static readonly catalog = DomainEvents
|
|
13
|
-
* async execute({ event, ports }: EventCtx<typeof NotifyOnClose>) {
|
|
14
|
-
* await ports.notifier.send(event.payload)
|
|
15
|
-
* }
|
|
16
|
-
* }
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
export declare abstract class EventUseCase {
|
|
20
|
-
/** Discriminator for `App.from` / `isEventUseCase`. Do not override. */
|
|
21
|
-
static readonly trigger: "event";
|
|
22
|
-
/** Handler id (`incident.notifyOnClose`). Used in completeness messages. */
|
|
23
|
-
static readonly key: string;
|
|
24
|
-
/** Event class this handler listens to. Required by `App.from`; must be in `catalog`. */
|
|
25
|
-
static readonly on?: EventClass;
|
|
26
|
-
/** Catalog that owns `on`. Required by `App.from`; bind it with `App.bind`. */
|
|
27
|
-
static readonly catalog?: AnyEventCatalog;
|
|
28
|
-
/** Port tokens keyed by the alias used in `execute`. */
|
|
29
|
-
static readonly ports?: Record<string, PortToken<unknown>>;
|
|
30
|
-
/** Consumer group for queue catalogs. Required when `catalog.kind` is `'queue'`. */
|
|
31
|
-
static readonly group?: string;
|
|
32
|
-
/** `static publishes = [DomainEvents] as const` — without `as const`, Events widens to EventClass. */
|
|
33
|
-
static readonly publishes?: readonly AnyEventCatalog[];
|
|
34
|
-
/** `static channels = [ClientChannel] as const` — without `as const`, catalog keys widen. */
|
|
35
|
-
static readonly channels?: readonly EventChannelCtor[];
|
|
36
|
-
/** Declared refusals. Keys become `errors.CODE()` factories on `EventCtx`. */
|
|
37
|
-
static readonly errors: ErrorMap;
|
|
38
|
-
protected constructor();
|
|
39
|
-
/** Typed `never` so subclasses may take `EventCtx` (tighter `publish`). */
|
|
40
|
-
abstract execute(ctx: never): Promise<void>;
|
|
41
|
-
/**
|
|
42
|
-
* Same one-liner as `if (!result.ok) throw new CodedError({ code: result.code })`.
|
|
43
|
-
* For `validate` / custom Results. Entity methods throw themselves.
|
|
44
|
-
*/
|
|
45
|
-
unwrap<T, E extends string>(result: Result<T, E>): T;
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=event-use-case.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"event-use-case.d.ts","sourceRoot":"","sources":["../../src/app/event-use-case.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,SAAS,EACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,8BAAsB,YAAY;IAChC,wEAAwE;IACxE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAG,OAAO,CAAU;IAC3C,4EAA4E;IAC5E,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAC5B,yFAAyF;IACzF,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC;IAChC,+EAA+E;IAC/E,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1C,wDAAwD;IACxD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D,oFAAoF;IACpF,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAC/B,sGAAsG;IACtG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACvD,6FAA6F;IAC7F,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACvD,8EAA8E;IAC9E,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAM;IAEtC,SAAS;IAET,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3C;;;OAGG;IACH,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;CAYrD"}
|