repos / starfx

supercharged async flow control library.
git clone https://github.com/neurosnap/starfx.git

commit
e1ff96d
parent
3a918f0
author
Vlad
date
2023-09-12 15:36:34 +0000 UTC
refactor(store/slice): rename `obj.patch` to `obj.update`

3 files changed,  +108, -3
M store/schema.test.ts
+33, -1
 1@@ -10,6 +10,9 @@ interface User {
 2   id: string;
 3   name: string;
 4 }
 5+interface UserWithRoles extends User {
 6+  roles: string[];
 7+}
 8 
 9 const emptyUser = { id: "", name: "" };
10 it(tests, "general types and functionality", async () => {
11@@ -54,7 +57,7 @@ it(tests, "general types and functionality", async () => {
12     const counter = yield* select(db.counter.select);
13     asserts.assertEquals(counter, 1);
14 
15-    yield* schema.update(db.currentUser.patch({ key: "name", value: "vvv" }));
16+    yield* schema.update(db.currentUser.update({ key: "name", value: "vvv" }));
17     const curUser = yield* select(db.currentUser.select);
18     asserts.assertEquals(curUser, { id: "", name: "vvv" });
19 
20@@ -67,3 +70,32 @@ it(tests, "general types and functionality", async () => {
21     asserts.assertNotEquals(fetchLoader.lastRun, 0);
22   });
23 });
24+
25+it(tests, "can work with a nested object", async () => {
26+  const schema = createSchema({
27+    currentUser: slice.obj<UserWithRoles>({ id: "", name: "", roles: [] }),
28+  });
29+  const db = schema.db;
30+  const store = configureStore(schema);
31+  await store.run(function* () {
32+    yield* schema.update(db.currentUser.update({ key: "name", value: "vvv" }));
33+    const curUser = yield* select(db.currentUser.select);
34+    asserts.assertEquals(curUser, { id: "", name: "vvv", roles: [] });
35+
36+    yield* schema.update(
37+      db.currentUser.update({ key: "roles", value: ["admin"] }),
38+    );
39+    const curUser2 = yield* select(db.currentUser.select);
40+    asserts.assertEquals(curUser2, { id: "", name: "vvv", roles: ["admin"] });
41+
42+    yield* schema.update(
43+      db.currentUser.update({ key: "roles", value: ["admin", "users"] }),
44+    );
45+    const curUser3 = yield* select(db.currentUser.select);
46+    asserts.assertEquals(curUser3, {
47+      id: "",
48+      name: "vvv",
49+      roles: ["admin", "users"],
50+    });
51+  });
52+});
A store/slice/obj.test.ts
+73, -0
 1@@ -0,0 +1,73 @@
 2+import { asserts, describe, it } from "../../test.ts";
 3+import { configureStore, updateStore } from "../../store/mod.ts";
 4+
 5+import { createObj } from "./obj.ts";
 6+const tests = describe("createObj()");
 7+
 8+export interface ICurrentUser {
 9+  username: string;
10+  userId: number;
11+  isadmin: boolean;
12+  roles: string[];
13+}
14+
15+const NAME = "currentUser";
16+const crtInitialState = {
17+  username: "",
18+  userId: 0,
19+  isadmin: false,
20+  roles: [],
21+};
22+
23+const slice = createObj<ICurrentUser>({
24+  name: NAME,
25+  initialState: crtInitialState,
26+});
27+
28+it(tests, "sets up an obj", async () => {
29+  const store = configureStore({
30+    initialState: {
31+      [NAME]: crtInitialState,
32+    },
33+  });
34+
35+  await store.run(function* () {
36+    yield* updateStore(slice.set({
37+      username: "bob",
38+      userId: 1,
39+      isadmin: true,
40+      roles: ["admin", "user"],
41+    }));
42+  });
43+
44+  asserts.assertEquals(store.getState()["currentUser"], {
45+    username: "bob",
46+    userId: 1,
47+    isadmin: true,
48+    roles: ["admin", "user"],
49+  });
50+
51+  await store.run(function* () {
52+    yield* updateStore(slice.update({ key: "username", value: "alice" }));
53+  });
54+
55+  asserts.assertEquals(store.getState()["currentUser"], {
56+    username: "alice",
57+    userId: 1,
58+    isadmin: true,
59+    roles: ["admin", "user"],
60+  });
61+
62+  await store.run(function* () {
63+    yield* updateStore(
64+      slice.update({ key: "roles", value: ["admin", "superuser"] }),
65+    );
66+  });
67+
68+  asserts.assertEquals(store.getState()["currentUser"], {
69+    username: "alice",
70+    userId: 1,
71+    isadmin: true,
72+    roles: ["admin", "superuser"],
73+  });
74+});
M store/slice/obj.ts
+2, -2
 1@@ -8,7 +8,7 @@ export interface ObjOutput<V extends AnyState, S extends AnyState>
 2   initialState: V;
 3   set: (v: V) => (s: S) => void;
 4   reset: () => (s: S) => void;
 5-  patch: <P extends keyof V>(prop: { key: P; value: V[P] }) => (s: S) => void;
 6+  update: <P extends keyof V>(prop: { key: P; value: V[P] }) => (s: S) => void;
 7   select: (s: S) => V;
 8 }
 9 
10@@ -27,7 +27,7 @@ export function createObj<V extends AnyState, S extends AnyState = AnyState>(
11       // deno-lint-ignore no-explicit-any
12       (state as any)[name] = initialState;
13     },
14-    patch: <P extends keyof V>(prop: { key: P; value: V[P] }) => (state) => {
15+    update: <P extends keyof V>(prop: { key: P; value: V[P] }) => (state) => {
16       // deno-lint-ignore no-explicit-any
17       (state as any)[name][prop.key] = prop.value;
18     },