Releases: evoluhq/evolu
@evolu/web@3.0.0-next.1
Patch Changes
-
c1f97ff: Fixed the SharedWorker fallback on older Chrome Android versions without native SharedWorker support.
Apps can pass
onSharedWorkerUnsupportedto show a custom message when another fallback tab is already running:createEvoluDeps({ onSharedWorkerUnsupported: () => { alert( "This browser supports Evolu in one tab only. Close this tab and use the already open tab.", ); }, });
-
63dce92: Updated Task and Run dependency injection API.
Removed
Run.addDepsbecause everyRunnow owns its deps. The new API is more flexible and better matches sync Pure DI: deps are passed explicitly where a task is called, can replace existing deps when needed, and can be scoped to an owned disposableRunwithrun.create(deps).- Renamed
RunDepstoRunDefaultDepsto describe default Run dependencies more clearly. - Replaced
Run.addDepswith explicit dependency passing viarun(task, deps),run.orThrow(task, deps), andrun.create(deps). - Allowed explicit deps to override default
RunDefaultDepswhen needed.
- Renamed
@evolu/react-native@15.0.0-next.2
Patch Changes
-
63dce92: Updated Task and Run dependency injection API.
Removed
Run.addDepsbecause everyRunnow owns its deps. The new API is more flexible and better matches sync Pure DI: deps are passed explicitly where a task is called, can replace existing deps when needed, and can be scoped to an owned disposableRunwithrun.create(deps).- Renamed
RunDepstoRunDefaultDepsto describe default Run dependencies more clearly. - Replaced
Run.addDepswith explicit dependency passing viarun(task, deps),run.orThrow(task, deps), andrun.create(deps). - Allowed explicit deps to override default
RunDefaultDepswhen needed.
- Renamed
@evolu/nodejs@3.0.0-next.3
Patch Changes
-
63dce92: Updated Task and Run dependency injection API.
Removed
Run.addDepsbecause everyRunnow owns its deps. The new API is more flexible and better matches sync Pure DI: deps are passed explicitly where a task is called, can replace existing deps when needed, and can be scoped to an owned disposableRunwithrun.create(deps).- Renamed
RunDepstoRunDefaultDepsto describe default Run dependencies more clearly. - Replaced
Run.addDepswith explicit dependency passing viarun(task, deps),run.orThrow(task, deps), andrun.create(deps). - Allowed explicit deps to override default
RunDefaultDepswhen needed.
- Renamed
@evolu/common@8.0.0-next.5
Minor Changes
-
63dce92: Updated Task and Run dependency injection API.
Removed
Run.addDepsbecause everyRunnow owns its deps. The new API is more flexible and better matches sync Pure DI: deps are passed explicitly where a task is called, can replace existing deps when needed, and can be scoped to an owned disposableRunwithrun.create(deps).- Renamed
RunDepstoRunDefaultDepsto describe default Run dependencies more clearly. - Replaced
Run.addDepswith explicit dependency passing viarun(task, deps),run.orThrow(task, deps), andrun.create(deps). - Allowed explicit deps to override default
RunDefaultDepswhen needed.
- Renamed
Patch Changes
- 0fbb5e7: Kept SharedWorker Evolu tenants alive briefly after the last instance was released so immediate dispose-and-recreate flows continue using the same local-first runtime.
@evolu/react-native@15.0.0-next.1
Minor Changes
-
ef7f242: Added Web Locks helpers in
@evolu/common:LockManagerDep,
testCreateLockManager, andacquireLeaderLock.testCreateLockManageris a native-backed test helper because nativeLockManagercannot be instantiated per test. It isolates lock usage per instance with internal namespacing while preserving visible lock names and native Web Locks behavior in tests.acquireLeaderLockacquires an exclusive leader-election lease for a name and returns an async-disposable handle that holds leadership until disposed.Added a React Native
lockManagerponyfill in@evolu/react-nativebecause React Native does not support Web Locks yet.
@evolu/common@8.0.0-next.4
Minor Changes
-
ef7f242: Added Web Locks helpers in
@evolu/common:LockManagerDep,
testCreateLockManager, andacquireLeaderLock.testCreateLockManageris a native-backed test helper because nativeLockManagercannot be instantiated per test. It isolates lock usage per instance with internal namespacing while preserving visible lock names and native Web Locks behavior in tests.acquireLeaderLockacquires an exclusive leader-election lease for a name and returns an async-disposable handle that holds leadership until disposed.Added a React Native
lockManagerponyfill in@evolu/react-nativebecause React Native does not support Web Locks yet.
Patch Changes
-
a70d933: Improved Schedule timing safety and validation.
Schedule now:
- Saturates computed delays to valid
Millisvalues instead of throwing on overflow. - Handles backwards-clock elapsed deltas without producing invalid branded values.
- Validates numeric Schedule options.
Also added:
saturateMillisin the Time module for converting numbers to validMillisvalues with overflow saturation.NonNegativeFiniteNumberin the Type module for validating non-negative finite numbers.
- Saturates computed delays to valid
@evolu/nodejs@3.0.0-next.2
Patch Changes
- 65c1fe6: Documented
createTimingSafeEqualin the Node.js crypto module.
@evolu/common@8.0.0-next.3
Patch Changes
- f7d505a: Fixed in-memory transferred message port lifetime so transferred ports stayed usable while ownership moved between wrappers during disposal and re-creation.
@evolu/common@8.0.0-next.2
Patch Changes
- b096543: Added test coverage proving that
createSlip21normalizes numeric path elements to strings.
@evolu/web@3.0.0-next.0
Major Changes
-
5a4d172: Updated minimum Node.js version from 22 to 24 (current LTS)
-
0528425: - Merged
@evolu/common/local-first/Platform.tsinto@evolu/common/Platform.ts- Made
@evolu/react-webre-export everything from@evolu/web, allowing React users to install only@evolu/react-web
- Made
-
2abf93d: Refactored SQLite integration to use Task and throw-first semantics
- Changed
createSqlitetoTask<Sqlite, never, CreateSqliteDriverDep> - Changed
CreateSqliteDrivertoTask<SqliteDriver> - Removed
SqliteErrorfrom SQLite driver/task APIs - Changed
Sqlite.execto returnSqliteExecResultdirectly (noResult<..., SqliteError>) - Changed
Sqlite.transactionto support callbacks returning eitherResult<T, E>orvoid(noSqliteErrorin the error channel) - Changed
Sqlite.exportto returnUint8Arraydirectly (noResult<..., SqliteError>) - Simplified
SqliteDriver.execby removing theisMutationparameter, so the driver determines read vs write internally - Replaced
options.memoryandoptions.encryptionKeywith a discriminatedoptions.modefield ("memory"|"encrypted") - Updated Expo and op-sqlite drivers to match the new API
- Added SQLite schema metadata primitives (
SqliteSchema,SqliteIndex,eqSqliteIndex,getSqliteSchema,getSqliteSnapshot) - Added
testSetupSqlitehelper for SQLite tests
Why
SqliteErrorwas removed:- In Evolu, SQLite runs in-process. Failures are infrastructure-level and unrecoverable at the call site.
- Wrapping these failures as
Resultvalues did not create meaningful recovery paths; callers still had to fail. - The correct behavior is to let such failures throw and surface them through platform
createRunglobal handlers (web, nodejs, react-native), which report uncaught errors via Evoluconsole.error. - Evolu also propagates
console.errorentries through its messaging layer into the sharedevoluErrorglobal store, so app-level error subscriptions still receive these failures.
Boundary handling:
- At protocol boundaries (for example Protocol ↔ Storage), error handling remains explicit.
- Since storage implementations may throw, boundary code uses
try/catch, logs withconsole.error(error), and returns protocol-level outcomes. - Protocol handles all thrown errors as boundary concerns, without coupling to SQLite-specific error types.
- Changed
-
953c1fb: Replaced interface-based symmetric encryption with direct function-based API
Breaking Changes
Removed:
SymmetricCryptointerfaceSymmetricCryptoDepinterfacecreateSymmetricCrypto()factory functionSymmetricCryptoDecryptErrorerror type
Added:
encryptWithXChaCha20Poly1305()- Direct encryption function with explicit algorithm namedecryptWithXChaCha20Poly1305()- Direct decryption functionXChaCha20Poly1305Ciphertext- Branded type for ciphertextEntropy24- Branded type for 24-byte noncesDecryptWithXChaCha20Poly1305Error- Algorithm-specific error typexChaCha20Poly1305NonceLength- Constant for nonce length (24)
Migration Guide
Before:
const symmetricCrypto = createSymmetricCrypto({ randomBytes }); const { nonce, ciphertext } = symmetricCrypto.encrypt(plaintext, key); const result = symmetricCrypto.decrypt(ciphertext, key, nonce);
After:
const [ciphertext, nonce] = encryptWithXChaCha20Poly1305({ randomBytes })( plaintext, key, ); const result = decryptWithXChaCha20Poly1305(ciphertext, nonce, key);
Error handling:
// Before if (!result.ok && result.error.type === "SymmetricCryptoDecryptError") { ... } // After if (!result.ok && result.error.type === "DecryptWithXChaCha20Poly1305Error") { ... }
Dependency injection:
// Before interface Deps extends SymmetricCryptoDep { ... } // After - only encrypt needs RandomBytesDep interface Deps extends RandomBytesDep { ... }
Rationale
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. -
4be336d: Refactored worker abstraction to support all platforms uniformly:
- Added platform-agnostic worker interfaces:
Worker<Input, Output>,SharedWorker<Input, Output>,MessagePort<Input, Output>,MessageChannel<Input, Output> - Added worker-side interfaces:
WorkerSelf<Input, Output>andSharedWorkerSelf<Input, Output>for typed workerselfwrappers - Changed
onMessagefrom a method to a property for consistency with Web APIs - Made all worker and message port interfaces
Disposablefor proper resource cleanup - Added default generic parameters (
Output = never) for simpler one-way communication patterns - Added complete web platform implementations:
createWorker,createSharedWorker,createMessageChannel,createWorkerSelf,createSharedWorkerSelf,createMessagePort - Added React Native polyfills for Workers and MessageChannel
- Added platform-agnostic worker interfaces:
Patch Changes
- Updated dependencies [6fc3bba]
- Updated dependencies [2f39c8e]
- Updated dependencies [98a4b6c]
- Updated dependencies [ce83b24]
- Updated dependencies [97f5314]
- Updated dependencies [5275b07]
- Updated dependencies [cd6b74d]
- Updated dependencies [5a4d172]
- Updated dependencies [87780a3]
- Updated dependencies [bfaa2ca]
- Updated dependencies [f0bbebb]
- Updated dependencies [332dfca]
- Updated dependencies [7da2364]
- Updated dependencies [6f1d6ea]
- Updated dependencies [0528425]
- Updated dependencies [5f97e83]
- Updated dependencies [7fe328d]
- Updated dependencies [3ba2a92]
- Updated dependencies [5720b0b]
- Updated dependencies [e948269]
- Updated dependencies [d1f817f]
- Updated dependencies [2abf93d]
- Updated dependencies [b956a5f]
- Updated dependencies [ece429b]
- Updated dependencies [d30b95a]
- Updated dependencies [953c1fb]
- Updated dependencies [9ba5442]
- Updated dependencies [3b74e48]
- Updated dependencies [c24ec2f]
- Updated dependencies [9373afa]
- Updated dependencies [4be336d]
- @evolu/common@8.0.0-next.0