nanoeffects 0.25.0 → 0.27.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 +76 -23
- package/dist/{action-creator-Bpa8BUS9.d.ts → action-creator-D_c223C7.d.ts} +51 -23
- package/dist/actions.d.ts +54 -21
- package/dist/actions.js +1 -1
- package/dist/{bus-hHp-T7JV.js → bus-DQDHUN5e.js} +1 -1
- package/dist/{context-types-BKIH5a8s.d.ts → context-types-nGtzhjxD.d.ts} +1 -1
- package/dist/context.d.ts +2 -2
- package/dist/dev.d.ts +2 -2
- package/dist/effects.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/match.d.ts +1 -1
- package/dist/{module-B5V47MZ0.d.ts → module-WX0Gngnt.d.ts} +40 -57
- package/dist/notrace/{action-creator-D2CotugT.d.ts → action-creator-Bux7Zzsl.d.ts} +51 -23
- package/dist/notrace/actions.d.ts +114 -98
- package/dist/notrace/actions.js +1 -1
- package/dist/notrace/{bus-BdyvumpX.js → bus-CGi2lrd5.js} +1 -1
- package/dist/notrace/effects.d.ts +2 -2
- package/dist/notrace/index.d.ts +2 -2
- package/dist/notrace/index.js +1 -1
- package/dist/notrace/{plugin-ks-oNq5n.d.ts → plugin-CATXOxtj.d.ts} +10 -9
- package/dist/notrace/policies.d.ts +1 -1
- package/dist/notrace/redux.d.ts +1 -1
- package/dist/observable.d.ts +6 -6
- package/dist/oop.d.ts +2 -2
- package/dist/oop.js +1 -1
- package/dist/{plugin-B6UQyoVd.d.ts → plugin-vvkmIIz2.d.ts} +11 -10
- package/dist/policies.d.ts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/redux.d.ts +1 -1
- package/dist/scope.d.ts +2 -2
- package/dist/signal.d.ts +1 -1
- package/dist/signal.js +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/trace.d.ts +1 -1
- package/dist/{types-DWjyeii7.d.ts → types-Bf-LX_tE.d.ts} +2 -2
- package/dist/vue.d.ts +1 -1
- package/dist/{with-policy-BeH8wCkX.d.ts → with-policy-CPjx0sLm.d.ts} +1 -1
- package/docs/README.md +5 -4
- package/docs/actions.md +93 -52
- package/docs/chat-example.md +6 -6
- package/docs/context.md +1 -1
- package/docs/effects.md +2 -2
- package/docs/errors.md +1 -1
- package/docs/guide.md +25 -25
- package/docs/hmr.md +1 -1
- package/docs/motivation.md +10 -4
- package/docs/oop.md +2 -0
- package/docs/package.md +1 -1
- package/docs/plugins.md +23 -23
- package/docs/query-libraries.md +14 -14
- package/docs/scope.md +22 -22
- package/docs/server.md +12 -12
- package/docs/stability.md +90 -0
- package/docs/starter.md +1 -1
- package/docs/tracing.md +2 -2
- package/docs/typescript.md +16 -16
- package/llms-full.txt +326 -183
- package/llms.txt +3 -2
- package/package.json +4 -3
package/docs/typescript.md
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# Use nanoeffects in a TypeScript app with many files
|
|
2
2
|
|
|
3
|
-
Read this page if your app is in TypeScript and the
|
|
3
|
+
Read this page if your app is in TypeScript and the handlers and modules live in different files. It shows how to write an action with a handler so that TypeScript infers its payload and result, and what to add when the handlers need the fields of your bus (`ctx.store`, the effects of `effectsPlugin`). For one file or for JavaScript you do not need it.
|
|
4
4
|
|
|
5
|
-
## Write
|
|
5
|
+
## Write an action with its handler
|
|
6
6
|
|
|
7
|
-
Give `
|
|
7
|
+
Give `createAction` the handler and write nothing else. The payload comes from the annotated parameter, the result from the body. You do not write a generic.
|
|
8
8
|
|
|
9
9
|
<!-- docs-check: skip - a file of examples/typescript, type-checked there -->
|
|
10
10
|
```ts
|
|
11
11
|
// user.ts
|
|
12
|
-
import {
|
|
12
|
+
import { createAction, createModule } from "nanoeffects/actions";
|
|
13
13
|
|
|
14
14
|
export type User = { id: string; name: string };
|
|
15
15
|
|
|
16
16
|
// payload: string, from `id: string`; result: Promise<User>, from the body
|
|
17
|
-
export const getUser =
|
|
17
|
+
export const getUser = createAction(
|
|
18
18
|
"user/get",
|
|
19
19
|
async (id: string, { signal }) => {
|
|
20
20
|
const response = await fetch(`/api/users/${id}`, { signal });
|
|
@@ -56,11 +56,11 @@ A wrong payload at the call (`getUser(1)`) is an error. Annotate the parameters,
|
|
|
56
56
|
|
|
57
57
|
## Give `ctx` the fields of your bus
|
|
58
58
|
|
|
59
|
-
Types of a bus live on the bus. `contextPlugin({ store })` and `effectsPlugin({ race })` make `ctx.store` and `ctx.race` known to the handlers of **that bus**.
|
|
59
|
+
Types of a bus live on the bus. `contextPlugin({ store })` and `effectsPlugin({ race })` make `ctx.store` and `ctx.race` known to the handlers of **that bus**. An action with a handler made in another file does not see the bus, so its `ctx` has no `store`:
|
|
60
60
|
|
|
61
61
|
<!-- docs-check: skip - shows the error on purpose -->
|
|
62
62
|
```ts
|
|
63
|
-
export const getUser =
|
|
63
|
+
export const getUser = createAction("user/get", (id: string, ctx) => {
|
|
64
64
|
ctx.store; // error: Property 'store' does not exist
|
|
65
65
|
});
|
|
66
66
|
```
|
|
@@ -93,7 +93,7 @@ export type AppContext = Context<AppEvents>; // ctx of a handler of this bus: ha
|
|
|
93
93
|
| Type | What it is | Why you name it |
|
|
94
94
|
| ---- | ---------- | --------------- |
|
|
95
95
|
| `EventsOf<typeof bus>` | the event map of the bus, with the context fields of the plugins (and of `WithContext`, if you use it) | the source of `AppContext` |
|
|
96
|
-
| `Context<AppEvents>` | the `ctx` that a handler of the bus gets | annotate the `ctx` of a handler given to `
|
|
96
|
+
| `Context<AppEvents>` | the `ctx` that a handler of the bus gets | annotate the `ctx` of a handler given to `createAction` |
|
|
97
97
|
|
|
98
98
|
These types change nothing at runtime. They only tell the checker what the bus already does.
|
|
99
99
|
|
|
@@ -102,10 +102,10 @@ Annotate `ctx` with `AppContext` where the handler reads a field of the bus, and
|
|
|
102
102
|
<!-- docs-check: skip - a file of examples/typescript-context, type-checked there -->
|
|
103
103
|
```ts
|
|
104
104
|
// user.ts
|
|
105
|
-
import {
|
|
105
|
+
import { createAction } from "nanoeffects/actions";
|
|
106
106
|
import { type AppContext, createModule } from "./bus";
|
|
107
107
|
|
|
108
|
-
export const getUser =
|
|
108
|
+
export const getUser = createAction(
|
|
109
109
|
"user/get",
|
|
110
110
|
(id: string, { store, signal }: AppContext) => store.fetchUser(id, { signal }),
|
|
111
111
|
);
|
|
@@ -145,14 +145,14 @@ Pass `ctx` (or `{ signal }`) when you call it. The effects of `nanoeffects/effec
|
|
|
145
145
|
|
|
146
146
|
## Keep the contract apart from the code
|
|
147
147
|
|
|
148
|
-
When the file with the
|
|
148
|
+
When the file with the action must not import the code that implements it, make the action without a handler. Here you write the payload and the result once, as a `Call`, and the handler goes to a module, where it needs no annotation. `Call` is a promise of yours: nothing checks it against the handler, so keep the handler typed from it in the module:
|
|
149
149
|
|
|
150
150
|
<!-- docs-check: skip - fragment of the file above -->
|
|
151
151
|
```ts
|
|
152
|
-
export const getUser =
|
|
152
|
+
export const getUser = createAction<Call<string, Promise<User>>>("user/get"); // the contract
|
|
153
153
|
|
|
154
154
|
createModule("user", (m) => {
|
|
155
|
-
// payload and result come from the
|
|
155
|
+
// payload and result come from the Call, ctx from the app: no annotation
|
|
156
156
|
m.handle(getUser, (id, { store, signal }) => store.fetchUser(id, { signal }));
|
|
157
157
|
});
|
|
158
158
|
```
|
|
@@ -161,8 +161,8 @@ A wrong payload, a wrong field of `ctx` and a wrong result are errors.
|
|
|
161
161
|
|
|
162
162
|
## Check your setup
|
|
163
163
|
|
|
164
|
-
- **A field is missing on `ctx`.** The `ctx` of a handler given to `
|
|
165
|
-
- **`EventsOf<typeof bus>` is `never`.** `bus` is not a bus. `bus.use(
|
|
164
|
+
- **A field is missing on `ctx`.** The `ctx` of a handler given to `createAction` is not annotated: add `: AppContext`. A handler written inline in `m.handle` or `m.on` of a module made with the `createModule` of `bus.ts` does not need it. The default `ctx` has no fields of your bus.
|
|
165
|
+
- **`EventsOf<typeof bus>` is `never`.** `bus` is not a bus. `bus.use(actionsPlugin())` and `bus.use(modulePlugin(...))` return the registry or the app, not the bus: keep the bus in its own constant (`bus`, then `app = bus.use(modulePlugin())`).
|
|
166
166
|
- **`effectsPlugin` is not in the type.** `use` must come before you read `typeof bus`. Chain `createBus(...).use(effectsPlugin(...))` in one binding.
|
|
167
167
|
- **A policy loses the types.** It does not: `latest(handler)` keeps the payload, the result and the context of `handler`.
|
|
168
|
-
- **Do not pass the context as a generic of `
|
|
168
|
+
- **Do not pass the context as a generic of `createAction`.** It is the fourth generic of the handler form, after the payload, the result and the type string, so you would have to write all four. Annotate `ctx` with `AppContext`, or put the handler in a module made with the `createModule` of `bus.ts`.
|