v0.19: Coding Agents, Batch Controller.set(), Faster TypeScript
· 阅读需 37 分钟
v0.19 makes coding agents a first-class way to build with Data Client: one prompt sets up your app, and your agent follows skills that ship with the packages you installed. It also 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:
- One-prompt setup - Add the
data-clientplugin to Claude Code, Cursor or Codex and ask it to set up Data Client; it installs the packages, adds the provider and links the skills your app needs - Skills ship in the packages -
npx --no data-client-skillslinks the skills your installed@data-client/*packages carry, so your agent follows the version you have instead of an older release - Agents keep using Data Client - Setup adds a note to
AGENTS.md, and each skill names the everyday tasks it covers, so later sessions reach for Data Client instead offetchinuseEffect - Debug the running app - In development,
globalThis.__DC__gives your agent the store's Controller and recent actions from Cursor's browser, Chrome DevTools MCP, Playwright MCP or Claude in Chrome - Vue skills, llms.txt, and skills generated from these docs
New APIs:
- Controller.set() with Array schemas - Write many entities in one store update with
ctrl.set([Entity], rows), up to 95x faster than oneset()per row
Performance:
- Faster TypeScript - Editors and
tsccheck RestEndpoint and resource() code about 2x faster with 40% less memory, catching every error they caught before
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()andresource().extend(), so a wrong path parameter is a TypeScript error instead ofundefinedat 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
invalidIfStaledata through unrelated store updates instead of getting stuck loading (#4142) - Vue
DataClientPlugininstalls on Vue versions before 3.5 instead of throwingapp.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'andexport typeerrors on TypeScript 4.x withskipLibCheckoff (#4138) - Fix
Entity,Endpoint,UnionandRestEndpointtype errors on TypeScript 4.0–4.5 withskipLibCheckoff (#4140) - Fix
',' expectederrors importing@data-client/react/redux,@data-client/react/nextjsor@data-client/teston TypeScript 4.0–4.4 (#4232) - Fix
actandrenderHookfrom@data-client/testtyped asanyon 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 noawait(#4374) - Entity classes can be used where an
EntityInterfaceis expected (#4149); preparepk()overrides for a future release - useCache() and useDLE() return
undefinedfor a deleted entity whose refetch failed, instead of a truthySymbolthat slipped pastif (!data)checks; remove any workarounds (#4150) - Vue useFetch() keeps its data from being garbage collected while mounted, like useSuspense(), so a configured
gcPolicyno 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,
unshiftandremoveaccept the Entity's fields as the body when a Query or Lazy wraps the Collection, instead of onlyFormData(#4226) - Vue useFetch() is typed as the read-only
Refit returns, sopromise.resolved(alwaysundefined) is now a TypeScript error; readpromise.value.resolvedinstead (#4114) - A
Controllersubclass passed to DataProvider or DataClientPlugin no longer needs a cast to type-check (#4228) - prepareStore()'s
storecan be passed to react-redux's<Provider>without a cast, and hasdispatch()in its type (#4238) - resource().create accepts FormData without a cast, like
update,partialUpdateandgetList.push(#4235) - RestEndpoint.push,
unshiftandremovesend an array body as JSON, so creating or removing several items at once no longer sends"[object Object]"to your server;resource().createtakes an array too (#4262) - 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 withapp.use(DataClientPlugin, options)instead of calling it directly (#4193) - Vue
renderDataCompose()'swaitForNextUpdate()is deprecated, since it gives up silently after 1 second and lets a test pass while still suspended;await resultinstead, orawait allSettled()after a change, which now also waits for fetches a prop change starts (unit testing composables, #4221)
- TypeScript 4.0 or later is required - the TypeScript 3.x declarations are removed (#4151)
- Managers must define
middleware-getMiddleware()is removed (#4378, #4382) - @data-client/test requires @data-client/react 0.15.3 or later (#4414)
globalThis.__DC__replaces__DC_CONTROLLERS__in development (#4435)
