Skip to content

[v10] feat(cache): promise based caching with workers #3245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 274 commits into
base: master
Choose a base branch
from

Conversation

krispya
Copy link
Member

@krispya krispya commented Apr 30, 2024

⚠️Includes breaking change: Removes extensions from useLoader in favor of passing in already extended loader instances.

Caching was hidden behind react-suspend and did not offer any way to utilize browser APIs or extend it. This PR adds PromiseCache class that creates a local cache compatible with React.use backed by the web Cache API. The Cache API offers many benefits such as:

  • Fully integrated with fetch.
  • Allows for caching resources across worker boundaries.
  • Allows for downloading, processing and caching resources inside of a service worker.
  • Allows for client side control over offline caching.
  • Fully inspectable via dev tools

The PromiseCache accesses and processes resources from the global cache while handling promises for you.

// Pass in the name of the global cache that backs it, or the cache itself if you have it.
const cache = new PromiseCache('assets') 
// Fetches resources from a url, caches it, then runs a handler on that data. Returns a promise with the handler's return value.
// ?? Should this just return a blob instead of a blob URL? ??
cache.run(url: string, handler: async (cacheUrl: string) => any)): Promise<any>
// Add a promise.
cache.add(url: string, promise: Promise<any>)
//  Get a promise from the cache.
cache.get(url: string): Promise<any>
// Check if the cache has a url stored.
cache.has(url: string): boolean
// Delete a cached response. Return true if successful, false if unsuccessful.
await cache.delete(url: string): Promise<boolean>

It looks like this when combined with React.use:

const cache = loaderCaches.get(loaderInstance)!

if (!cache.has(url)) cache.run(url, async (cacheUrl) => loadAsset(cacheUrl, loaderInstance))
const result = React.use(cache.get(url)!)

TODO

  • Testing is broken. jest doesn't mock the Cache API or fetch. Trying to polyfill either proved harder than I expected.
  • The API could use some tuning.
  • This should probably get split off into its own library.
  • Make compatible with Node.

krispya and others added 30 commits June 4, 2022 15:29
…ixedStages also has substepDeltas returning an array of deltas for each substep
…alues and now that we have deltas there are useland ways to hanlde this
feat: implement update lifecycle with useUpdate
Copy link

codesandbox-ci bot commented Apr 30, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 5e53956:

Sandbox Source
example Configuration

@krispya
Copy link
Member Author

krispya commented May 2, 2024

  • extensions removed from useLoader.
  • Testing now works. Requires Node 18 or higher since it is using Node's browser-compliant fetch API.

@krispya krispya mentioned this pull request May 2, 2024
18 tasks
@krispya krispya changed the title feat(cache): promise based caching with workers [v9] feat(cache): promise based caching with workers May 3, 2024
@krispya
Copy link
Member Author

krispya commented May 3, 2024

@CodyJasonBennett How can I check if this PR fixes the issue trying to be solved by #3243 ?

@CodyJasonBennett CodyJasonBennett changed the title [v9] feat(cache): promise based caching with workers [v9] feat(cache)!: promise based caching with workers May 3, 2024
@CodyJasonBennett CodyJasonBennett changed the title [v9] feat(cache)!: promise based caching with workers [v9] feat(cache): promise based caching with workers May 3, 2024
@CodyJasonBennett
Copy link
Member

I'll add tests once we can reproduce issues with error boundaries also. I don't expect that to be addressed here.

Comment on lines 113 to 114
// Apply loader extensions
if (extensions) extensions(loader)
Copy link
Member

@CodyJasonBennett CodyJasonBennett May 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to keep this and deopt calls to useLoader with extensions to only cache for the caller component? Can pass React.useId to discern the component.

@CodyJasonBennett CodyJasonBennett changed the title [v9] feat(cache): promise based caching with workers [v10] feat(cache): promise based caching with workers Feb 7, 2025
Base automatically changed from v9 to master February 19, 2025 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants