Skip to content

Commit 2bc32dd

Browse files
committed
Merge upstream to dev
2 parents 03f7f9a + e3fbeae commit 2bc32dd

117 files changed

Lines changed: 11526 additions & 7566 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/angry-kings-obey.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"@evolu/react-native": patch
3+
"@evolu/common": patch
4+
"@evolu/web": patch
5+
"@evolu/nodejs": patch
6+
"@evolu/react": patch
7+
"@evolu/react-web": patch
8+
---
9+
10+
Native Base64 ID encoding
11+
12+
Breaking change: Id is encoded into BinaryId via new native algorithm (uses platform Base64 with polyfill). Removed custom Base64Url256 micro-optimization; table & column names now plain strings. Simpler, smaller, more standard code.

.changeset/clever-forks-read.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
"@evolu/react-native": patch
3+
"@evolu/common": patch
4+
"@evolu/svelte": patch
5+
"@evolu/web": patch
6+
---
7+
8+
Fix and improve relay broadcasting
9+
10+
- Enable relay broadcasting for all messages, not just non-sync messages. The previous logic was only working due to a bug and we've normalized this behavior.
11+
- Remove TimestampDuplicateNodeError and related NodeId collision checks from receiveTimestamp function.
12+
- Add comprehensive documentation explaining relay broadcasting behavior during migration scenarios and why duplicate messages are safe due to applyMessages idempotency.
13+
- Update NodeId documentation.

.changeset/common-ads-serve.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@evolu/react-native": patch
3+
"@evolu/common": patch
4+
"@evolu/web": patch
5+
---
6+
7+
Replace Mnemonic with OwnerSecret
8+
9+
OwnerSecret is the fundamental cryptographic primitive from which all owner keys are derived via SLIP-21. Mnemonic is just a representation of this underlying entropy. This change makes the type system more accurate and the cryptographic relationships clearer.

.changeset/tricky-wings-join.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
"@evolu/react-native": patch
3+
"@evolu/common": patch
4+
"@evolu/web": patch
5+
---
6+
7+
# Transport-Based Configuration System
8+
9+
# Transport-Based Configuration System
10+
11+
**BREAKING CHANGE**: Replaced `syncUrl` with flexible `transport` property supporting single transport or array of transports for multiple sync endpoints.
12+
13+
## What Changed
14+
15+
- **Removed** `syncUrl` property from Evolu config
16+
- **Added** `transport` property accepting a single `Transport` object or array of `Transport` objects
17+
- **Added** `Transport` type union with initial WebSocket support
18+
- **Updated** sync system to support Nostr-style relay pools with simultaneous connections
19+
- **Updated** all examples and documentation to use new transport configuration
20+
21+
## Migration Guide
22+
23+
**Before:**
24+
25+
```ts
26+
const evolu = createEvolu(deps)(Schema, {
27+
syncUrl: "wss://relay.example.com",
28+
});
29+
```
30+
31+
**After (single transport):**
32+
33+
```ts
34+
const evolu = createEvolu(deps)(Schema, {
35+
transport: { type: "WebSocket", url: "wss://relay.example.com" },
36+
});
37+
```
38+
39+
**After (multiple transports):**
40+
41+
```ts
42+
const evolu = createEvolu(deps)(Schema, {
43+
transport: [
44+
{ type: "WebSocket", url: "wss://relay1.example.com" },
45+
{ type: "WebSocket", url: "wss://relay2.example.com" },
46+
],
47+
});
48+
```
49+
50+
## Benefits
51+
52+
- **Single or multiple relay support**: Use one transport for simplicity or multiple for redundancy
53+
- **Intuitive API**: Singular property name that accepts both single item and array
54+
- **Future extensibility**: Ready for upcoming transport types (FetchRelay, Bluetooth, LocalNetwork)
55+
- **Nostr-style resilience**: Messages broadcast to all connected relays simultaneously when using arrays
56+
- **Type safety**: Full TypeScript support for transport configurations
57+
58+
## Future Transport Types
59+
60+
The new system is designed to support upcoming transport types:
61+
62+
- `FetchRelay`: HTTP-based polling for environments without WebSocket support
63+
- `Bluetooth`: P2P sync for offline collaboration
64+
- `LocalNetwork`: LAN/mesh sync for local networks
65+
66+
## Technical Details
67+
68+
- Single transports are automatically normalized to arrays internally
69+
- CRDT messages are sent to all connected transports simultaneously
70+
- Duplicate message handling relies on CRDT idempotency (no deduplication needed)
71+
- WebSocket connections auto-reconnect independently
72+
- Backwards compatibility removed (preview version breaking change)
73+
74+
This change provides an intuitive API that scales from simple single-transport setups to complex multi-transport configurations, positioning Evolu for a more resilient, multi-transport future.

