klis87 / normy Goto Github PK
View Code? Open in Web Editor NEWAutomatic normalization and data updates for data fetching libraries (react-query, swr, rtk-query and more)
License: MIT License
Automatic normalization and data updates for data fetching libraries (react-query, swr, rtk-query and more)
License: MIT License
I have an object with a child array that gets normalized. However, when a new item is added to the array, the parent doesn't show the new object in the array. How can I have it update the array?
Here's my config:
<QueryNormalizerProvider
queryClient={queryClient}
normalizerConfig={{
normalize: typeof window !== 'undefined',
devLogging: true,
getNormalizationObjectKey: (obj: { id?: string; createdAt?: Date }) => {
const key =
typeof obj.id === 'string' && obj.createdAt instanceof Date
? obj.id
: undefined
if (!key) {
return
}
console.log('Normalizing %o', obj)
return key
},
}}>
Which prints my log with the date, and then the dev log, which shows the date being gone.
Normalizing
{id: 'cloeog1mm0005ckahzxq197b1', createdAt: Tue Oct 31 2023 14:43:27 GMT-0400 (Eastern Daylight Time), updatedAt: Tue Oct 31 2023 16:43:02 GMT-0400 (Eastern Daylight Time), …}
set query: [["task","get"],{"input":"cloeog1mm0005ckahzxq197b1","type":"query"}]
with data:
{id: 'cloeog1mm0005ckahzxq197b1', createdAt: {…}, updatedAt: {…}, type: 'REMINDER', title: 'LOI coming soon', …}
actions
:
[]
assignedDate
:
{}
completedDate
:
{}
createdAt
:
{}
Currently, when you have an optimistic update, you can define optimisticData
to update data immediately.
Also you can pass rollbackData
, so that data will be reverted accordingly in case of some error.
However, based on optimistic data structure and current data, actually it should be really possible to calculate rollbackData
automatically, so you will not even need to thing about it!
Currently examples are in a separate pnpm workspace. It is better to put them together with the library, so linking is done automatically
Add getObjectById
method to createNormalizer
response. It could be then used not only to get objects by id, instead of only using queries, but also potentially it could be also used by libraries like react-query
to actually get a given object from normalized store instead of firing request... or, to make the request regardless, but to initially show data from getObjectById
to make ui more responsive.
For example, if we have already a data for list of books, this list could already contain an object with a given id, so detail request might make no sense.
Some ideas what can be done here:
getObjectById
getObjectById
- dataStructure
or sth like this, with all fields including nested fields, which a given object should have, this can prevent problem from 2), and also this would be helpful to make decisions if a data from normalized store could be used instead of making a request, for example if we do not have all fields, we need to fetch remote data, if we do, we might skip itgetQueryFragment
, which would work like getObjectById
, but for multiple objects with any data structure, for example getQueryFragment({ list: ['@@1, '@@2'], obj: '@@3' })
. So it would be like virtual query, which data would be calculated from normalized store, almost like grapgql for local data.react-query
driverIt would be cool to have some measurement of normy normalization alogorythms. We could just calculate number of ms a function takes and console.log it, but maybe it is a better way? Or having a test threshold defined somewhere?
Also, maybe it would be cool to add some dev loggers with performance measurements, so that it would be transparent how costly normalization is for a given data.
Currently we use https://github.com/TehShrike/deepmerge , but there are other libraries which claim to be faster.
We should at least try it. Ideally we should have some performance measurement first, at least in tests, so that we could see if another lib would be faster or slower.
Usually it is better to update dependent data in memory, which is already supported. However, in some cases, especially if a fetching library does not allow it, it might become handy.
We have travis config but it is not free anymore for opensource projects. So let's switch to github actions!
Currently createNormalizer
has internal data which is private.
It would be handy to allow something like controlled version of createNormalizer
, like controlled React component.
A value and setter prop could be passed, so that createNormalizer
consumer would own data.
Then, data could be stored anywhere, like in Redux store, or React state. This could be useful for normy addons.
This will wait for new rtk query major version, which should be released in December.
Hi there, love what you've built here! I'm wondering if there's a way to use this with NextJS.
Thanks
Currently for mutations like ADD_BOOK
, or REMOVE_BOOK
, there are no automatic updates - without some extra hints, the library cannot know which arrays to update and how.
It should be possible though with some extra hints.
I just found out that you can do this for optimistic updates. This is amazing and should be documented:
const completeTaskMutationResult = api.task.complete.useMutation({
onMutate(variables) {
const updatedTask = {
...task,
completedDate: variables.isCompleted ? new Date() : null,
} satisfies Task
return {
optimisticData: updatedTask,
rollbackData: task,
}
}
})
react-query plugin should be updated to work with version 5.
Also, after trpc migrates to react-query 5, it should be checked that trpc example still works.
This happens when installing via bun.sh
Currently we always normalize data after each query successful response. However, some libs like react-query uses structural sharing feature, which preserves data
reference if it did not change. We could use this to normy advantage to give up normalization in such cases, as normalizating in this scenario will end up with the same normalized store.
This is especially useful for features like refetch on refocus, as then we can end up with multiple queries refetches at the same time, most of each will end up probably being the same.
For now we use just github readme as docs. But despite the fact docs are not very big, it is best to see features and examples for the framework of your choice. Otherwise it is hard to explain especially generic concepts.
Plus, it would be cool to have built-in interactive examples.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.