Skip to content

Commit 79e8101

Browse files
authored
docs(brownie): add alpha documentation for shared state library (#178)
* docs(brownie): add alpha documentation for shared state library * refactor(brownie): require selector param in useStore
1 parent 0e0059a commit 79e8101

File tree

9 files changed

+767
-42
lines changed

9 files changed

+767
-42
lines changed

docs/docs/_nav.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,10 @@
33
"text": "Docs",
44
"link": "/docs/getting-started/quick-start",
55
"activeMatch": "^/docs/"
6+
},
7+
{
8+
"text": "Brownie (Alpha)",
9+
"link": "/brownie/overview",
10+
"activeMatch": "^/brownie/"
611
}
712
]

docs/docs/brownie/_meta.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[
2+
{
3+
"type": "file",
4+
"name": "overview",
5+
"label": "Overview"
6+
},
7+
{
8+
"type": "file",
9+
"name": "store-definition",
10+
"label": "Defining Stores"
11+
},
12+
{
13+
"type": "file",
14+
"name": "codegen",
15+
"label": "Code Generation"
16+
},
17+
{
18+
"type": "file",
19+
"name": "typescript-usage",
20+
"label": "TypeScript Usage"
21+
},
22+
{
23+
"type": "file",
24+
"name": "swift-usage",
25+
"label": "Swift Usage"
26+
}
27+
]

docs/docs/brownie/codegen.mdx

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Code Generation
2+
3+
The Brownie CLI generates native types from your TypeScript store definitions.
4+
5+
## Usage
6+
7+
```bash
8+
brownie codegen # Generate for all configured platforms
9+
brownie codegen -p swift # Generate Swift only
10+
brownie codegen --platform kotlin # Generate Kotlin only (coming soon)
11+
brownie --help # Show help
12+
brownie --version # Show version
13+
```
14+
15+
## Configuration
16+
17+
Add to your app's `package.json`:
18+
19+
```json
20+
{
21+
"brownie": {
22+
"swift": "./ios/Generated/",
23+
"kotlin": "./android/app/src/main/java/com/example/",
24+
"kotlinPackageName": "com.example"
25+
}
26+
}
27+
```
28+
29+
| Field | Required | Description |
30+
| ------------------- | -------- | ---------------------------------------------------------- |
31+
| `swift` | No\* | Output directory for Swift files |
32+
| `kotlin` | No\* | Output directory for Kotlin files |
33+
| `kotlinPackageName` | No | Kotlin package name (extracted from path if not specified) |
34+
35+
\*At least one of `swift` or `kotlin` is required.
36+
37+
## Generated Output
38+
39+
For this TypeScript definition:
40+
41+
```ts
42+
interface BrownfieldStore extends BrownieStore {
43+
counter: number;
44+
user: { name: string };
45+
}
46+
```
47+
48+
### Swift Output
49+
50+
```swift
51+
import Brownie
52+
53+
struct BrownfieldStore: Codable {
54+
var counter: Double
55+
var user: User
56+
}
57+
58+
struct User: Codable {
59+
var name: String
60+
}
61+
62+
extension BrownfieldStore: BrownieStoreProtocol {
63+
public static let storeName = "BrownfieldStore"
64+
}
65+
```
66+
67+
The generated struct:
68+
69+
- Conforms to `Codable` for JSON serialization
70+
- Conforms to `BrownieStoreProtocol` with auto-generated `storeName`
71+
- Uses mutable `var` properties
72+
73+
### Kotlin Output (Coming Soon)
74+
75+
```kotlin
76+
package com.example
77+
78+
data class BrownfieldStore(
79+
val counter: Double,
80+
val user: User
81+
)
82+
83+
data class User(
84+
val name: String
85+
)
86+
```
87+
88+
## Auto-Generation Hooks
89+
90+
### iOS (Podfile)
91+
92+
Run codegen before pod install:
93+
94+
```ruby
95+
pre_install do |installer|
96+
system("npx", "brownie", "codegen", "-p", "swift")
97+
end
98+
```
99+
100+
### Android (build.gradle.kts)
101+
102+
Run codegen before build:
103+
104+
```kotlin
105+
tasks.register("generateBrownfieldStore") {
106+
exec { commandLine("npx", "brownie", "codegen", "-p", "kotlin") }
107+
}
108+
preBuild.dependsOn("generateBrownfieldStore")
109+
```
110+
111+
## How It Works
112+
113+
1. CLI recursively finds all `*.brownie.ts` files
114+
2. Parses `declare module '@callstack/brownie'` blocks using ts-morph
115+
3. Extracts store names from `BrownieStores` interface
116+
4. Generates native types using quicktype

