Skip to content

Commit 5b0170a

Browse files
feat: add zustand typed store
1 parent e31754a commit 5b0170a

File tree

4 files changed

+80
-80
lines changed

4 files changed

+80
-80
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { describe, it, expect, beforeEach, test, vi } from "vitest";
2+
import { createTypedStore } from "../zustand";
3+
4+
describe("createTypedStore", () => {
5+
interface TestStore {
6+
count: number;
7+
name: string;
8+
set: <K extends keyof TestStore>(key: K, value: TestStore[K]) => void;
9+
get: <K extends keyof TestStore>(key: K) => TestStore[K];
10+
}
11+
12+
let useStore: ReturnType<typeof createTypedStore<TestStore>>;
13+
let store: TestStore;
14+
15+
beforeEach(() => {
16+
useStore = createTypedStore<TestStore>();
17+
useStore.setState({ count: 0, name: "Test" });
18+
store = useStore.getState();
19+
});
20+
21+
test("should set and get values correctly", () => {
22+
store.set("count", 5);
23+
expect(store.get("count")).toBe(5);
24+
25+
store.set("name", "Updated");
26+
expect(store.get("name")).toBe("Updated");
27+
});
28+
29+
test("should update state without affecting other properties", () => {
30+
store.set("count", 10);
31+
expect(store.get("count")).toBe(10);
32+
expect(store.get("name")).toBe("Test");
33+
});
34+
35+
test("should return the current state", () => {
36+
const state = useStore.getState();
37+
expect(state).toEqual(
38+
expect.objectContaining({ count: 0, name: "Test" })
39+
);
40+
});
41+
42+
test("should update state using setState", () => {
43+
useStore.setState({ count: 20, name: "New Name" });
44+
store = useStore.getState();
45+
expect(store.get("count")).toBe(20);
46+
expect(store.get("name")).toBe("New Name");
47+
});
48+
49+
test("should subscribe to state changes", () => {
50+
const listener = vi.fn();
51+
const unsubscribe = useStore.subscribe(listener);
52+
53+
store.set("count", 15);
54+
expect(listener).toHaveBeenCalledTimes(1);
55+
56+
store.set("name", "Another");
57+
expect(listener).toHaveBeenCalledTimes(2);
58+
59+
unsubscribe();
60+
store.set("count", 25);
61+
expect(listener).toHaveBeenCalledTimes(2);
62+
});
63+
});

packages/state/src/findAndSyncEntities.ts

-79
This file was deleted.

packages/state/src/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
export * from "./recs";
2-
// export * from "./findAndSyncEntities";

packages/state/src/zustand/index.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { create } from "zustand";
2+
3+
export const createTypedStore = <T extends object>() => {
4+
return create<
5+
T & {
6+
set: <K extends keyof T>(key: K, value: T[K]) => void;
7+
get: <K extends keyof T>(key: K) => T[K];
8+
}
9+
>(
10+
(set, get) =>
11+
({
12+
set: <K extends keyof T>(key: K, value: T[K]) =>
13+
set((state) => ({ ...state, [key]: value }) as T),
14+
get: <K extends keyof T>(key: K) => get()[key],
15+
}) as T & { set: any; get: any }
16+
);
17+
};

0 commit comments

Comments
 (0)