Skip to main content

2 posts tagged with "Managers"

Managers handle global side effects and middleware

View All Tags

v0.19: Batch Controller.set(), Faster TypeScript

· 31 min read
Nathaniel Tucker
Creator of Reactive Data Client

v0.19 lets a Manager write a whole batch of streamed rows in one store update, type-checks endpoint code about 2x faster, and fixes a round of TypeScript and Vue issues. Coding agents also get a Claude Code plugin, Vue skills and llms.txt; see Data Client for Coding Agents.

New APIs:

Performance:

Other Improvements:

  • Fix TypeScript 7 module resolution for package exports; imports now resolve to declaration files (#4019)
  • renderDataHook() runs provider mount effects when the first render suspends (#4099)
  • Controller.set() values are typed by the schema, so ctrl.set(new schema.All(Todo), 42) is a TypeScript error (#4133)
  • Controller.set() deletes one entity with an Invalidate schema without the one-row batch workaround (#4230)
  • process() gets typed params in new RestEndpoint(), .extend() and resource().extend(), so a wrong path parameter is a TypeScript error instead of undefined at runtime (#4183, #4184)
  • getOptimisticResponse() returns are typed by the schema, so a wrong field type is a TypeScript error instead of a flash of bad data (#4198)
  • Vue useSuspense() and useLive() keep the previous data while new arguments load, instead of returning undefined (#4131)
  • Vue useSuspense() and useLive() send fetch errors after arguments change to onErrorCaptured() instead of an unhandled promise rejection (#4135)
  • Vue useSuspense(), useDLE() and useFetch() no longer refetch stale data on every store update, so a controller.set() is not overwritten (#4134)
  • Vue useSuspense() shows stale data on mount and refetches in the background, like React, instead of showing the <Suspense> fallback until the refetch finishes (#4169)
  • Vue useDLE() and useCache() keep expired invalidIfStale data through unrelated store updates instead of getting stuck loading (#4142)
  • Vue DataClientPlugin installs on Vue versions before 3.5 instead of throwing app.onUnmount is not a function (#4146)
  • Vue DataClientPlugin garbage collects by default, matching React's DataProvider, so you no longer need to pass gcPolicy; how it decides what to remove (#4148)
  • Vue composables accept getter arguments like () => ({ id: props.id }); they were typed to allow them but passed the function itself to the endpoint (#4115)
  • Fix Cannot find name 'NoInfer' and export type errors on TypeScript 4.x with skipLibCheck off (#4138)
  • Fix Entity, Endpoint, Union and RestEndpoint type errors on TypeScript 4.0–4.5 with skipLibCheck off (#4140)
  • Fix ',' expected errors importing @data-client/react/redux, @data-client/react/nextjs or @data-client/test on TypeScript 4.0–4.4 (#4232)
  • Fix act and renderHook from @data-client/test typed as any on TypeScript 4.0–4.4 (#4251)
  • React Native useSuspense(), useFetch() and useDLE() refetch on screen focus only when the current data is stale or invalid, instead of refetching fresh data on every refocus (#4378)
  • renderDataHook() works with React Native Testing Library 14 and stays synchronous, so renderDataHook() calls need no await (#4374)
  • Entity classes can be used where an EntityInterface is expected (#4149); prepare pk() overrides for a future release
  • useCache() and useDLE() return undefined for a deleted entity whose refetch failed, instead of a truthy Symbol that slipped past if (!data) checks; remove any workarounds (#4150)
  • Vue useFetch() keeps its data from being garbage collected while mounted, like useSuspense(), so a configured gcPolicy no longer evicts prefetched data that components read later (#4152)
  • Apps with Redux DevTools open no longer stutter in development on large stores or frequent updates; each update serializes 40-60x faster (#4163)
  • resource().extend() with an object of endpoint overrides keeps endpoints added earlier with .extend('name', options) in its type, so using them is no longer a TypeScript error (#4184)
  • RestEndpoint.push, unshift and remove accept the Entity's fields as the body when a Query or Lazy wraps the Collection, instead of only FormData (#4226)
  • Vue useFetch() is typed as the read-only Ref it returns, so promise.resolved (always undefined) is now a TypeScript error; read promise.value.resolved instead (#4114)
  • A Controller subclass passed to DataProvider or DataClientPlugin no longer needs a cast to type-check (#4228)
  • prepareStore()'s store can be passed to react-redux's <Provider> without a cast, and has dispatch() in its type (#4238)
  • resource().create accepts FormData without a cast, like update, partialUpdate and getList.push (#4235)
  • RestEndpoint.push, unshift and remove send an array body as JSON, so creating or removing several items at once no longer sends "[object Object]" to your server; resource().create takes an array too (#4262)
  • Pushing a list of items to RestEndpoint.push or unshift resolves an array type, so const [a, b] = await ctrl.fetch(getTodos.push, [x, y]) compiles; ctrl.set() with Collection.push takes the Collection's args and a list of rows (#4421)
  • Polling keeps the schema of endpoints given pollFrequency with .extend(), so a polled useLive() list updates right away from mutations and optimistic updates instead of waiting for the next poll (#4437)
  • DataProvider only warns that it doesn't update during SSR when something fetches while the server renders, instead of on every server render, so pages that load data after mount (like Expo Router's static web output) stay quiet (#4449)
  • Server rendering with React 19 no longer logs "Uncaught suspense" when nothing suspended; React renders and discards fallbacks of large boundaries, and the warning now waits for a fallback that actually shows (#4450)
  • Vue createDataClient() is deprecated, since it's internal to DataClientPlugin; install the plugin with app.use(DataClientPlugin, options) instead of calling it directly (#4193)
  • Vue renderDataCompose()'s waitForNextUpdate() is deprecated, since it gives up silently after 1 second and lets a test pass while still suspended; await result instead, or await allSettled() after a change, which now also waits for fetches a prop change starts (unit testing composables, #4221)

Breaking Changes:

Get ready for future releases:

v0.14: Streamlined Manager APIs, Performance, and GC

· 12 min read
Nathaniel Tucker
Creator of Reactive Data Client

Managers:

Manager APIs have been streamlined—flatter action shapes reduce code complexity and improve performance by minimizing distinct inline cache entries, while simpler configuration APIs make customization more delightful.

Performance:

Schema/Data Modeling:

Testing:

Garbage Collection:

  • GCPolicy - automatic garbage collection of stale data

Breaking Changes: