From 0160e38793083275c992f4a1221f38c5384d2a8a Mon Sep 17 00:00:00 2001 From: Jason Doyle <46789294+Jason-Doyle@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:50:01 -0700 Subject: [PATCH] Prepare 3.2.0 release --- CHANGELOG.md | 7 ++++-- deploy/cloudflare/wrangler.example.jsonc | 1 + docs/DEPLOYMENT-AWS.md | 9 ++++---- docs/DEPLOYMENT-AZURE.md | 9 ++++---- docs/EVALUATION.md | 10 ++++++++ docs/OPERATIONS.md | 16 +++++++++++++ docs/SECURITY.md | 18 +++++++++++++++ docs/VERSIONING.md | 29 ++++++++++++++++-------- package-lock.json | 4 ++-- package.json | 2 +- site/src/pages/index.astro | 5 +++- site/tests/site.spec.ts | 2 +- 12 files changed, 87 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41b3fd0..20209a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,12 @@ The format follows Keep a Changelog and the package uses semantic versioning. ## Unreleased +## 3.2.0 - 2026-09-28 + - Added opt-in bounded mutation batches for up to 20 documents and 1 MiB of - JSON, with one atomic collection revision, HEAD-last durability, and browser - cache updates. + JSON through typed `putMany()` APIs, with one atomic collection revision, + HEAD-last durability, bounded browser cache updates, and no silent fallback + to separate writes. - Published a post-merge 1,008-write scaling matrix across seven regions, three collection sizes, and zero, one, and two indexes, including three retained R2 failures and the historical comparison. diff --git a/deploy/cloudflare/wrangler.example.jsonc b/deploy/cloudflare/wrangler.example.jsonc index 92443b5..ad8cb91 100644 --- a/deploy/cloudflare/wrangler.example.jsonc +++ b/deploy/cloudflare/wrangler.example.jsonc @@ -16,6 +16,7 @@ "THIMBLE_READ_KEY_VERSIONS": "", "THIMBLE_HEAD_TTL_MS": "1000", "THIMBLE_READ_BUNDLES": "false", + "THIMBLE_MUTATION_BATCHES": "false", "THIMBLE_COLLECTION_LAYOUTS": "", "THIMBLE_COLLECTION_INDEXES": "{}", "THIMBLE_COLLECTIONS": "", diff --git a/docs/DEPLOYMENT-AWS.md b/docs/DEPLOYMENT-AWS.md index 39d6671..51d27fc 100644 --- a/docs/DEPLOYMENT-AWS.md +++ b/docs/DEPLOYMENT-AWS.md @@ -73,10 +73,11 @@ expose: - `THIMBLE_READ_BUNDLES` - `THIMBLE_MUTATION_BATCHES` -The supplied deployment therefore leaves Studio, covering indexes, and read -bundles disabled. Use a reviewed derived template or another Node deployment -configuration when those optional features are required. Setting variables -only in the deployment shell does not pass them into the Lambda function. +The supplied deployment therefore leaves Studio, covering indexes, read +bundles, and mutation batches disabled. Use a reviewed derived template or +another Node deployment configuration when those optional features are +required. Setting variables only in the deployment shell does not pass them +into the Lambda function. The template still passes its legacy `RetiredCollectionLayouts` value into the Lambda environment. The authority runtime does not perform retired-layout diff --git a/docs/DEPLOYMENT-AZURE.md b/docs/DEPLOYMENT-AZURE.md index b5315e3..65c1149 100644 --- a/docs/DEPLOYMENT-AZURE.md +++ b/docs/DEPLOYMENT-AZURE.md @@ -96,10 +96,11 @@ collection-layout, and retention settings. It does not currently expose: - `THIMBLE_READ_BUNDLES` - `THIMBLE_MUTATION_BATCHES` -The supplied deployment therefore leaves Studio, covering indexes, and read -bundles disabled. Use a reviewed derived template or another Container Apps -configuration when those optional features are required. Setting variables -only in the deployment shell does not add them to the Container App. +The supplied deployment therefore leaves Studio, covering indexes, read +bundles, and mutation batches disabled. Use a reviewed derived template or +another Container Apps configuration when those optional features are +required. Setting variables only in the deployment shell does not add them to +the Container App. For key rotation, set `keyVersion` to the current write version and `readKeyVersions` to the comma-separated historical versions that remain diff --git a/docs/EVALUATION.md b/docs/EVALUATION.md index 2efa621..1ffb703 100644 --- a/docs/EVALUATION.md +++ b/docs/EVALUATION.md @@ -42,6 +42,16 @@ Enable the opt-in cold point-read bundle path with: $env:THIMBLE_READ_BUNDLES = "true" ``` +Enable the opt-in bounded mutation-batch path with: + +```powershell +$env:THIMBLE_MUTATION_BATCHES = "true" +``` + +The browser harness does not automatically coalesce writes. Use +`ThimbleCollection.putMany()` or `ThimbleClient.writeBatch()` to exercise one +explicit group. + For a compiled local run: ```powershell diff --git a/docs/OPERATIONS.md b/docs/OPERATIONS.md index 6eae6cf..88eb078 100644 --- a/docs/OPERATIONS.md +++ b/docs/OPERATIONS.md @@ -136,6 +136,20 @@ Backups require the matching master key version. Logical exports are portable plaintext migrations, not encrypted backups. See [Logical migration](MIGRATION.md). +## Mutation batches + +Enable mutation batching only for applications that intentionally call +`putMany()`. Ordinary writes are not delayed or coalesced automatically. + +Monitor complete batch duration rather than only amortized per-document +latency. A batch remains one conflict and retry unit, so repeated CAS failures +can repeat more work than one ordinary mutation. Keep an immediate single-write +fallback for user actions that should not wait for a group. + +The initial supported limits are 20 unique documents and 1 MiB of JSON. Do not +raise them without measuring authority memory, provider request limits, and +contention with representative payloads. + ## Observability Record: @@ -143,6 +157,8 @@ Record: - read source: memory, IndexedDB, or remote - remote object bytes - read-bundle requests, bytes, object counts, and fallbacks +- mutation-batch document count, request bytes, total duration, revision, + `cacheComplete`, failures, and CAS retries - compression ratio - envelope encode/decode duration - HEAD conditional-write retries diff --git a/docs/SECURITY.md b/docs/SECURITY.md index 315ccb8..7ae59a4 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -164,6 +164,24 @@ maintenance, key rotation, and migration. A deployment that does not trust the authority runtime with plaintext is outside the current ThimbleDB threat model. +## Mutation batch boundary + +Mutation batching is disabled by default. When enabled, it uses the same +authenticated session, exact origin, CSRF token, scope write grant, and layout +generation checks as an ordinary write. + +The complete request is limited to 20 unique document IDs and 1 MiB of JSON. +Validation finishes before candidate immutable objects are uploaded. Success +is returned only after one conditional collection HEAD publication. A +validation failure publishes nothing, and a HEAD conflict applies to the +complete batch rather than hidden per-document commits. + +The batch response is `no-store` and may contain decoded changed document-path +cache values over HTTPS. Response cache values are bounded to 42 objects and +16 MiB. The authority already processes the same plaintext during writes. +Applications that do not accept this response boundary should leave mutation +batching disabled and use ordinary writes. + ## Secret handling Never commit: diff --git a/docs/VERSIONING.md b/docs/VERSIONING.md index 25542e3..575d1be 100644 --- a/docs/VERSIONING.md +++ b/docs/VERSIONING.md @@ -14,16 +14,6 @@ Package version `1.0.0` freezes the documented exports in [Public package API](PUBLIC-API.md). Semantic versioning applies to the root, auth, authority, and provider subpaths. -## Unreleased compatible capabilities - -- authorities may explicitly advertise bounded mutation batches -- clients can publish 1-20 documents in one collection revision through - `putMany()` -- authorities that do not enable the capability retain existing single-write - behavior and do not advertise the endpoint -- the stored TDB1, Snapshot HEAD, Trie HEAD, and secondary-index formats are - unchanged - ## Version 1.0 Version 1.0 provides: @@ -114,6 +104,25 @@ optional definition and projection fields that older readers ignore. Upgrade every writing authority before enabling covering fields, then rebuild the affected indexes while writes are quiescent. +## Version 3.2 + +Version 3.2 adds compatible bounded write and performance improvements: + +- authorities may explicitly advertise bounded mutation batches +- clients can publish 1-20 unique documents and at most 1 MiB of JSON in one + collection revision through `putMany()` +- authorities that do not enable the capability retain existing single-write + behavior and do not advertise the endpoint +- range planning applies every supported bound before loading candidates +- bounded immutable commits overlap independent Snapshot, Trie, and index + uploads while preserving final HEAD publication +- normal decoded object reads and writes fail closed above 16 MiB by default +- mutable HEAD freshness begins when revalidation completes + +The stored TDB1, Snapshot HEAD, Trie HEAD, and secondary-index formats are +unchanged. Mutation batching is an optional authority and browser capability, +so older clients continue using ordinary single writes. + ## Object protocol version `TDB1` is stored in every object envelope. Protocol compatibility is separate diff --git a/package-lock.json b/package-lock.json index 3c755d9..a0bf059 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "thimbledb", - "version": "3.1.0", + "version": "3.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "thimbledb", - "version": "3.1.0", + "version": "3.2.0", "license": "Apache-2.0", "dependencies": { "jose": "^6.1.0" diff --git a/package.json b/package.json index 580bca4..2b1775c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "thimbledb", - "version": "3.1.0", + "version": "3.2.0", "description": "Encrypted browser-first JSON database for small web apps, backed by object storage with in-app or separate Cloudflare and Node authorities.", "private": false, "license": "Apache-2.0", diff --git a/site/src/pages/index.astro b/site/src/pages/index.astro index 3c9b73b..b7f601d 100644 --- a/site/src/pages/index.astro +++ b/site/src/pages/index.astro @@ -206,7 +206,9 @@ const websiteSchema = {
The authority owns credentials, identity, keys, and conditional - writes. Application code works with documents and collections. + writes. Applications can explicitly group an existing burst into one + bounded collection revision. Application code works with documents + and collections.
@@ -277,6 +279,7 @@ const websiteSchema = {