Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
13fab62
Clarify ESLint 'Unsafe...' troubleshooting
steida Feb 3, 2026
046d374
Migrate to monorepo Vitest config
steida Feb 3, 2026
9e442be
Expand TDD guidance and add Vitest examples
steida Feb 3, 2026
60ac61b
Update TreeShaking.test.ts
steida Feb 3, 2026
dd0b8a6
Use 'observability' term in error comment
steida Feb 3, 2026
205bc8c
Rename vitest config to .mts and add scripts tests
steida Feb 3, 2026
c02e13d
Add createQueryBuilder, replace createQuery usage
steida Feb 3, 2026
969a82d
chore: format
miccy Feb 4, 2026
f6ed047
update: minors
miccy Feb 4, 2026
5445ac2
fix: missing dependencies and verified build
miccy Feb 4, 2026
1fe6836
chore: Update Biome to version 2.3.14 and reflect this change in docu…
miccy Feb 4, 2026
07f0836
Update packages/common/src/local-first/Evolu.ts
miccy Feb 4, 2026
f05c64a
Update packages/common/src/local-first/Evolu.ts
miccy Feb 4, 2026
815c80e
Revert EvoluMinimalExample.tsx to working implementation (#24)
Copilot Feb 5, 2026
d952c70
Fix CI: generate docs before typedoc-plugin tests (#23)
Copilot Feb 5, 2026
923ab54
Merge branch 'main' into merge/common-v8-04-02-2026
miccy Feb 5, 2026
dcec9a6
Fix CI: Exclude typedoc test from regular test run (#27)
Copilot Feb 5, 2026
3e8c0db
fix: Correct `Uint8Array` type signature in `exportDatabase` and rela…
miccy Feb 5, 2026
12427a0
chore: Update Angular and Svelte dependencies and enable documentatio…
miccy Feb 5, 2026
e78be8c
refactor: improve schema difference calculation for columns and use a…
miccy Feb 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ai/knowledge/02-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ bunx <package> # Execute packages

### Development
- **Turbo** 2.8.1 - Monorepo build orchestration
- **Biome** 2.3.13 - Linting and formatting
- **Biome** 2.3.14 - Linting and formatting
- **Vitest** ^4.0.18 - Testing framework
- **TypeDoc** ^0.28.16 - API documentation

Expand Down
2 changes: 1 addition & 1 deletion .ai/tasks/archive/cherry-pick-common-v8-SUPERSEDED.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Migrating changes from `upstream/common-v8` to our fork, while preserving our st
| Tool | Before | After | Status |
| ------- | ------ | ------ | ---------------- |
| Bun | 1.3.6 | 1.3.8 | ✅ Done |
| Biome | 2.3.13 | 2.3.13 | ✅ Current |
| Biome | 2.3.14 | 2.3.14 | ✅ Current |
| Turbo | 2.8.1 | 2.8.1 | ✅ Current |
| Node.js | >=24 | >=24 | ✅ LTS 24 correct |

Expand Down
16 changes: 16 additions & 0 deletions .changeset/create-query-builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@evolu/common": major
---

Replaced `evolu.createQuery` with standalone `createQueryBuilder` function

Queries are now created using a standalone `createQueryBuilder` function instead of `evolu.createQuery` method. This enables query creation without an Evolu instance, improving code organization and enabling schema-first development.

```ts
// Before
const todosQuery = evolu.createQuery((db) => db.selectFrom("todo").selectAll());

// After
const createQuery = createQueryBuilder(Schema);
const todosQuery = createQuery((db) => db.selectFrom("todo").selectAll());
```
79 changes: 62 additions & 17 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,6 @@ apps/

Follow these specific conventions and patterns:

## Test-driven development

- Write a failing test before implementing a new feature or fixing a bug
- Keep test code cleaner than production code — good tests let you refactor production code; nothing protects messy tests

## Code organization & imports

- **Use named imports only** - avoid default exports and namespace imports
Expand Down Expand Up @@ -498,6 +493,68 @@ const processTask: Task<void, ParseError | TimeoutError> = async (run) => {
const result = await sleep("1s")(run);
```

## Test-driven development

- Write a failing test before implementing a new feature or fixing a bug
- Run tests using the `runTests` tool with the test file path
- Test files are in `packages/*/test/*.test.ts`
- Use `testNames` parameter to run specific tests by name
- Run related tests after making code changes to verify correctness

### Test structure

- Use `describe` blocks to group related tests by feature or function
- Use `test` or `it` for individual test cases (both are equivalent)
- Test names should be descriptive phrases: `"returns true for non-empty array"`
- Use nested `describe` for sub-categories

```ts
import { describe, expect, expectTypeOf, test } from "vitest";

describe("arrayFrom", () => {
test("creates array from iterable", () => {
const result = arrayFrom(new Set([1, 2, 3]));
expect(result).toEqual([1, 2, 3]);
});

test("returns input unchanged if already an array", () => {
const input = [1, 2, 3];
const result = arrayFrom(input);
expect(result).toBe(input);
});
});
```

### Type testing

Use `expectTypeOf` from Vitest for compile-time type assertions:

```ts
import { expectTypeOf } from "vitest";

test("returns readonly array", () => {
const result = arrayFrom(2, () => "x");
expectTypeOf(result).toEqualTypeOf<ReadonlyArray<string>>();
});

test("NonEmptyArray requires at least one element", () => {
const _valid: NonEmptyArray<number> = [1, 2, 3];
// @ts-expect-error - empty array is not a valid NonEmptyArray
const _invalid: NonEmptyArray<number> = [];
});
```

### Inline snapshots

Use `toMatchInlineSnapshot` for readable test output directly in the test file:

```ts
test("Buffer", () => {
const buffer = createBuffer([1, 2, 3]);
expect(buffer.unwrap()).toMatchInlineSnapshot(`uint8:[1,2,3]`);
});
```

## Testing

- **Create deps per test** - use `testCreateDeps()` from `@evolu/common` for test isolation
Expand Down Expand Up @@ -564,18 +621,6 @@ bun run test --filter @evolu/common -- -t "yields and returns ok"
- **No prefixes** - avoid `feat:`, `fix:`, `feature:` etc.
- **Be descriptive** - explain what the change does

```bash
# Good
Add support for custom error formatters
Fix memory leak in WebSocket reconnection
Update schema validation to handle edge cases

# Avoid
feat: add support for custom error formatters
fix: memory leak in websocket reconnection
Update schema validation to handle edge cases.
```

## Changesets

- **Write in past tense** - describe what was done, not what will be done
Expand Down
28 changes: 14 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@

## 📊 Quick Context

| Aspect | Value |
|--------|-------|
| Package Manager | Bun 1.3.8 |
| Node.js | >=24.0.0 |
| Linter/Formatter | Biome 2.3.13 |
| Test Framework | Vitest |
| Upstream | evoluhq/evolu |
| Aspect | Value |
| ---------------- | ------------- |
| Package Manager | Bun 1.3.8 |
| Node.js | >=24.0.0 |
| Linter/Formatter | Biome 2.3.14 |
| Test Framework | Vitest |
| Upstream | evoluhq/evolu |

## 🗂️ Repository Structure

Expand Down Expand Up @@ -92,13 +92,13 @@ bun run verify

## 📍 Related Resources

| Resource | Location |
|----------|----------|
| Issues | `../knowledge/05-Issues/` |
| Roadmap | `../knowledge/05-Issues/roadmap.md` |
| Architecture | `../knowledge/02-Architecture/` |
| Bench Suite | `../bench-suite/` (sibling repo) |
| Upstream | https://github.com/evoluhq/evolu |
| Resource | Location |
| ------------ | ----------------------------------- |
| Issues | `../knowledge/05-Issues/` |
| Roadmap | `../knowledge/05-Issues/roadmap.md` |
| Architecture | `../knowledge/02-Architecture/` |
| Bench Suite | `../bench-suite/` (sibling repo) |
| Upstream | https://github.com/evoluhq/evolu |

## 🤖 For AI Agents

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Linting
Testing

- `bun run test` - Run tests
- [Vitest VS Code extension](https://github.com/vitest-dev/vscode)

Release

Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"@evolu/tsconfig": "workspace:*",
"@types/mdx": "^2.0.13",
"@types/node": "^24.10.9",
"@types/react": "~19.2.10",
"@types/react": "~19.2.11",
"@types/react-dom": "~19.2.3",
"@types/react-highlight-words": "^0.20.1",
"@types/rss": "^0.0.32",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
createEvolu,
createFormatTypeError,
createObjectURL,
createQueryBuilder,
FiniteNumber,
id,
idToIdBytes,
Expand Down Expand Up @@ -99,6 +100,8 @@ const Schema = {
},
};

const createQuery = createQueryBuilder(Schema);

const deps = createEvoluDeps();

const evolu = createEvolu(deps)(Schema, {
Expand Down Expand Up @@ -212,7 +215,7 @@ const App: FC = () => {
);
};

const projectsWithTodosQuery = evolu.createQuery(
const projectsWithTodosQuery = createQuery(
(db) =>
db
.selectFrom("project")
Expand Down Expand Up @@ -409,7 +412,7 @@ const HomeTabProjectSectionTodoItem: FC<{

// Demonstrate history tracking. Evolu automatically tracks all changes
// in the evolu_history table, making it easy to build audit logs or undo features.
const titleHistoryQuery = evolu.createQuery((db) =>
const titleHistoryQuery = createQuery((db) =>
db
.selectFrom("evolu_history")
.select(["value", "timestamp"])
Expand Down Expand Up @@ -503,7 +506,7 @@ const HomeTabProjectSectionTodoItem: FC<{
);
};

const projectsQuery = evolu.createQuery((db) =>
const projectsQuery = createQuery((db) =>
db
.selectFrom("project")
.select(["id", "name", "fooJson"])
Expand Down Expand Up @@ -716,7 +719,7 @@ const AccountTab: FC = () => {
);
};

const deletedProjectsQuery = evolu.createQuery((db) =>
const deletedProjectsQuery = createQuery((db) =>
db
.selectFrom("project")
.select(["id", "name", "updatedAt"])
Expand All @@ -728,7 +731,7 @@ const deletedProjectsQuery = evolu.createQuery((db) =>

type DeletedProjectsRow = typeof deletedProjectsQuery.Row;

const deletedTodosQuery = evolu.createQuery((db) =>
const deletedTodosQuery = createQuery((db) =>
db
.selectFrom("todo")
.select(["id", "title", "isCompleted", "projectId", "updatedAt"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const Schema = {

const deps = createEvoluDeps();

// Create a typed query builder from the schema
const createQuery = Evolu.createQueryBuilder(Schema);

deps.evoluError.subscribe(() => {
const error = deps.evoluError.get();
if (!error) return;
Expand Down Expand Up @@ -73,7 +76,7 @@ export const EvoluMultitenantExample: FC = () => (
);

// Evolu uses Kysely for type-safe SQL (https://kysely.dev/).
const todosQuery = evolu.createQuery((db) =>
const todosQuery = createQuery((db) =>
db
// Type-safe SQL: try autocomplete for table and column names.
.selectFrom("todo")
Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
"$schema": "https://biomejs.dev/schemas/2.3.14/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand Down
Loading