Skip to content

Commit dc15701

Browse files
authored
chore: add AGENTS.md file (#1289)
1 parent 8e0993c commit dc15701

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed

AGENTS.md

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to the agents when working with code in this repository.
4+
5+
## Overview
6+
7+
This is a monorepo for the Supabase Flutter SDK, managed by [Melos](https://melos.invertase.dev/). It contains multiple independently versioned packages that provide Flutter and Dart clients for Supabase services.
8+
9+
## Package Architecture
10+
11+
The repository follows a layered dependency structure:
12+
13+
- **supabase_flutter**: Flutter-specific wrapper with platform integrations (deep links, local storage, app lifecycle)
14+
- **supabase**: Core Dart client that orchestrates all service clients
15+
- **gotrue**: Authentication client (sessions, JWT, OAuth)
16+
- **postgrest**: Database query client with ORM-style API
17+
- **realtime_client**: WebSocket client for real-time subscriptions
18+
- **storage_client**: File storage client with retry logic
19+
- **functions_client**: Edge functions invocation client
20+
- **yet_another_json_isolate**: JSON parsing in separate isolate for performance
21+
22+
Key architectural patterns:
23+
- `SupabaseClient` is a facade that initializes and coordinates all sub-clients
24+
- `AuthHttpClient` wraps HTTP requests to inject JWT tokens automatically
25+
- Builder/fluent interface pattern for query construction (`from().select().eq()`)
26+
- Stream-based reactive pattern using RxDart `BehaviorSubject`
27+
- Platform-specific code via conditional imports (web vs native)
28+
29+
## Development Setup
30+
31+
```bash
32+
# Install Melos globally (if not already installed)
33+
dart pub global activate melos
34+
35+
# Bootstrap dependencies for all packages
36+
melos bootstrap
37+
# or shorthand:
38+
melos bs
39+
```
40+
41+
## Common Commands
42+
43+
### Linting and Formatting
44+
45+
```bash
46+
# Run all static analysis checks (analyze + format)
47+
melos run lint:all
48+
49+
# Run analyzer on all packages
50+
melos run analyze
51+
52+
# Format code (80 char line length)
53+
melos run format
54+
```
55+
56+
### Testing
57+
58+
Most packages have unit tests. The `postgrest`, `gotrue`, and `storage_client` packages require Docker services.
59+
60+
**For packages requiring Docker (postgrest, gotrue, storage_client):**
61+
62+
```bash
63+
# 1. Start Docker services
64+
cd infra/<package>
65+
docker compose up -d
66+
67+
# 2. Run tests (from package directory)
68+
cd ../../packages/<package>
69+
dart test -j 1
70+
71+
# 3. Stop Docker services when done
72+
cd ../../infra/<package>
73+
docker compose down
74+
```
75+
76+
The `-j 1` flag runs tests sequentially (not concurrently), which is required since tests share the same Docker services.
77+
78+
**For packages without Docker requirements:**
79+
80+
```bash
81+
# Run tests from package directory
82+
cd packages/<package>
83+
dart test
84+
```
85+
86+
**Run tests with coverage:**
87+
88+
```bash
89+
# From root or package directory
90+
melos run test:coverage
91+
```
92+
93+
### Running a Single Test File
94+
95+
```bash
96+
# From package directory
97+
dart test test/specific_test.dart
98+
99+
# For a specific test case
100+
dart test test/specific_test.dart -n "test name pattern"
101+
```
102+
103+
### Package Management
104+
105+
```bash
106+
# Upgrade dependencies across all packages
107+
melos run upgrade
108+
109+
# Check for outdated dependencies
110+
melos run outdated
111+
```
112+
113+
### Version Management
114+
115+
```bash
116+
# Update version.dart files for all packages
117+
melos run update-version
118+
119+
# Version packages and generate changelogs (handled by melos)
120+
melos version
121+
```
122+
123+
## Key Implementation Details
124+
125+
### Authentication Flow
126+
127+
- **GoTrueClient** manages sessions, tokens, and JWT validation
128+
- Emits auth state changes via `Stream<AuthState>`
129+
- **supabase_flutter** adds session persistence via `SharedPreferences` (mobile) or browser localStorage (web)
130+
- Deep link handling for OAuth callbacks (detects `?code=` for PKCE or `#access_token=` for implicit flow)
131+
- Auth tokens are automatically injected into all HTTP requests via `AuthHttpClient`
132+
- Realtime client receives token updates when auth state changes
133+
134+
### Query Building
135+
136+
PostgREST queries use a chain of builder classes:
137+
```
138+
PostgrestQueryBuilder → PostgrestFilterBuilder → PostgrestTransformBuilder → ResponsePostgrestBuilder
139+
```
140+
141+
Example: `supabase.from('users').select('id, name').eq('id', 1).limit(10)`
142+
143+
### Realtime Architecture
144+
145+
- `SupabaseStreamBuilder` combines initial PostgREST data fetch with realtime updates
146+
- Uses RxDart `BehaviorSubject` for reactive streams
147+
- WebSocket maintains persistent connection with 30s heartbeat
148+
- Auto-reconnect with exponential backoff on disconnect
149+
150+
### Error Handling
151+
152+
Each package has its own exception hierarchy:
153+
- **gotrue**: `AuthException` (base), with specialized subclasses like `AuthApiException`, `AuthRetryableFetchException`
154+
- **postgrest**: HTTP-based error responses
155+
- **realtime**: `RealtimeSubscribeException` with status tracking
156+
- **storage**: Retry logic with exponential backoff (up to 8 attempts)
157+
158+
### Platform Differences
159+
160+
The codebase uses conditional imports for platform-specific implementations:
161+
```dart
162+
import './local_storage_stub.dart'
163+
if (dart.library.js_interop) './local_storage_web.dart'
164+
```
165+
166+
This enables:
167+
- Native mobile (iOS/Android): SharedPreferences for persistence
168+
- Web: Browser localStorage
169+
- Single codebase for all platforms
170+
171+
### Client Configuration
172+
173+
All clients accept options classes for customization:
174+
- `PostgrestClientOptions`: Custom schema access
175+
- `AuthClientOptions`: Auto-refresh tokens, PKCE vs implicit flow
176+
- `StorageClientOptions`: Retry attempts for uploads
177+
- `FunctionsClientOptions`: Edge function region selection
178+
- `RealtimeClientOptions`: WebSocket timeout configuration
179+
180+
### URL Structure
181+
182+
The `SupabaseClient` transforms a base URL into service-specific endpoints:
183+
```
184+
supabaseUrl: "https://project.supabase.co"
185+
├─ REST: "https://project.supabase.co/rest/v1"
186+
├─ Realtime: "ws://project.supabase.co/realtime/v1"
187+
├─ Auth: "https://project.supabase.co/auth/v1"
188+
├─ Storage: "https://project.supabase.co/storage/v1" (or dedicated host)
189+
└─ Functions: "https://project.supabase.co/functions/v1"
190+
```
191+
192+
## Testing Against Local Supabase
193+
194+
For integration testing, you may want to point to a local Supabase instance:
195+
196+
```dart
197+
await Supabase.initialize(
198+
url: 'http://localhost:54321',
199+
anonKey: 'your-local-anon-key',
200+
);
201+
```
202+
203+
## Contributing Guidelines
204+
205+
- Fork the repo and create feature branches
206+
- Run `melos run lint:all` before committing
207+
- Ensure tests pass for modified packages
208+
- Update package changelogs if making notable changes
209+
- Line length limit is 80 characters
210+
- Use `dart format` for consistent formatting

0 commit comments

Comments
 (0)