Repository navigation
perf(vue): publish writeItems once - #64
Merged
Merged
Conversation
@rstore/connector-toolkit
@rstore/core
@rstore/devtools
@rstore/directus
@rstore/monospace
@rstore/nuxt
@rstore/nuxt-directus
@rstore/nuxt-drizzle
@rstore/nuxt-monospace
@rstore/nuxt-multiplayer
@rstore/nuxt-multiplayer-server
@rstore/offline
@rstore/shared
@rstore/vite-directus
@rstore/vite-monospace
@rstore/vue
commit: |
Akryum
force-pushed
the
fix/vue-batch-writeitems-publication
branch
from
September 9, 2026 12:01
e6633e2 to
9ef9985
Compare
Akryum
force-pushed
the
fix/vue-batch-writeitems-publication
branch
from
September 9, 2026 16:27
9ef9985 to
06d9791
Compare
Avoid notifying Vue dependents after every item in a bulk cache write. Publish affected collections atomically, defer nested hooks until settlement, and preserve queue progress and error context across partial failures.
Akryum
force-pushed
the
fix/vue-batch-writeitems-publication
branch
from
September 9, 2026 17:20
06d9791 to
b7eb76f
Compare
Akryum
force-pushed
the
fix/vue-batch-writeitems-publication
branch
from
September 9, 2026 17:25
b7eb76f to
eed258a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Bulk cache writes now publish one reactive update per affected collection instead of notifying Vue dependents after every item. This removes repeated synchronous query recomputation while preserving immediate
writeItembehavior, nested relation consistency, hook ordering, and retryable partial failures.The PR now includes an RStore-native benchmark that exercises the real Vue cache runtime, public
peekManyquery API, a Vue computed, and a synchronous watcher:The optimized case calls the public
cache.writeItemsAPI. The control reproduces the parent commit's flat, active, non-staggeredwriteItemspath with the realwriteItemNow, including per-item reactive publication and one outer hook. Each mode gets two warmups and 20 measured samples in alternating order, with a new store and cache for every sample.For 1,000 items, a clean-process run on Node v26.5.0 and an Apple M4 Pro produced:
writeItemsBoth paths produced the same final cache and query digest. This run measured a 466.864× median speedup. Timing is descriptive and machine-dependent; the benchmark fails only when the final semantics, hook payload, or publication/recomputation counts differ.
Recorded 1,000-item timing samples and source provenance
e6633e291f0a1212f75d6d839b52b622e7cd4a90true41ebc39a12e7d48d526eff79b758e22ff884baf67fb8f905a8195bffafa4de10[712.311, 707.645, 708.969, 752.247, 709.683, 846.453, 772.726, 732.693, 720.207, 733.25, 731.016, 770.027, 762.509, 781.253, 871.926, 838.172, 798.52, 753.594, 764.693, 864.371][1.557, 1.419, 1.508, 1.491, 1.582, 1.478, 1.628, 1.68, 1.843, 1.543, 1.74, 2.536, 1.619, 1.561, 1.673, 2.208, 2.389, 1.597, 1.642, 1.631]The exact control is limited to the benchmarked flat, non-staggered case. It does not claim to reproduce legacy staggering, nested-relation settlement, or error handling; focused tests cover those production contracts.
This is an atomic reactive-publication boundary, not a rollback transaction. Imperative cache reads can still observe already-written raw state during a staggered batch. If a later item fails, successful earlier writes are published before the error is returned, and the failed item remains retryable.
The settlement boundary also guarantees that:
afterCacheWritehooks run;Additional context
The public
writeItemsAPI and multi-resultapplyMutationpath share one batch initializer.CacheWriteBatchowns the affected collection set and deferred nested-hook payloads, so batching policy stays in the cache repository instead of leaking into consumers.Mutation testing removed batch propagation and produced 11 focused failures while immediate single-item publication stayed green. The final checks are:
pnpm --filter @rstore/vue benchmark:write-items— semantic and structural assertions passedpnpm vitest run packages/vue/test— 17 files, 261 tests passedpnpm --filter @rstore/vue test:types— passed, including the benchmark sourcepnpm --filter @rstore/vue build— passedpnpm install --lockfile-only --offline --frozen-lockfile— passedgit diff --check— passedThe local monorepo-wide build and test commands could not complete because this checkout is missing generated Nuxt configs and package-local binaries such as
nuxt-module-build. The affected package checks above pass; CI should run the full matrix in a prepared checkout.Reviewer focus: queue completion after subscriber/hook exceptions, partial-failure retry semantics, the benchmark control's explicit scope, and the distinction between reactive atomicity and rollback.
New concepts
Atomic reactive publication
The cache still performs each raw item mutation in order, but it delays Vue notifications until the batch settles. One batch object records which collections changed and which nested hooks must run later.
This is preferable to disabling each consumer watcher because the cache owns the publication contract. It also covers public writes, mutation results, relations, indexes, and layers through one seam.
Do not use this pattern when intermediate states are part of the public contract. It is also not a substitute for transactional rollback because successful raw writes remain applied after a later failure.
Post-Deploy Monitoring & Validation
afterCacheWritehooks, or queued writes that stop progressing after a subscriber error.@rstore/vuerelease.What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following
fixes #123).