-
Notifications
You must be signed in to change notification settings - Fork 0
PR: Merge upstream Common v8 branch plus my fixes #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
469d4d1
11af2dc
bba73d6
87b32fe
76babe6
6b2ef92
ad353f0
2c4fe0a
ffcffb4
88dabe9
f46f25c
45dae12
34669e4
23402c1
f05f23b
5a4d172
7268cde
b4858fa
d1f817f
7ef3b51
8f47597
e4d0d7b
f48fbbf
216a294
f4f0bbc
953c1fb
6ff8bb0
e01010a
7a8b588
b76322e
ebcaa53
e29928f
7557dc2
f0bbebb
240ac18
08347f0
ac90851
010145a
325e1d3
2564bb0
1f1819f
2aa786a
0528425
c9ac795
0df8692
ce37b58
df7bca1
0c886fb
4be336d
686bbfd
438116d
a8e0453
95dfad4
3108133
025632d
aebd8a5
6aac338
f9a53b1
0a60eb0
b7b4e07
fd35b0a
771a286
8abad4c
e948269
82893f0
2557e49
d8e9668
e823948
9ba5442
3b290f4
eefdea9
5194e24
ff7fc71
7e95a04
0df63a0
e78550a
74245dd
e8c4584
4ecc8a3
17b35c2
b65ddfe
b2814b9
f191332
780b6f0
7fe328d
5340043
f060169
f4aa7c2
db275f3
998bb39
14869f5
d0c10ab
a88e382
9373afa
e794858
cb5b351
7769158
9337864
eaa08aa
a9bd934
f3d2c2d
98a4b6c
67ab589
685cd9d
89b8e3c
91b971c
46fd0ea
6c64e85
fe1b09b
e4fafe6
44d2fe5
1009fd8
6704457
b0d6935
7a14faa
bac5663
08b454b
af67b9a
0936343
eaa5a43
b80fd81
a90b889
1811013
0fd4a28
835bee7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| --- | ||
| "@evolu/common": major | ||
| --- | ||
|
|
||
| Refactored the Array module with breaking changes, better naming, and new helpers. | ||
|
|
||
| ### Breaking Changes | ||
|
|
||
| **Removed `isNonEmptyReadonlyArray`** — use `isNonEmptyArray` instead. The function now handles both mutable and readonly arrays via overloads: | ||
|
|
||
| ```ts | ||
| // Before | ||
| if (isNonEmptyReadonlyArray(readonlyArr)) { ... } | ||
| if (isNonEmptyArray(mutableArr)) { ... } | ||
|
|
||
| // After — one function for both | ||
| if (isNonEmptyArray(readonlyArr)) { ... } | ||
| if (isNonEmptyArray(mutableArr)) { ... } | ||
| ``` | ||
|
|
||
| **Renamed mutation functions** for consistency with the `...Array` suffix pattern: | ||
|
|
||
| - `shiftArray` → `shiftFromArray` | ||
| - `popArray` → `popFromArray` | ||
|
|
||
| ### New Functions | ||
|
|
||
| - **`flatMapArray`** — maps each element to an array and flattens the result, preserving non-empty type when applicable | ||
| - **`concatArrays`** — concatenates two arrays, returning non-empty when at least one input is non-empty | ||
| - **`sortArray`** — returns a new sorted array (wraps `toSorted`), preserving non-empty type | ||
| - **`reverseArray`** — returns a new reversed array (wraps `toReversed`), preserving non-empty type | ||
| - **`spliceArray`** — returns a new array with elements removed/replaced (wraps `toSpliced`) | ||
|
|
||
| ### Migration | ||
|
|
||
| ```ts | ||
| // isNonEmptyReadonlyArray → isNonEmptyArray | ||
| -import { isNonEmptyReadonlyArray } from "@evolu/common"; | ||
| +import { isNonEmptyArray } from "@evolu/common"; | ||
|
|
||
| // shiftArray → shiftFromArray | ||
| -import { shiftArray } from "@evolu/common"; | ||
| +import { shiftFromArray } from "@evolu/common"; | ||
|
|
||
| // popArray → popFromArray | ||
| -import { popArray } from "@evolu/common"; | ||
| +import { popFromArray } from "@evolu/common"; | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| --- | ||
| "@evolu/react-native": major | ||
| "@evolu/react-web": major | ||
| "@evolu/common": major | ||
| "@evolu/nodejs": major | ||
| "@evolu/react": major | ||
| "@evolu/vue": major | ||
| "@evolu/web": major | ||
| "@evolu/relay": major | ||
| --- | ||
|
|
||
| # Update Node.js requirement | ||
|
|
||
| Updated minimum Node.js version from 22 to 24 (current LTS) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| "@evolu/common": minor | ||
| "@evolu/web": minor | ||
| "@evolu/nodejs": minor | ||
| --- | ||
|
|
||
| Added `GlobalErrorScope` interface for platform-agnostic global error handling | ||
|
|
||
| - Added `GlobalErrorScope` interface representing execution contexts that capture uncaught errors and unhandled promise rejections | ||
| - Added `handleGlobalError` helper to forward errors to scope callbacks | ||
| - Added `createGlobalErrorScope` for browser windows in `@evolu/web` | ||
| - Added `createGlobalErrorScope` for Node.js processes in `@evolu/nodejs` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@evolu/common": major | ||
| --- | ||
|
|
||
| Renamed `LazyValue<T>` to `Lazy<T>` for brevity |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| --- | ||
| "@evolu/common": minor | ||
| --- | ||
|
|
||
| Added `createObjectURL` helper for safe, disposable `URL.createObjectURL` usage using JS Resource Management so the URL is disposed automatically when the scope ends. | ||
|
|
||
| Example: | ||
|
|
||
| ```ts | ||
| const handleDownloadDatabaseClick = () => { | ||
| void evolu.exportDatabase().then((data) => { | ||
| using objectUrl = createObjectURL( | ||
| new Blob([data], { type: "application/x-sqlite3" }), | ||
| ); | ||
|
|
||
| const link = document.createElement("a"); | ||
| link.href = objectUrl.url; | ||
| link.download = `${evolu.name}.sqlite3`; | ||
| link.click(); | ||
| }); | ||
| }; | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| "@evolu/react-native": major | ||
| "@evolu/react-web": major | ||
| "@evolu/common": major | ||
| "@evolu/web": major | ||
| --- | ||
|
|
||
| - Merged `@evolu/common/local-first/Platform.ts` into `@evolu/common/Platform.ts` | ||
| - Made `@evolu/react-web` re-export everything from `@evolu/web`, allowing React users to install only `@evolu/react-web` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@evolu/common": major | ||
| --- | ||
|
|
||
| Changed `ok()` to return `Result<T, never>` and `err()` to return `Result<never, E>` for correct type inference. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@evolu/common": minor | ||
| --- | ||
|
|
||
| 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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| "@evolu/common": minor | ||
| --- | ||
|
|
||
| Added Resource Management polyfills | ||
|
|
||
| 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. | ||
|
|
||
| Polyfills are installed automatically when importing `@evolu/common`. | ||
|
|
||
| See `Result.test.ts` for usage patterns combining `Result` with `using`, `DisposableStack`, and `AsyncDisposableStack`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| --- | ||
| "@evolu/common": major | ||
| "@evolu/web": major | ||
| --- | ||
|
|
||
| Replaced interface-based symmetric encryption with direct function-based API | ||
|
|
||
| ### Breaking Changes | ||
|
|
||
| **Removed:** | ||
|
|
||
| - `SymmetricCrypto` interface | ||
| - `SymmetricCryptoDep` interface | ||
| - `createSymmetricCrypto()` factory function | ||
| - `SymmetricCryptoDecryptError` error type | ||
|
|
||
| **Added:** | ||
|
|
||
| - `encryptWithXChaCha20Poly1305()` - Direct encryption function with explicit algorithm name | ||
| - `decryptWithXChaCha20Poly1305()` - Direct decryption function | ||
| - `XChaCha20Poly1305Ciphertext` - Branded type for ciphertext | ||
| - `Entropy24` - Branded type for 24-byte nonces | ||
| - `DecryptWithXChaCha20Poly1305Error` - Algorithm-specific error type | ||
| - `xChaCha20Poly1305NonceLength` - Constant for nonce length (24) | ||
|
|
||
| ### Migration Guide | ||
|
|
||
| **Before:** | ||
|
|
||
| ```ts | ||
| const symmetricCrypto = createSymmetricCrypto({ randomBytes }); | ||
| const { nonce, ciphertext } = symmetricCrypto.encrypt(plaintext, key); | ||
| const result = symmetricCrypto.decrypt(ciphertext, key, nonce); | ||
| ``` | ||
|
|
||
| **After:** | ||
|
|
||
| ```ts | ||
| const [ciphertext, nonce] = encryptWithXChaCha20Poly1305({ randomBytes })( | ||
| plaintext, | ||
| key, | ||
| ); | ||
| const result = decryptWithXChaCha20Poly1305(ciphertext, nonce, key); | ||
| ``` | ||
|
|
||
| **Error handling:** | ||
|
|
||
| ```ts | ||
| // Before | ||
| if (!result.ok && result.error.type === "SymmetricCryptoDecryptError") { ... } | ||
|
|
||
| // After | ||
| if (!result.ok && result.error.type === "DecryptWithXChaCha20Poly1305Error") { ... } | ||
| ``` | ||
|
|
||
| **Dependency injection:** | ||
|
|
||
| ```ts | ||
| // 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. | ||
|
Comment on lines
+1
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Changeset jasně popisuje breaking změnu kryptografického API; lint MD041 je spíše kosmetika Text dobře vystihuje odstranění Upozornění markdownlintu MD041 („First line in a file should be a top-level heading“) je v kontextu Changeset souborů spíš falešný poplach – frontmatter na první řádce je v tomto formátu standard. Pokud ale chcete lint úplně utišit, můžete za frontmatter přidat jednoduchý nadpis (např. 🧰 Tools🪛 markdownlint-cli2 (0.18.1)5-5: First line in a file should be a top-level heading (MD041, first-line-heading, first-line-h1) 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@evolu/common": major | ||
| --- | ||
|
|
||
| Renamed `TransferableError` to `UnknownError` to better reflect its purpose as a wrapper for unknown errors caught at runtime, not just errors that need to be transferred between contexts |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| --- | ||
| "@evolu/common": minor | ||
| --- | ||
|
|
||
| Added `Typed` interface and `typed` factory for discriminated unions | ||
|
|
||
| Discriminated unions model mutually exclusive states where each variant is a distinct type. This makes illegal states unrepresentable — invalid combinations cannot exist. | ||
|
|
||
| ```ts | ||
| // Type-only usage for static discrimination | ||
| interface Pending extends Typed<"Pending"> { | ||
| readonly createdAt: DateIso; | ||
| } | ||
| interface Shipped extends Typed<"Shipped"> { | ||
| readonly trackingNumber: TrackingNumber; | ||
| } | ||
| type OrderState = Pending | Shipped; | ||
|
|
||
| // Runtime validation with typed() factory | ||
| const Pending = typed("Pending", { createdAt: DateIso }); | ||
| const Shipped = typed("Shipped", { trackingNumber: TrackingNumber }); | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| --- | ||
| "@evolu/common": major | ||
| "@evolu/web": major | ||
| "@evolu/react-native": major | ||
| "@evolu/react-web": major | ||
| --- | ||
|
|
||
| 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: `WorkerScope<Input, Output>` and `SharedWorkerScope<Input, Output>` that extend `GlobalErrorScope` for unified error handling | ||
| - Changed `onMessage` from a method to a property for consistency with Web APIs | ||
| - Made all worker and message port interfaces `Disposable` for proper resource cleanup | ||
| - Added default generic parameters (`Output = never`) for simpler one-way communication patterns | ||
| - Added complete web platform implementations: `createWorker`, `createSharedWorker`, `createMessageChannel`, `createWorkerScope`, `createSharedWorkerScope`, `createMessagePort` | ||
| - Added React Native polyfills for Workers and MessageChannel |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| --- | ||
| name: Bug report | ||
| about: Create a report to help us improve | ||
| title: '' | ||
| labels: '' | ||
| assignees: '' | ||
|
|
||
| --- | ||
|
Comment on lines
+1
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Zvažte přidání výchozích štítků a kontextu specifického pro @evolu. Šablona je funkční, ale vzhledem k rozsáhlým změnám v tomto PR (přejmenování API, transformace šifrování, abstractions pro workery) by mohla být obohacena o:
Namíchť generické šablony bude lépe sloužit k rychlejšímu třídění a diagnostice problémů specifických pro ekosystém. 🔎 Navrhovaná vylepšení ---
name: Bug report
about: Create a report to help us improve
title: ''
-labels: ''
-assignees: ''
+labels: 'bug'
+assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
+**Affected package**
+Which @evolu package(s) are affected? (e.g., @evolu/react, @evolu/sqlite, @evolu/common)
+
+**Package version**
+What version of @evolu are you using?
+
**To Reproduce**
🤖 Prompt for AI Agents |
||
|
|
||
| **Describe the bug** | ||
| A clear and concise description of what the bug is. | ||
|
|
||
| **To Reproduce** | ||
| Steps to reproduce the behavior: | ||
| 1. Go to '...' | ||
| 2. Click on '....' | ||
| 3. Scroll down to '....' | ||
| 4. See error | ||
|
|
||
| **Expected behavior** | ||
| A clear and concise description of what you expected to happen. | ||
|
|
||
| **Screenshots** | ||
| If applicable, add screenshots to help explain your problem. | ||
|
|
||
| **Desktop (please complete the following information):** | ||
| - OS: [e.g. iOS] | ||
| - Browser [e.g. chrome, safari] | ||
| - Version [e.g. 22] | ||
|
|
||
| **Smartphone (please complete the following information):** | ||
| - Device: [e.g. iPhone6] | ||
| - OS: [e.g. iOS8.1] | ||
| - Browser [e.g. stock browser, safari] | ||
| - Version [e.g. 22] | ||
|
|
||
| **Additional context** | ||
| Add any other context about the problem here. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Zvažte rozšíření popisu změn o kontext refaktoringu.
Aktuální popis se zaměřuje pouze na upgrade Node.js. Podle kontextu PR zahrnuje tato verze značné refaktoringové práce (sjednocení Array API, nové typy chyb, správa zdrojů, vývoj veřejného API). Zvažte, zda by se těmito položkami mělo zmínit v popisu changésetu pro jasnost v changeloge.
Alternativně, pokud se opírá příslušné detaily na commit messages, je aktuální minimalistický přístup přijatelný za předpokladu, že commit zprávy jsou vhodně detailní.
🤖 Prompt for AI Agents