fireproof-storage / fireproof

Realtime database, runs anywhere. Install Fireproof in your front-end app or edge function, and sync data via any backend.
https://fireproof.storage
Other
219 stars 16 forks source link

Typescript Generics in react-hooks #81

Open davidjamesb opened 5 months ago

davidjamesb commented 5 months ago

First of all great project and I'm excited for the work ongoing in this space and this project in particular!

I'm following the vite/react tutorial here and ran into issues with the typescript compiler:

image

Switching to an interface and extending DocBase gets past this hurdle:

image

However, the types returned by the useDocument hook are inferred as DocBase leading to a lot of casting when using the todo object as an actual instance of ToDo later on in the react component.

I expected there to be a version such as useDocument<T>(...) and looking through the source for useFireProof.tsx there does appear to be comments alluding to this, but such signature doesn't appear to exist. I understand there has been some recent work regarding generics in #80 so maybe this is due to come. Either that or I'm using it wrong. image

The siutation is the same for useLiveQuery.

Finally, a tangent but related - whilst digging around the source I noticed that we have generic signatures for most functions on database.ts except subscribe. It's my understanding that this function will listen for all changes that occurred in the database since the latest clock sync with which documents of multiple types could have been changed.

Whilst working with other document databases, the common solution is to add a type : string field to each document and have a discriminator function map from the serialized JSON to the correct type at runtime. Would this be the recommendation when using fireproof e.g. handle it in the (changes) => {...} callback or is there scope to 'bake' this into the source by embedding the object type information into the JSON or providing an overload e.g:

type DocDiscriminator = (doc: DocBase) => boolean;

subscribe(listener: ListenerFn | NoUpdateListenerFn, updates?: boolean, discriminator?: DocDicriminator): () => void {
}
thedanchez commented 5 months ago

Ah, thanks for raising this! Was an oversight on my part. Got missed as I was porting over the work from the SolidJS adapter.

thedanchez commented 5 months ago

@davidjamesb just merged in the PR to fix this issue. Should have a new version of the React package published soon!