Skip to content

Commit 7a14faa

Browse files
authored
Merge branch 'dev' into snyk-fix-b658d13147eb97b3e73c0a339ef562f8
Signed-off-by: Miccy <code@miccy.dev>
2 parents 17b35c2 + b0d6935 commit 7a14faa

167 files changed

Lines changed: 15297 additions & 9569 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.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
"@evolu/common": major
3+
---
4+
5+
Refactored the Array module with breaking changes, better naming, and new helpers.
6+
7+
### Breaking Changes
8+
9+
**Removed `isNonEmptyReadonlyArray`** — use `isNonEmptyArray` instead. The function now handles both mutable and readonly arrays via overloads:
10+
11+
```ts
12+
// Before
13+
if (isNonEmptyReadonlyArray(readonlyArr)) { ... }
14+
if (isNonEmptyArray(mutableArr)) { ... }
15+
16+
// After — one function for both
17+
if (isNonEmptyArray(readonlyArr)) { ... }
18+
if (isNonEmptyArray(mutableArr)) { ... }
19+
```
20+
21+
**Renamed mutation functions** for consistency with the `...Array` suffix pattern:
22+
23+
- `shiftArray``shiftFromArray`
24+
- `popArray``popFromArray`
25+
26+
### New Functions
27+
28+
- **`flatMapArray`** — maps each element to an array and flattens the result, preserving non-empty type when applicable
29+
- **`concatArrays`** — concatenates two arrays, returning non-empty when at least one input is non-empty
30+
- **`sortArray`** — returns a new sorted array (wraps `toSorted`), preserving non-empty type
31+
- **`reverseArray`** — returns a new reversed array (wraps `toReversed`), preserving non-empty type
32+
- **`spliceArray`** — returns a new array with elements removed/replaced (wraps `toSpliced`)
33+
34+
### Migration
35+
36+
```ts
37+
// isNonEmptyReadonlyArray → isNonEmptyArray
38+
-import { isNonEmptyReadonlyArray } from "@evolu/common";
39+
+import { isNonEmptyArray } from "@evolu/common";
40+
41+
// shiftArray → shiftFromArray
42+
-import { shiftArray } from "@evolu/common";
43+
+import { shiftFromArray } from "@evolu/common";
44+
45+
// popArray → popFromArray
46+
-import { popArray } from "@evolu/common";
47+
+import { popFromArray } from "@evolu/common";
48+
```

.changeset/gentle-pumas-eat.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"@evolu/react-native": major
3+
"@evolu/react-web": major
4+
"@evolu/common": major
5+
"@evolu/nodejs": major
6+
"@evolu/react": major
7+
"@evolu/vue": major
8+
"@evolu/web": major
9+
"@evolu/relay": major
10+
---
11+
12+
Updated minimum Node.js version from 22 to 24 (current LTS)

.changeset/global-error-scope.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"@evolu/common": minor
3+
"@evolu/web": minor
4+
"@evolu/nodejs": minor
5+
---
6+
7+
Added `GlobalErrorScope` interface for platform-agnostic global error handling
8+
9+
- Added `GlobalErrorScope` interface representing execution contexts that capture uncaught errors and unhandled promise rejections
10+
- Added `handleGlobalError` helper to forward errors to scope callbacks
11+
- Added `createGlobalErrorScope` for browser windows in `@evolu/web`
12+
- Added `createGlobalErrorScope` for Node.js processes in `@evolu/nodejs`

.changeset/lazy-rename.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@evolu/common": major
3+
---
4+
5+
Renamed `LazyValue<T>` to `Lazy<T>` for brevity

.changeset/lovely-aliens-camp.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
"@evolu/common": minor
3+
---
4+
5+
Added `createObjectURL` helper for safe, disposable `URL.createObjectURL` usage using JS Resource Management so the URL is disposed automatically when the scope ends.
6+
7+
Example:
8+
9+
```ts
10+
const handleDownloadDatabaseClick = () => {
11+
void evolu.exportDatabase().then((data) => {
12+
using objectUrl = createObjectURL(
13+
new Blob([data], { type: "application/x-sqlite3" }),
14+
);
15+
16+
const link = document.createElement("a");
17+
link.href = objectUrl.url;
18+
link.download = `${evolu.name}.sqlite3`;
19+
link.click();
20+
});
21+
};
22+
```

