migration of example code to row_input! macro
I migrated the three remaining hand-rolled HashMap call sites in the examples to use the new row_input! macro, and enabled SQLite for persistent storage in the todo-server tests.
I migrated the three remaining hand-rolled HashMap call sites in the examples to use the new row_input! macro, and enabled SQLite for persistent storage in the todo-server tests.
I added From<T> implementations on the Value type for common Rust types and introduced a row_input! macro for building HashMaps more ergonomically. This deleted about 250 lines of boilerplate across the codebase.
I built a multiplayer moon lander game as an example app for Jazz using React and Phaser. It demonstrates real-time multiplayer sync — multiple players can fly their landers at the same time and see each other's movements.
I updated allowedTo so you can write allowedTo.read("project") instead of having to specify the full "projectId" suffix. It tries an exact match first, then falls back to adding "Id" or "_id" for backwards compatibility.
I wrote a new Advanced Internals page covering the Jazz data model, browser architecture, query engine, sync protocol, schema evolution, and durability signals. I also fixed several documentation gaps along the way.
I standardised snake_case field naming across all todo and file-upload examples to match the docs convention, added missing permissions.ts files, fixed a bug in wequencer's instrument seeding, and cleaned up undocumented config.
I moved prop reads in JazzSvelteProvider and SyntheticUserSwitcher into reactive contexts so the Svelte 5 compiler no longer emits state_referenced_locally warnings. I also improved lifecycle handling in both components.
I updated the developer documentation to reflect the current build-less status quo, adding sections on the project layout (schema.ts, permissions.ts, migrations), the defineApp pattern, and type helpers.
I migrated the Wequencer example app from storing sound data as inline bytes to using Jazz's proper file/blob storage pattern with createFileFromBlob. This is the recommended way to handle binary data in Jazz.
I built a complete Vue 3 example app demonstrating Jazz as a local-first relational database. It covers schema definitions, permissions, and file handling — everything you need to see how Jazz works with Vue.
Our createInviteLink function had two different shapes depending on whether you imported it from the core library or from the browser/React Native wrappers. That was confusing for users and, in particular, was causing AI coding assistants to generate broken code because they'd mix up the two forms. I added an options-object overload to the core version so it matches the browser version, and cleaned up some duplicate implementations along the way. The old positional form still works, but it's now deprecated.
When two writers were updating the same piece of data at the same time, Jazz would sometimes throw an InvalidSignature error on load. The cause was a classic off-by-one: our code was using a count where it needed an index, so it was fetching one more transaction than the stored signature actually covered. I changed that one number and the storage layer now copes with concurrent writes properly.
We had been pulling in wasm-pack as an npm package, which dragged in axios and another helper library as transitive dependencies -- more things to trust from the npm ecosystem. Since anyone building our Rust/WASM crate already has a full Rust toolchain installed anyway, I switched us to installing wasm-pack directly via cargo install. One less set of supply-chain risks to worry about.
I removed the npm wasm-pack package and switched to installing it via cargo instead. This eliminates the axios transitive dependency, reducing the risk of supply chain vulnerabilities.
I added a reconcileArray utility that diffs keyed arrays in place and wired it into the Svelte and Vue onDelta callbacks. This means only the items that actually changed get re-rendered, instead of the whole list.
I fixed an issue where per-subscription claims sent by the client weren't being merged into the server session. This meant policies that depended on ephemeral claims couldn't evaluate correctly.
I replaced the mock-based Svelte tests with .svelte.test.ts files that run through the Svelte compiler. This means the tests exercise real Svelte 5 runes instead of mocking them, so they catch actual bugs in reactive behaviour.
I added JWKS (JSON Web Key Set) rotation support for self-hosted Jazz servers with a TTL-based cache, on-demand refresh, and a stale-if-error fallback. This means the server can automatically pick up new signing keys without needing a restart.
I built a complete React chat example app for Jazz featuring messaging, reactions, a canvas, file uploads, and row-level permissions with an invite flow. It shows how to build a real collaborative app with proper access control.
Jazz stores some authentication secrets behind the scenes, and our set function was telling everyone "the new value is ready!" before it had actually finished writing to storage. That tiny window was enough to cause spurious logouts when another part of the app asked for the session at the wrong moment. I added a missing await so the write finishes before anyone else is notified.