.github/instructions/copilot.instructions.md renamed to .github/copilot-instructions.md

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,44 @@ interface Example {
3737
}
3838
```
3939

40+
## Documentation & JSDoc
41+
42+
- **Avoid `@param` and `@return` tags** - TypeScript provides type information, focus on describing the function's purpose
43+
- **Use `### Example` instead of `@example`** - for better markdown rendering and consistency
44+
- **Write clear descriptions** - explain what the function does, not how to use it
45+
46+
````ts
47+
// ✅ Good
48+
/**
49+
* Creates a new user with the provided data.
50+
*
51+
* ### Example
52+
*
53+
* ```ts
54+
* const user = createUser({ name: "John", email: "john@example.com" });
55+
* ```
56+
*/
57+
export const createUser = (data: UserData): User => {
58+
// implementation
59+
};
60+
61+
// ❌ Avoid
62+
/**
63+
* Creates a new user with the provided data.
64+
*
65+
* @example
66+
* ```ts
67+
* const user = createUser({ name: "John", email: "john@example.com" });
68+
* ```;
69+
*
70+
* @param data The user data to create the user with
71+
* @returns The created user
72+
*/
73+
export const createUser = (data: UserData): User => {
74+
// implementation
75+
};
76+
````
77+
4078
## Error Handling with Result
4179

4280
- Use `Result<T, E>` for business/domain errors in public APIs
@@ -150,9 +188,6 @@ assert(NonNegativeInt.is(length), "buffer length should be non-negative");
150188
// ✅ Good - Non-empty array assertion
151189
assertNonEmptyArray(items, "Expected items to process");
152190

153-
// ✅ Good - Catch block for promises that shouldn't error
154-
Promise.resolve().catch((e) => assertNoErrorInCatch("WebSocket retry", e));
155-
156191
// ❌ Avoid - Use Type validation instead
157192
// Don't use assert for runtime input validation
158193
```
@@ -214,21 +249,44 @@ const deps: TimeDep & Partial<LoggerDep> = {
214249

215250
- **Run tests using pnpm** - use `pnpm test` from the project root to run all tests
216251
- **Run specific test files** - use `pnpm test --filter @evolu/package-name -- test-file-pattern` from project root (e.g., `pnpm test --filter @evolu/common -- Protocol`)
252+
- **Check compilation** - use `pnpm build` to check TypeScript compilation across all packages
253+
- **Run linting** - use `pnpm lint` to check code style and linting rules
254+
- **Leverage `_deps.ts`** - use existing test utilities and mocks from `packages/common/test/_deps.ts` (e.g., `testCreateId`, `testTime`, `testOwner`)
217255
- Mock dependencies using the same interfaces
218256
- Create test factories (e.g., `createTestTime`)
219257
- Never rely on global state
220258
- Use assertions in tests for conditions that should never fail
221259

222260
```ts
261+
import { testCreateId, testTime, testOwner } from "../_deps.js";
262+
223263
const createTestTime = (): Time => ({
224264
now: () => 1234567890, // Fixed time for testing
225265
});
226266

227267
test("timeUntilEvent calculates correctly", () => {
228-
const deps = { time: createTestTime() };
268+
const deps = { time: testTime }; // Use from _deps.ts
229269
const result = timeUntilEvent(deps)(1234567990);
230270
assert(result === 100, "Expected result to be 100");
231271
});
232272
```
233273

274+
## Git Commit Messages
275+
276+
- **Write as sentences** - use proper sentence case without trailing period
277+
- **No prefixes** - avoid `feat:`, `fix:`, `feature:` etc.
278+
- **Be descriptive** - explain what the change does
279+
280+
```bash
281+
# ✅ Good
282+
Add support for custom error formatters
283+
Fix memory leak in WebSocket reconnection
284+
Update schema validation to handle edge cases
285+
286+
# ❌ Avoid
287+
feat: add support for custom error formatters
288+
fix: memory leak in websocket reconnection
289+
Update schema validation to handle edge cases.
290+
```
291+
234292
When suggesting code changes, ensure they follow these patterns and conventions.

0 commit comments

Comments
 (0)