.changeset/red-wings-itch.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@evolu/react-native": major
3+
"@evolu/react-web": major
4+
"@evolu/common": major
5+
"@evolu/web": major
6+
---
7+
8+
- Merged `@evolu/common/local-first/Platform.ts` into `@evolu/common/Platform.ts`
9+
- Made `@evolu/react-web` re-export everything from `@evolu/web`, allowing React users to install only `@evolu/react-web`
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@evolu/common": major
3+
---
4+
5+
Changed `ok()` to return `Result<T, never>` and `err()` to return `Result<never, E>` for correct type inference.

.changeset/smart-refs-store.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@evolu/common": minor
3+
---
4+
5+
Added optional equality function to `Ref` and `ReadonlyStore` interface. `Ref.set` and `Ref.modify` now return `boolean` indicating whether state was updated. `Store` now uses `Ref` internally for state management.

.changeset/spotty-coats-sort.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@evolu/common": minor
3+
---
4+
5+
Added Resource Management polyfills
6+
7+
Provides `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, and `AsyncDisposableStack` for environments without native support (e.g., Safari). This enables the `using` and `await using` declarations for automatic resource cleanup.
8+
9+
Polyfills are installed automatically when importing `@evolu/common`.
10+
11+
See `Result.test.ts` for usage patterns combining `Result` with `using`, `DisposableStack`, and `AsyncDisposableStack`.

.changeset/tough-cats-fall.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
"@evolu/common": major
3+
"@evolu/web": major
4+
---
5+
6+
Replaced interface-based symmetric encryption with direct function-based API
7+
8+
### Breaking Changes
9+
10+
**Removed:**
11+
12+
- `SymmetricCrypto` interface
13+
- `SymmetricCryptoDep` interface
14+
- `createSymmetricCrypto()` factory function
15+
- `SymmetricCryptoDecryptError` error type
16+
17+
**Added:**
18+
19+
- `encryptWithXChaCha20Poly1305()` - Direct encryption function with explicit algorithm name
20+
- `decryptWithXChaCha20Poly1305()` - Direct decryption function
21+
- `XChaCha20Poly1305Ciphertext` - Branded type for ciphertext
22+
- `Entropy24` - Branded type for 24-byte nonces
23+
- `DecryptWithXChaCha20Poly1305Error` - Algorithm-specific error type
24+
- `xChaCha20Poly1305NonceLength` - Constant for nonce length (24)
25+
26+
### Migration Guide
27+
28+
**Before:**
29+
30+
```ts
31+
const symmetricCrypto = createSymmetricCrypto({ randomBytes });
32+
const { nonce, ciphertext } = symmetricCrypto.encrypt(plaintext, key);
33+
const result = symmetricCrypto.decrypt(ciphertext, key, nonce);
34+
```
35+
36+
**After:**
37+
38+
```ts
39+
const [ciphertext, nonce] = encryptWithXChaCha20Poly1305({ randomBytes })(
40+
plaintext,
41+
key,
42+
);
43+
const result = decryptWithXChaCha20Poly1305(ciphertext, nonce, key);
44+
```
45+
46+
**Error handling:**
47+
48+
```ts
49+
// Before
50+
if (!result.ok && result.error.type === "SymmetricCryptoDecryptError") { ... }
51+
52+
// After
53+
if (!result.ok && result.error.type === "DecryptWithXChaCha20Poly1305Error") { ... }
54+
```
55+
56+
**Dependency injection:**
57+
58+
```ts
59+
// Before
60+
interface Deps extends SymmetricCryptoDep { ... }
61+
62+
// After - only encrypt needs RandomBytesDep
63+
interface Deps extends RandomBytesDep { ... }
64+
```
65+
66+
### Rationale
67+
68+
This change improves API extensibility by using explicit function names instead of a generic interface. Adding new encryption algorithms (e.g., `encryptWithAES256GCM`) is now straightforward without breaking existing code.

0 commit comments

Comments
 (0)