Skip to content

Commit e048b79

Browse files
committed
RELEASING: Releasing 2 package(s)
Releases: kosha@1.2.1 @repo/shared@0.0.13
1 parent cb25fae commit e048b79

File tree

17 files changed

+239
-60
lines changed

17 files changed

+239
-60
lines changed

.changeset/beige-regions-relate.md

Lines changed: 0 additions & 22 deletions
This file was deleted.

README.md

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Live demo: [https://kosha-six.vercel.app](https://kosha-six.vercel.app)
6969
6. **Middleware Architecture (BYO Middleware)**
7070

7171
- Middleware support is built-in. While Kosha doesnt yet include a plugin ecosystem like Zustand, you can define and compose custom middlewares easily.
72-
- Includes working [persist middleware](https://github.com/mayank1513/kosha/blob/main/lib/src/middleware/persist.ts) example out-of-the-box
72+
- Includes working [persist middleware](https://github.com/mayank1513/kosha/blob/main/lib/src/middleware/persist.ts) and [immer middleware](https://github.com/mayank1513/kosha/blob/main/lib/src/middleware/immer.ts) example out-of-the-box
7373

7474
---
7575

@@ -210,6 +210,80 @@ You can combine `immer` middleware with other middlewares like `persist` for pow
210210

211211
---
212212

213+
### 🧩 Modular Slice Composition
214+
215+
Kosha supports Zustand-style **slice composition** via the `SliceCreator` utility type. This lets you create modular, typed slices and combine them cleanly.
216+
217+
```ts
218+
export type SliceCreator<TStore extends BaseType, TSlice = Partial<TStore>> = (
219+
set: StateSetter<TStore>,
220+
get: () => TStore | null,
221+
) => TSlice;
222+
```
223+
224+
#### Example
225+
226+
```ts
227+
interface CounterSlice {
228+
count: number;
229+
setCount: (count: number) => void;
230+
}
231+
232+
interface ThemeSlice {
233+
theme: string;
234+
setTheme: (theme: string) => void;
235+
}
236+
237+
type StoreType = CounterSlice & ThemeSlice;
238+
239+
const createCounterSlice: SliceCreator<StoreType, CounterSlice> = set => ({
240+
count: 0,
241+
setCount: count => set({ count }),
242+
});
243+
244+
const createThemeSlice: SliceCreator<StoreType, ThemeSlice> = set => ({
245+
theme: "light",
246+
setTheme: theme => set({ theme }),
247+
});
248+
249+
const useStore = create<StoreType>((...a) => ({
250+
...createCounterSlice(...a),
251+
...createThemeSlice(...a),
252+
}));
253+
```
254+
255+
#### 🔍 Notes
256+
257+
- You can use `get()` inside any slice to access the full store.
258+
- This gives more flexibility than Zustands default slice typing, where youre limited to accessing only fields from your own slice.
259+
260+
---
261+
262+
### Slicing Pattern Support
263+
264+
Kosha supports the **slicing pattern** commonly used in Zustand. You can compose your store by combining multiple slices:
265+
266+
```ts
267+
const createUserSlice = set => ({
268+
user: null,
269+
setUser: user => set({ user }),
270+
});
271+
272+
const createThemeSlice = set => ({
273+
theme: "light",
274+
toggleTheme: () => set(state => ({ theme: state.theme === "light" ? "dark" : "light" })),
275+
});
276+
277+
const useStore = create(set => ({
278+
...createUserSlice(set),
279+
...createThemeSlice(set),
280+
}));
281+
```
282+
283+
However, **Kosha does not yet provide strong TypeScript inference for slices** like Zustands `StoreApi`-based helpers. If you rely heavily on types for composing slices, you may need to manually define or merge slice types for better intellisense.
284+
285+
---
286+
213287
## ⚖️ Why Choose Kosha Over Zustand?
214288

215289
| Feature | Kosha | Zustand |

examples/nextjs/src/app/page.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ export default function Page(): ReactNode {
1212
return (
1313
<LandingPage title="Next.js Example">
1414
<Demo />
15-
<MyButton />
1615
</LandingPage>
1716
);
1817
}

lib/CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
# kosha
22

3+
## 1.2.1
4+
5+
### Patch Changes
6+
7+
- fab33c4: - ✨ Support for Zustand-style **slice composition** via `SliceCreator` utility type.
8+
9+
- Now you can structure your store in a modular, scalable way by composing smaller slices and combining them into a single store.
10+
11+
```ts
12+
export type SliceCreator<TStore extends BaseType, TSlice = Partial<TStore>> = (
13+
set: StateSetter<TStore>,
14+
get: () => TStore | null,
15+
) => TSlice;
16+
```
17+
18+
**Usage**
19+
20+
```
21+
const useKosha = create<StoreType>((...a) => ({
22+
...createThemeSlice(...a),
23+
...counterSlice(...a),
24+
}));
25+
```
26+
327
## 1.2.0
428

529
### Minor Changes

lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "kosha",
33
"author": "Mayank Kumar Chaudhari <https://mayank-chaudhari.vercel.app>",
44
"private": false,
5-
"version": "1.2.0",
5+
"version": "1.2.1",
66
"description": "A modern, lightweight, fast, and powerful global state management library for modern React.js projects. ",
77
"license": "MPL-2.0",
88
"main": "./dist/index.js",

packages/shared/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# @repo/shared
22

3+
## 0.0.13
4+
5+
### Patch Changes
6+
7+
- Updated dependencies [fab33c4]
8+
- kosha@1.2.1
9+
310
## 0.0.12
411

512
### Patch Changes

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@repo/shared",
3-
"version": "0.0.12",
3+
"version": "0.0.13",
44
"private": true,
55
"sideEffects": false,
66
"main": "./dist/index.js",

packages/shared/src/client/demo/demo.module.scss

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
.codeDisplay {
22
padding: 10px;
3+
margin: 0 -10px;
34
.hide {
45
display: none;
56
}
67
summary {
78
cursor: pointer;
9+
padding: 0 15px;
810
}
911
&[open] {
1012
.show {
@@ -86,8 +88,10 @@
8688
}
8789

8890
.preview {
89-
padding: 0 30px;
90-
padding-bottom: 30px;
91+
padding: 0 15px;
92+
.flex h2 {
93+
margin-top: 0;
94+
}
9195
}
9296

9397
.center {

packages/shared/src/client/demo/demo.tsx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import compareCode from "./compare?raw";
1919
import compareStoreCode from "./compare/store?raw";
2020
import { CounterWithImmer } from "./immer";
2121
import CounterWithImmerCode from "./immer?raw";
22+
import { SlicingTheStore } from "./slice";
23+
import SlicingTheStoreCode from "./slice?raw";
2224

2325
const compareExCode = [
2426
{ filename: "compare.tsx", code: compareCode },
@@ -51,14 +53,6 @@ export function Demo() {
5153
<Compare />
5254
<CodeDisplay code={compareExCode} />
5355
</div>
54-
<div className={styles.demo}>
55-
<BasicExample />
56-
<CodeDisplay code={basicExCode} />
57-
</div>
58-
<div className={styles.demo}>
59-
<WithSelector />
60-
<CodeDisplay code={withSelectorExCode} />
61-
</div>
6256
<div className={styles.demo}>
6357
<PersistedCounter />
6458
<CodeDisplay code={[{ filename: "index.tsx", code: PersistedCounterCode }]} />
@@ -67,6 +61,18 @@ export function Demo() {
6761
<CounterWithImmer />
6862
<CodeDisplay code={[{ filename: "index.tsx", code: CounterWithImmerCode }]} />
6963
</div>
64+
<div className={styles.demo}>
65+
<SlicingTheStore />
66+
<CodeDisplay code={[{ filename: "index.tsx", code: SlicingTheStoreCode }]} />
67+
</div>
68+
<div className={styles.demo}>
69+
<BasicExample />
70+
<CodeDisplay code={basicExCode} />
71+
</div>
72+
<div className={styles.demo}>
73+
<WithSelector />
74+
<CodeDisplay code={withSelectorExCode} />
75+
</div>
7076
</>
7177
);
7278
}

packages/shared/src/client/demo/immer/index.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { create } from "kosha";
22
import { immer } from "kosha/middleware";
3+
import styles from "../demo.module.scss";
34

45
interface CounterStore {
56
count: number;
@@ -19,10 +20,12 @@ const useKoshaWithImmer = create(
1920
export const CounterWithImmer = () => {
2021
const { count, setCount } = useKoshaWithImmer();
2122
return (
22-
<div>
23+
<div className={styles.preview}>
2324
<h2>Example using immer middleware</h2>
24-
<div>Count: {count}</div>
25-
<button onClick={() => setCount(count + 1)}>Increment</button>
25+
<div>
26+
Count: {count}
27+
<button onClick={() => setCount(count + 1)}>Increment</button>
28+
</div>
2629
</div>
2730
);
2831
};

0 commit comments

Comments
 (0)