- commit
- ee29a97
- parent
- 2e93eae
- author
- Eric Bower
- date
- 2023-11-23 02:31:22 +0000 UTC
docs: readme
1 files changed,
+73,
-30
+73,
-30
1@@ -29,41 +29,84 @@ Read my introductory blog post:
2 - state management should not be coupled to the view
3 - full control over state management
4
5-## example
6+# example: thunks are tasks for business logic
7
8-This complete solution to the problem Jake Archibald discusses in his blog
9-article
10-[The gotcha of unhandled promise rejections](https://jakearchibald.com/2023/unhandled-rejections/):
11+```ts
12+import { createThunks, mdw } from "starfx";
13+
14+const thunks = createThunks();
15+thunks.use(mdw.err);
16+thunks.use(thunks.routes());
17+
18+const log = thunks.create("log", function* (ctx, next) {
19+ console.log("before calling next middleware");
20+ yield* next();
21+ console.log("after all middleware have run");
22+});
23+
24+store.dispatch(log());
25+```
26+
27+# example: endpoints are tasks for managing HTTP requests
28
29 ```ts
30-import { each, json, main, parallel, request } from "starfx";
31-
32-function* fetchChapter(title: string) {
33- const response = yield* request(`/chapters/${title}`);
34- const data = yield* json(response);
35- return data;
36-}
37-
38-const task = main(function* () {
39- const chapters = ["01", "02", "03"];
40- const ops = chapters.map((title) => () => fetchChapter(title));
41-
42- // parallel returns a list of `Result` type
43- const chapters = yield* parallel(ops);
44-
45- // make http requests in parallel but process them in sequence (e.g. 01, 02, 03)
46- for (const result of yield* each(chapters.sequence)) {
47- if (result.ok) {
48- console.log(result.value);
49- } else {
50- console.error(result.error);
51- }
52- yield* each.next();
53- }
54+import { createApi, mdw } from "starfx";
55+
56+const api = createApi();
57+api.use(mdw.api());
58+api.use(api.routes());
59+api.use(mdw.fetch({ baseUrl: "https://jsonplaceholder.typicode.com" }));
60+
61+export const fetchUsers = api.get("/users", api.cache());
62+
63+store.dispatch(fetchUsers());
64+// now accessible with useCache(fetchUsers)
65+```
66+
67+# example: an immutable store that acts like a reactive, in-memory database
68+
69+```ts
70+import { configureStore, createSchema, slice } from "starfx/store";
71+
72+// app-wide database for ui, api data, or anything that needs reactivity
73+const { db, initialState, update } = createSchema({
74+ users: slice.table(),
75+ cache: slice.table(),
76+ loaders: slice.loader(),
77 });
78
79-const results = await task;
80-console.log(results);
81+const fetchUsers = api.get<never, User[]>(
82+ "/users",
83+ function* (ctx, next) {
84+ // make the http request
85+ yield* next();
86+
87+ // ctx.json is a Result type that either contains the http response
88+ // json data or an error
89+ if (!ctx.json.ok) {
90+ return;
91+ }
92+
93+ const { value } = ctx.json;
94+ const users = value.reduce<Record<string, User>>((acc, user) => {
95+ acc[user.id] = user;
96+ return acc;
97+ }, {});
98+
99+ // update the store and trigger a re-render in react
100+ yield* update(db.users.add(users));
101+
102+ // User[]
103+ const users = yield* select(db.users.selectTableAsList);
104+ // User
105+ const user = yield* select(
106+ (state) => db.users.selectById(state, { id: "1" }),
107+ );
108+ },
109+);
110+
111+const store = configureStore({ initialState });
112+store.dispatch(fetchUsers());
113 ```
114
115 ## usage