docs/docs/brownie/overview.mdx

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Brownie
2+
3+
:::warning Alpha
4+
Brownie is in alpha stage and not yet released. APIs may change.
5+
:::
6+
7+
Brownie is a shared state management library for React Native brownfield apps. It enables seamless state synchronization between your React Native code and native iOS code.
8+
9+
## Features
10+
11+
- **Shared State** - Single source of truth accessible from both TypeScript and Swift
12+
- **Type Safety** - Full type inference from TypeScript schema to generated Swift types
13+
- **React Integration** - `useStore` hook with selector support for optimal re-renders
14+
- **SwiftUI Integration** - `@UseStore` property wrapper for reactive UI updates
15+
- **UIKit Support** - Subscribe-based API for imperative UI updates
16+
17+
## Platform Support
18+
19+
| Platform | Status |
20+
| -------- | ----------- |
21+
| iOS | Supported |
22+
| Android | Coming soon |
23+
24+
## How It Works
25+
26+
```
27+
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
28+
│ TypeScript │──────▶│ Brownie CLI │──────▶│ Swift types │
29+
│ Store Schema │ │ (codegen) │ │ (generated) │
30+
└─────────────────┘ └──────────────────┘ └─────────────────┘
31+
```
32+
33+
1. Define your store shape in a `*.brownie.ts` file using TypeScript
34+
2. Run `brownie codegen` to generate native types
35+
3. Use `useStore` in React Native and `Store<T>` in Swift
36+
4. State changes sync automatically between both sides
37+
38+
## Installation
39+
40+
```bash
41+
npm install @callstack/brownie
42+
# or
43+
yarn add @callstack/brownie
44+
```
45+
46+
### iOS Setup
47+
48+
Add to your `Podfile`:
49+
50+
```ruby
51+
pre_install do |installer|
52+
system("npx", "brownie", "codegen", "-p", "swift")
53+
end
54+
```
55+
56+
Then run `pod install`.
57+
58+
## Quick Example
59+
60+
**TypeScript (store definition):**
61+
62+
```ts
63+
// BrownfieldStore.brownie.ts
64+
import type { BrownieStore } from '@callstack/brownie';
65+
66+
interface AppStore extends BrownieStore {
67+
counter: number;
68+
user: { name: string };
69+
}
70+
71+
declare module '@callstack/brownie' {
72+
interface BrownieStores {
73+
AppStore: AppStore;
74+
}
75+
}
76+
```
77+
78+
**TypeScript (usage):**
79+
80+
```tsx
81+
import { useStore } from '@callstack/brownie';
82+
83+
function Counter() {
84+
const [counter, setState] = useStore('AppStore', (s) => s.counter);
85+
86+
return (
87+
<Button
88+
title={`Count: ${counter}`}
89+
onPress={() => setState((prev) => ({ counter: prev.counter + 1 }))}
90+
/>
91+
);
92+
}
93+
```
94+
95+
**Swift (usage):**
96+
97+
```swift
98+
import Brownie
99+
100+
struct ContentView: View {
101+
@UseStore<AppStore> var store
102+
103+
var body: some View {
104+
VStack {
105+
Text("Count: \(Int(store.state.counter))")
106+
Button("Increment") {
107+
store.set { $0.counter += 1 }
108+
}
109+
}
110+
}
111+
}
112+
```
113+
114+
## Next Steps
115+
116+
- [Defining Stores](/brownie/store-definition) - Learn how to define your store schema
117+
- [Code Generation](/brownie/codegen) - Configure and run the codegen CLI
118+
- [TypeScript Usage](/brownie/typescript-usage) - Use stores in React Native
119+
- [Swift Usage](/brownie/swift-usage) - Use stores in iOS apps
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Defining Stores
2+
3+
Stores are defined in TypeScript using `*.brownie.ts` files. The CLI auto-discovers these files and generates corresponding native types.
4+
5+
## Basic Store
6+
7+
Create a file ending with `.brownie.ts`:
8+
9+
```ts
10+
// BrownfieldStore.brownie.ts
11+
import type { BrownieStore } from '@callstack/brownie';
12+
13+
interface BrownfieldStore extends BrownieStore {
14+
counter: number;
15+
user: string;
16+
isLoading: boolean;
17+
}
18+
19+
declare module '@callstack/brownie' {
20+
interface BrownieStores {
21+
BrownfieldStore: BrownfieldStore;
22+
}
23+
}
24+
```
25+
26+
Key points:
27+
28+
- Interface must extend `BrownieStore`
29+
- Register via module augmentation in `BrownieStores`
30+
- Interface name becomes the store key
31+
32+
## Nested Objects
33+
34+
Stores support nested object types:
35+
36+
```ts
37+
interface BrownfieldStore extends BrownieStore {
38+
counter: number;
39+
user: {
40+
name: string;
41+
email: string;
42+
};
43+
}
44+
```
45+
46+
Generated Swift:
47+
48+
```swift
49+
struct BrownfieldStore: Codable {
50+
var counter: Double
51+
var user: User
52+
}
53+
54+
struct User: Codable {
55+
var name: String
56+
var email: String
57+
}
58+
```
59+
60+
## Multiple Stores
61+
62+
Define multiple stores in the same file or separate files:
63+
64+
```ts
65+
// Stores.brownie.ts
66+
import type { BrownieStore } from '@callstack/brownie';
67+
68+
interface UserStore extends BrownieStore {
69+
name: string;
70+
email: string;
71+
}
72+
73+
interface SettingsStore extends BrownieStore {
74+
theme: 'light' | 'dark';
75+
notificationsEnabled: boolean;
76+
}
77+
78+
declare module '@callstack/brownie' {
79+
interface BrownieStores {
80+
UserStore: UserStore;
81+
SettingsStore: SettingsStore;
82+
}
83+
}
84+
```
85+
86+
## Supported Types
87+
88+
| TypeScript | Swift |
89+
| ----------------------------- | ------------------ |
90+
| `number` | `Double` |
91+
| `string` | `String` |
92+
| `boolean` | `Bool` |
93+
| `object` | Generated `struct` |
94+
| Union literals (`'a' \| 'b'`) | `String` (enum) |
95+
96+
## Import the Store File
97+
98+
Make sure to import your `.brownie.ts` file in your app entry point:
99+
100+
```ts
101+
// App.tsx or index.js
102+
import './BrownfieldStore.brownie';
103+
```
104+
105+
This ensures TypeScript module augmentation is applied.
106+
107+
## Store Discovery
108+
109+
The CLI recursively finds all `*.brownie.ts` files in your project (excluding `node_modules`). Each file is parsed to extract store definitions from the `BrownieStores` interface.

0 commit comments

Comments
 (0)