Skip to content

Commit 0714608

Browse files
committed
feat: make DX of defining your store better
1 parent 8647f8a commit 0714608

25 files changed

+568
-355
lines changed

apps/example/App.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
import { StyleSheet, Text, View, Button, TextInput } from 'react-native';
22
import { useBrownieStore, setState } from '@callstack/brownie';
3-
import type { BrownfieldStore } from './brownfield-store.schema';
4-
5-
const STORE_KEY = 'BrownfieldStore';
3+
import './BrownfieldStore.brownie';
64

75
function HomeScreen() {
8-
const state = useBrownieStore<BrownfieldStore>(STORE_KEY);
6+
const state = useBrownieStore('SettingsStore');
97

108
const handleIncrement = () => {
11-
setState<BrownfieldStore>(STORE_KEY, { counter: state.counter + 1 });
9+
setState('BrownfieldStore', { counter: state.counter + 1 });
1210
};
1311

1412
const handleSetHasError = () => {
15-
setState<BrownfieldStore>(STORE_KEY, { hasError: !state.hasError });
13+
setState('BrownfieldStore', { hasError: !state.hasError });
1614
};
1715

1816
return (
@@ -26,9 +24,7 @@ function HomeScreen() {
2624
<TextInput
2725
style={styles.input}
2826
value={state.user}
29-
onChangeText={(text) =>
30-
setState<BrownfieldStore>(STORE_KEY, { user: text })
31-
}
27+
onChangeText={(text) => setState('BrownfieldStore', { user: text })}
3228
placeholder="User name"
3329
/>
3430

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { BrownieStore } from "@callstack/brownie";
2+
3+
interface BrownfieldStore extends BrownieStore {
4+
counter: number;
5+
user: string;
6+
isLoading: boolean;
7+
hasError: boolean;
8+
};
9+
10+
interface SettingsStore extends BrownfieldStore {
11+
theme: 'light' | 'dark';
12+
notificationsEnabled: boolean;
13+
privacyMode: boolean;
14+
};
15+
16+
declare module '@callstack/brownie' {
17+
interface BrownieStores {
18+
BrownfieldStore: BrownfieldStore;
19+
SettingsStore: SettingsStore;
20+
}
21+
}

apps/example/brownfield-store.schema.ts

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

apps/example/package.json

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,8 @@
3434
"node": ">=20"
3535
},
3636
"brownie": {
37-
"stores": [
38-
{
39-
"schema": "./brownfield-store.schema.ts",
40-
"typeName": "BrownfieldStore",
41-
"swift": "./swift/Generated/BrownfieldStore.swift",
42-
"kotlin": "./kotlin/app/src/main/java/com/callstack/kotlinexample/Generated/BrownfieldStore.kt",
43-
"kotlinPackageName": "com.callstack.kotlinexample"
44-
}
45-
]
37+
"swift": "./swift/Generated",
38+
"kotlin": "./kotlin/app/src/main/java/com/callstack/kotlinexample/Generated",
39+
"kotlinPackageName": "com.callstack.kotlinexample"
4640
}
4741
}

apps/example/swift/App.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct MyApp: App {
1515
let state = Store(initialState)
1616
StoreManager.shared.register(
1717
store: state,
18-
for: BrownfieldStore.self
18+
key: BrownfieldStore.storeName
1919
)
2020
}
2121

@@ -40,8 +40,8 @@ struct MyApp: App {
4040
}
4141

4242
struct NativeView: View {
43-
@UseStore<BrownfieldStore, String>(\.user) var user
44-
@UseStore<BrownfieldStore, Double>(\.counter) var counter
43+
@UseStore<BrownfieldStore, String>(\.user, key: BrownfieldStore.storeName) var user
44+
@UseStore<BrownfieldStore, Double>(\.counter, key: BrownfieldStore.storeName) var counter
4545

4646
var body: some View {
4747
VStack {

apps/example/tsconfig.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,5 @@
33
"references": [
44
{ "path": "../../packages/brownie" },
55
{ "path": "../../packages/react-native-brownfield" }
6-
],
7-
"compilerOptions": {
8-
"rootDir": "."
9-
}
6+
]
107
}

packages/brownie/ios/BrownieStore.swift

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,10 @@ protocol StateSettable {
2424
stores[key] = store
2525
}
2626

27-
public func register<State>(store: Store<State>, for type: State.Type) {
28-
let key = String(describing: type)
29-
stores[key] = store
30-
}
31-
3227
public func store<State>(key: String, as type: State.Type) -> Store<State>? {
3328
return stores[key] as? Store<State>
3429
}
3530

36-
public func store<State>(for type: State.Type) -> Store<State>? {
37-
let key = String(describing: type)
38-
return stores[key] as? Store<State>
39-
}
40-
4131
public func removeStore(key: String) {
4232
stores.removeValue(forKey: key)
4333
}
@@ -56,10 +46,6 @@ protocol StateSettable {
5646
}
5747

5848
public extension StoreManager {
59-
static func get<State>(_ type: State.Type) -> Store<State>? {
60-
shared.store(for: type)
61-
}
62-
6349
static func get<State>(key: String, as type: State.Type) -> Store<State>? {
6450
shared.store(key: key, as: type)
6551
}
@@ -82,10 +68,10 @@ public struct UseStore<State: Codable, Value>: DynamicProperty {
8268
private let keyPath: KeyPath<State, Value>
8369
@StateObject private var store: Store<State>
8470

85-
public init(_ keyPath: KeyPath<State, Value>) {
71+
public init(_ keyPath: KeyPath<State, Value>, key: String) {
8672
self.keyPath = keyPath
87-
let foundStore = StoreManager.shared.store(for: State.self)
88-
guard let foundStore else { fatalError("Store not found for \(State.self)") }
73+
let foundStore = StoreManager.shared.store(key: key, as: State.self)
74+
guard let foundStore else { fatalError("Store not found for key: \(key)") }
8975
self._store = StateObject(wrappedValue: foundStore)
9076
}
9177

packages/brownie/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"react-native": "src/index",
1616
"exports": {
1717
".": {
18+
"source": "./src/index.ts",
1819
"import": {
1920
"types": "./lib/typescript/module/src/index.d.ts",
2021
"default": "./lib/module/index.js"
@@ -61,7 +62,8 @@
6162
},
6263
"dependencies": {
6364
"quicktype-core": "^23.0.170",
64-
"quicktype-typescript-input": "^23.0.170"
65+
"quicktype-typescript-input": "^23.0.170",
66+
"ts-morph": "^25.0.0"
6567
},
6668
"devDependencies": {
6769
"@babel/core": "^7.25.2",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
type SecondStore = {
2+
theme: string;
3+
enabled: boolean;
4+
};
5+
6+
declare module '@callstack/brownie' {
7+
interface BrownieStores {
8+
SecondStore: SecondStore;
9+
}
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
type TestStore = {
2+
counter: number;
3+
name: string;
4+
isActive: boolean;
5+
};
6+
7+
declare module '@callstack/brownie' {
8+
interface BrownieStores {
9+
TestStore: TestStore;
10+
}
11+
}

0 commit comments

Comments
 (0)