11---
2- applyTo : " **/*.ts "
2+ applyTo : " **/*.{ts,tsx} "
33---
44
5- # Evolu Project Guidelines
5+ # Evolu project guidelines
66
77You are helping with the Evolu project. Follow these specific conventions and patterns:
88
9- ## Code Organization & Imports
9+ ## Code organization & imports
1010
1111- ** Use named imports only** - avoid default exports and namespace imports
1212- ** Use unique exported members** - avoid namespaces, use descriptive names to prevent conflicts
1313- ** Organize code top-down** - public interfaces first, then implementation, then implementation details
14- - ** Separate public/internal code** - use package.json exports to define clear boundaries
1514
1615``` ts
1716// ✅ Good
@@ -24,11 +23,9 @@ import Foo from "Foo.ts";
2423export const Utils = { ok , trySync };
2524```
2625
27- ## Type System & Immutability
26+ ## Immutability
2827
2928- ** Favor immutability** - use ` readonly ` properties and ` ReadonlyArray ` /` NonEmptyReadonlyArray `
30- - ** Use TypeScript's type system** to enforce immutability at compile time
31- - ** Use Type system for runtime validation** - never use assertions for input validation
3229
3330``` ts
3431interface Example {
@@ -75,7 +72,7 @@ export const createUser = (data: UserData): User => {
7572};
7673````
7774
78- ## Error Handling with Result
75+ ## Error handling with Result
7976
8077- Use ` Result<T, E> ` for business/domain errors in public APIs
8178- Keep implementation-specific errors internal to dependencies
@@ -112,7 +109,7 @@ export interface Storage {
112109}
113110```
114111
115- ### Result Patterns
112+ ### Result patterns
116113
117114- Use ` Result<void, E> ` for operations that don't return values
118115- Use ` trySync ` for wrapping synchronous unsafe code
@@ -132,7 +129,7 @@ for (const op of operations) {
132129}
133130```
134131
135- ## Type System Patterns
132+ ## Evolu Type
136133
137134- ** Use Type for validation/parsing** - leverage Evolu's Type system for runtime validation
138135- ** Define typed errors** - use interfaces extending ` TypeError<Name> `
@@ -165,13 +162,6 @@ const formatCurrencyCodeError = createTypeErrorFormatter<CurrencyCodeError>(
165162);
166163```
167164
168- ### Type System Guidelines
169-
170- - ** Use readonly for Type definitions** - all Type interfaces should use readonly
171- - ** Create error formatters** - use ` createTypeErrorFormatter ` for consistent error messages
172- - ** Use base, brand, transform factories** - follow established patterns for Type creation
173- - ** Leverage type inference** - use ` InferType ` , ` InferError ` , etc. for type extraction
174-
175165## Assertions
176166
177167- Use assertions for conditions logically guaranteed but not statically known by TypeScript
@@ -181,22 +171,17 @@ const formatCurrencyCodeError = createTypeErrorFormatter<CurrencyCodeError>(
181171``` ts
182172import { assert , assertNonEmptyArray } from " ./Assert.js" ;
183173
184- // ✅ Good example
185174const length = buffer .getLength ();
186175assert (NonNegativeInt .is (length ), " buffer length should be non-negative" );
187176
188- // ✅ Good - Non-empty array assertion
189177assertNonEmptyArray (items , " Expected items to process" );
190-
191- // ❌ Avoid - Use Type validation instead
192- // Don't use assert for runtime input validation
193178```
194179
195- ## Dependency Injection Pattern
180+ ## Dependency injection
196181
197182Follow Evolu's convention-based DI approach without frameworks:
198183
199- ### 1. Define Dependencies as Interfaces
184+ ### 1. Define dependencies as interfaces
200185
201186``` ts
202187export interface Time {
@@ -208,7 +193,7 @@ export interface TimeDep {
208193}
209194```
210195
211- ### 2. Use Currying for Functions with Dependencies
196+ ### 2. Use currying for functions with dependencies
212197
213198``` ts
214199const timeUntilEvent =
@@ -219,15 +204,15 @@ const timeUntilEvent =
219204 };
220205```
221206
222- ### 3. Create Factory Functions
207+ ### 3. Create factory functions
223208
224209``` ts
225210export const createTime = (): Time => ({
226211 now : () => Date .now (),
227212});
228213```
229214
230- ### 4. Composition Root Pattern
215+ ### 4. Composition root pattern
231216
232217``` ts
233218const deps: TimeDep & Partial <LoggerDep > = {
@@ -243,7 +228,7 @@ const deps: TimeDep & Partial<LoggerDep> = {
243228- ** Over-providing is OK** - passing extra deps is fine, over-depending is not
244229- ** Use Partial<>** for optional dependencies
245230- ** No global static instances** - avoid service locator pattern
246- - ** No generics in dependency interfaces** - keep them simple and implementation-agnostic
231+ - ** No generics in dependency interfaces** - keep them implementation-agnostic
247232
248233## Testing
249234
@@ -257,10 +242,6 @@ const deps: TimeDep & Partial<LoggerDep> = {
257242- Never rely on global state
258243- Use assertions in tests for conditions that should never fail
259244
260- ## Monorepo TypeScript Issues
261-
262- ** ESLint "Unsafe..." errors after changes** - In a monorepo, ESLint may show "Unsafe call", "Unsafe member access", or "Unsafe assignment" errors after modifying packages that other packages depend on. These errors should be ignored. Solution: use VS Code's "Developer: Reload Window" command (Cmd+Shift+P)
263-
264245``` ts
265246import { testCreateId , testTime , testOwner } from " ../_deps.js" ;
266247
@@ -275,11 +256,11 @@ test("timeUntilEvent calculates correctly", () => {
275256});
276257```
277258
278- ## Project Verification
259+ ## Monorepo TypeScript issues
279260
280- - ** Run ` pnpm verify ` after significant changes** – This command runs build, lint, monorepo lint, typedoc, and all tests to ensure the project is healthy after major updates. It is the recommended way to check the integrity of the entire monorepo.
261+ ** ESLint "Unsafe..." errors after changes** - In a monorepo, ESLint may show "Unsafe call", "Unsafe member access", or "Unsafe assignment" errors after modifying packages that other packages depend on. These errors should be ignored. Solution: use VS Code's "Developer: Reload Window" command (Cmd+Shift+P)
281262
282- ## Git Commit Messages
263+ ## Git commit messages
283264
284265- ** Write as sentences** - use proper sentence case without trailing period
285266- ** No prefixes** - avoid ` feat: ` , ` fix: ` , ` feature: ` etc.
0 commit comments