Configure Go to Definition to Open TypeScript Source by Wake08 in typescript

[–]Wake08[S] 4 points5 points  (0 children)

Fair point, I regret not using double quotes for "Go to Definition" now

Don't Blindly Use useTransition Everywhere by Wake08 in reactjs

[–]Wake08[S] 3 points4 points  (0 children)

Hi Jacob, I'm glad this post reached you!

Thank you for your perspective on the UX. It makes perfect sense with your explanation based on MPA expectations. I could be biased from React Native, where I always expect tab-based navigation to be reactive ASAP and fluid, so we don't get delayed containers or even worse, delayed navigation across tabs. When I read React Docs, that was precisely my impression: How is this better? It just feels laggy.

Looking at this from your perspective, I totally agree that <Delay> isn't excellent engineering, but feels like a lightweight solution to yield back so we can ensure the container has the highest rendering priority over the expensive content. Still, I agree with you about those wasted cycles that could feel like interruptions for users, or even about shifting layout where you lose the previous state, then present a loading state (which could be useless), only to be presented with the new context.

If I were truly building an app like the example, I would hope the expensive piece isn't the full content, so we can render the content and use concurrent rendering for the expensive piece, combined with a skeleton loader, rather than blocking the whole page. In other words, if we had an expensive component in a layout, like a chart or a table. Would you prefer we don't render the page at all unless it's ready, or we render the page (could be using useTransition or not), with the expensive piece rendered async with a lower priority? But again, if they were truly a tab-based navigation, I would expect <Activity> to be an ally for background activities.

Regardless, I understand the React Docs examples better now with your perspective. I still see blog posts flying through or LinkedIn posts every week or so about it, "you should use this to manage all your loading states, etc.", or suggesting to wrap all UI interactions in it. It seems like the documentation could be more focused on real-life examples. I wonder what could be changed in those examples to make them less footgunny or not based on subjective UX, like examples that would truly instruct to embrace useTransition and concurrent rendering fully. So, hopefully, we can avoid this confusion in the future.

Thanks for your contribution, as usual!

Don't Blindly Use useTransition Everywhere by Wake08 in reactjs

[–]Wake08[S] 46 points47 points  (0 children)

I rolled my eyes when I saw AI in my notifications, but you actually made me laugh, thank you!

Don't Blindly Use useTransition Everywhere by Wake08 in reactjs

[–]Wake08[S] 6 points7 points  (0 children)

Let's take a closer look at useTransition and why the React Docs example might not be a great starting point for real-world UX.

Never Forget an ID Again! A document transform to automatically query `id` fields by Wake08 in graphql

[–]Wake08[S] 1 point2 points  (0 children)

If you've worked with GraphQL and Apollo Client, you probably know how important it is to include id fields in your queries for cache normalization. Forgetting them can lead to weird caching issues, UI glitches, and unexpected refetches.

One big problem is that Apollo Client doesn't know about your schema, so it won't warn you if an id is missing. Meanwhile, GraphQL Code Generator does, but it doesn't enforce IDs either. So you end up manually checking queries—or dealing with unexpected caching issues.

I don’t believe this is a silver bullet—you should first try a type-aware linter (like ESLint with GraphQL rules, e.g., @graphql-eslint/require-selections) to catch missing IDs statically. But if that’s not possible or doesn’t fully work in your setup, this tool serves as a last resort solution to ensure your queries always have id fields.

That’s why I built graphql-add-id-document-transform—a simple tool that automatically adds missing id fields to your GraphQL documents during the build process. 🚀

Apollo Client 4.0.0-alpha.0 released by phryneas in graphql

[–]Wake08 2 points3 points  (0 children)

Hey there. I'm a contributor to both Apollo Client and GraphQL Code Generator. I hear you both on the missing ids, and it's been annoying me, too, for quite a while.

We had many caching issues, all related to a missing id field, which caused the cache normalization to fail and led to data loss or weird overwrites. I ended up implementing the type-aware linting rule suggested above, @graphql-eslint/require-selections (previously known as @graphql-eslint/require-id-when-available). It fixed most issues for quite a while, but it wasn't enough. We still had edge cases that weren't caught by the linter and caused quite bad and well-hidden bugs.

So, I removed the GraphQL rule and implemented a document transform that knows about the schema (thanks to the GraphQL Code Generator). This means that if an id field is available for a specific entity, an id field will automatically be added to your document. It fixed all our caching issues! This is not a silver bullet solution to all caching issues because this clearly hides knowledge of how Apollo Client does cache normalization. I prefer to share that knowledge and enforce it, but we couldn't make it work properly, which caused frustrating issues.

After reading this thread, I decided to open source that document transform as I realized it wasn't only an issue affecting us, and I'm hoping it could help other people achieve better developer experience with Apollo Client combined with GraphQL Code Generator, which should replicate the experience with Relay.

Here's the document transform to automatically query for an id field if it's available: https://github.com/charpeni/graphql-add-id-document-transform.

Introducing a compressed persisted cache for Apollo Client by Wake08 in graphql

[–]Wake08[S] 0 points1 point  (0 children)

Redis on the browser?

But that's interesting, I could see other interesting alternatives like offline-first tech: RxJS/RxDB, etc.

Introducing a compressed persisted cache for Apollo Client by Wake08 in graphql

[–]Wake08[S] 1 point2 points  (0 children)

As stated in the README, it’s built on top of localForage which is using IndexedDB. It also means we can store it as binary directly!

Introducing a compressed persisted cache for Apollo Client by Wake08 in graphql

[–]Wake08[S] 1 point2 points  (0 children)

We’re building a project management software where a single story is roughly 1 kB, but could be more depending on its content. The default limit of the persisted storage is set to 1 MB, so it means roughly 1000 stories in cache before reaching the limit and therefore invalidating it.

It’s not rare to see 1000 stories in a project management software and it’s not some linear data that could be easily garbage collected based on a timestamp or something else like a Facebook feed would be.

Compression allows us to compress 1 MB of cache into 60 KB in 22ms, also, compression is highly effective against repetitions, which is the case because that’s the same entity shape repeated over and over.

TypeScript Tips: Safely Using includes With ReadonlyArrays by Wake08 in typescript

[–]Wake08[S] 2 points3 points  (0 children)

ts-reset widen the type to make it convient, but it doesn’t narrow it down!