Skip to content

Commit 097a3c0

Browse files
committed
Update copilot-instructions.md
1 parent 05528bc commit 097a3c0

1 file changed

Lines changed: 16 additions & 35 deletions

File tree

.github/copilot-instructions.md

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
---
2-
applyTo: "**/*.ts"
2+
applyTo: "**/*.{ts,tsx}"
33
---
44

5-
# Evolu Project Guidelines
5+
# Evolu project guidelines
66

77
You 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";
2423
export 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
3431
interface 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
182172
import { assert, assertNonEmptyArray } from "./Assert.js";
183173

184-
// ✅ Good example
185174
const length = buffer.getLength();
186175
assert(NonNegativeInt.is(length), "buffer length should be non-negative");
187176

188-
// ✅ Good - Non-empty array assertion
189177
assertNonEmptyArray(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

197182
Follow Evolu's convention-based DI approach without frameworks:
198183

199-
### 1. Define Dependencies as Interfaces
184+
### 1. Define dependencies as interfaces
200185

201186
```ts
202187
export 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
214199
const timeUntilEvent =
@@ -219,15 +204,15 @@ const timeUntilEvent =
219204
};
220205
```
221206

222-
### 3. Create Factory Functions
207+
### 3. Create factory functions
223208

224209
```ts
225210
export const createTime = (): Time => ({
226211
now: () => Date.now(),
227212
});
228213
```
229214

230-
### 4. Composition Root Pattern
215+
### 4. Composition root pattern
231216

232217
```ts
233218
const 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
265246
import { 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

Comments
 (0)