├── .circleci └── config.yml ├── .gitignore ├── .npmignore ├── .vscode ├── settings.json └── tasks.json ├── .yarnrc.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── codecov.yml ├── docs ├── advanced-usage.md ├── faq.md ├── release.md └── storage-providers.md ├── examples └── web │ ├── .DS_Store │ ├── .gitignore │ ├── index.html │ ├── package.json │ ├── src │ ├── App.module.css │ ├── App.tsx │ ├── main.tsx │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ ├── vite.config.ts │ └── yarn.lock ├── package.json ├── prettier.config.js ├── renovate.json ├── rollup.config.mjs ├── src ├── Cache.ts ├── CachePersistor.ts ├── Log.ts ├── Persistor.ts ├── Storage.ts ├── Trigger.ts ├── __mocks__ │ ├── MockCache.ts │ ├── MockStorage.ts │ ├── MockStorageSync.ts │ └── simulate.ts ├── __tests__ │ ├── Persistor.ts │ ├── Storage.ts │ ├── __snapshots__ │ │ └── persistCache.ts.snap │ ├── persistCache.ts │ └── persistCacheSync.ts ├── index.ts ├── onAppBackground.native.ts ├── onAppBackground.ts ├── onCacheWrite.ts ├── persistCache.ts ├── persistCacheSync.ts ├── storageWrappers │ ├── AsyncStorageWrapper.ts │ ├── IonicStorageWrapper.ts │ ├── LocalForageWrapper.ts │ ├── LocalStorageWrapper.ts │ ├── MMKVStorageWrapper.ts │ ├── MMKVWrapper.ts │ ├── SessionStorageWrapper.ts │ └── index.ts └── types │ └── index.ts ├── tsconfig.cjs.json ├── tsconfig.json └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | secops: apollo/circleci-secops-orb@2.0.7 5 | 6 | workflows: 7 | security-scans: 8 | jobs: 9 | - secops/gitleaks: 10 | context: 11 | - platform-docker-ro 12 | - github-orb 13 | - secops-oidc 14 | git-base-revision: <<#pipeline.git.base_revision>><><> 15 | git-revision: << pipeline.git.revision >> 16 | - secops/semgrep: 17 | context: 18 | - secops-oidc 19 | - github-orb 20 | git-base-revision: <<#pipeline.git.base_revision>><><> 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib 2 | npm 3 | coverage 4 | node_modules 5 | package-lock.json 6 | yarn-error.log 7 | npm-debug.log 8 | .vscode 9 | 10 | .yarn/* 11 | .idea/* -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | tsconfig.cjs.json 2 | tsconfig.json 3 | codecov.yml 4 | renovate.json 5 | rollup.config.mjs 6 | coverage 7 | .vscode 8 | scripts 9 | examples/ 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "command": "tsc", 4 | "isShellCommand": true, 5 | "args": ["-w", "-p", ".", "--noEmit"], 6 | "isBackground": true, 7 | "problemMatcher": "$tsc-watch" 8 | } 9 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [0.15.0](https://github.com/apollographql/apollo-cache-persist/compare/0.14.1...0.15.0) (2024-03-26) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * persist cache on garbage collection ([330a9f4](https://github.com/apollographql/apollo-cache-persist/commit/330a9f4a617a46c95497e4e1db13b1461235436a)) 7 | * **tests:** make tests pass ([e431a56](https://github.com/apollographql/apollo-cache-persist/commit/e431a56c46c3f677d1ef9cdf97e2b8cc6f990fe3)) 8 | 9 | 10 | ### Features 11 | 12 | * add semgrep job ([db674af](https://github.com/apollographql/apollo-cache-persist/commit/db674af5453882c499b1f48edb379fe09d7fe5a4)) 13 | 14 | 15 | 16 | ## [0.14.1](https://github.com/apollographql/apollo-cache-persist/compare/0.14.0...0.14.1) (2022-07-04) 17 | 18 | 19 | ### Bug Fixes 20 | 21 | * **types:** remove unused keys ([5e83d71](https://github.com/apollographql/apollo-cache-persist/commit/5e83d7100ddbe60b833be45df626558c9666ff30)) 22 | 23 | 24 | 25 | # [0.13.0](https://github.com/apollographql/apollo-cache-persist/compare/v0.12.1...v0.13.0) (2021-09-17) 26 | 27 | 28 | ### Features 29 | 30 | * **MMKVWrapper:** Added new storage wrapper ([1b16bdb](https://github.com/apollographql/apollo-cache-persist/commit/1b16bdb00e896f62ee379777f7224a156e16004f)) 31 | 32 | 33 | 34 | ## [0.12.1](https://github.com/apollographql/apollo-cache-persist/compare/v0.12.0...v0.12.1) (2021-08-12) 35 | 36 | 37 | ### Bug Fixes 38 | 39 | * **types:** fix localforage interface ([63f7158](https://github.com/apollographql/apollo-cache-persist/commit/63f71582763b6895c05dd3897117cdfdbb0a70c3)) 40 | 41 | 42 | 43 | # [0.12.0](https://github.com/apollographql/apollo-cache-persist/compare/v0.11.0...v0.12.0) (2021-08-12) 44 | 45 | 46 | ### Bug Fixes 47 | 48 | * **examples:** remove ts-ignore, fix peristenceMapper return type, apply codestyle ([c7619e2](https://github.com/apollographql/apollo-cache-persist/commit/c7619e2dfa6ac4971f845824466180d3c09d9c25)) 49 | * **examples:** use locally built library version instead of published ([8f21bf7](https://github.com/apollographql/apollo-cache-persist/commit/8f21bf79baba89ca2d4f57432ea2b8a928c9acc2)) 50 | * **types:** determine required storage type based on serialize option ([996c831](https://github.com/apollographql/apollo-cache-persist/commit/996c8315c1005c3030b9b814740616b3019daa7b)) 51 | * **types:** MMKV wrapper - remove undefined, normalize to null ([852de5f](https://github.com/apollographql/apollo-cache-persist/commit/852de5f5466f8b7fb2e24d94cc313b286c6bf3b6)) 52 | * **types:** provide simplistic storage interfaces ([56b1c55](https://github.com/apollographql/apollo-cache-persist/commit/56b1c5513505900b8bf87a289994d6fc3505ccd5)), closes [#426](https://github.com/apollographql/apollo-cache-persist/issues/426) [#431](https://github.com/apollographql/apollo-cache-persist/issues/431) 53 | 54 | 55 | 56 | # [0.11.0](https://github.com/apollographql/apollo-cache-persist/compare/0.10.0...0.11.0) (2021-07-29) 57 | 58 | 59 | ### Bug Fixes 60 | 61 | * **examples:** fix typescript compile issues in the react-native example project ([17b513b](https://github.com/apollographql/apollo-cache-persist/commit/17b513b97ef9fd06e3f6dc5d4c1cbd9ba16a52ab)) 62 | 63 | 64 | ### Features 65 | 66 | * **persistor:** add an optional persistence mapper function to allow cache filtration ([dc69b30](https://github.com/apollographql/apollo-cache-persist/commit/dc69b30f2241a7d5077ade116b6c89c21eedc2e5)) 67 | 68 | 69 | 70 | ## [0.10.0](https://github.com/apollographql/apollo-cache-persist/compare/0.9.0...0.10.0) (2020-11-21) 71 | 72 | ### Features 73 | 74 | - allow unserialised data to be written to store ([7bcb322](https://github.com/apollographql/apollo-cache-persist/commit/7bcb322a32aafb088afcf2c21c1ebe793409d8e3)) 75 | 76 | ## [0.9.0](https://github.com/apollographql/apollo-cache-persist/compare/0.2.1...0.9.0) (2020-11-21) 77 | 78 | ### Bug Fixes 79 | 80 | - add example to npm ignore ([45aff6e](https://github.com/apollographql/apollo-cache-persist/commit/45aff6ee38d8f95e9fcfeda74cde08e67913059b)) 81 | - add npm ignore to examples ([734c601](https://github.com/apollographql/apollo-cache-persist/commit/734c601274047bdf81e4015cdcc04604af4a0280)) 82 | - Apollo client peer dependency ([5436da4](https://github.com/apollographql/apollo-cache-persist/commit/5436da48269089a54b3a187b2e326f0443a2b5cf)) 83 | - do not purge in example app ([f45816f](https://github.com/apollographql/apollo-cache-persist/commit/f45816f5ea6377b44c6265ddb3ec72dc36df83a6)) 84 | - example app ([513e561](https://github.com/apollographql/apollo-cache-persist/commit/513e5614e2d5b25dee95b3f44b14a9e27f17b813)) 85 | - loosen apollo-client peer dep ([eeb0e9a](https://github.com/apollographql/apollo-cache-persist/commit/eeb0e9a74bc5c863af362203b44ac4c0b74b9c6b)) 86 | - loosen peer dependency ([67b83dd](https://github.com/apollographql/apollo-cache-persist/commit/67b83ddaa7fd1716a56f5f72faf999e7e06fa1cb)) 87 | - move examples to examples folder ([53d0d77](https://github.com/apollographql/apollo-cache-persist/commit/53d0d770b70bfefe8afbda33b14ffea0ad4e8ca5)) 88 | - rename package ([44009b8](https://github.com/apollographql/apollo-cache-persist/commit/44009b87f49aa97caf2453fc25c374d124c12aca)) 89 | - typings and compilation issues for RN example ([05dac9e](https://github.com/apollographql/apollo-cache-persist/commit/05dac9edcc1bae18e76d6fe3735b96ec4a786a46)) 90 | 91 | ### Features 92 | 93 | - Add trigger for cache.evict and cache.modify, return results of functions ([4881e28](https://github.com/apollographql/apollo-cache-persist/commit/4881e285c519f5bc6e033d3326f1d2cc36f1477d)) 94 | 95 | ## [0.2.1](https://github.com/apollographql/apollo-cache-persist/compare/0.2.0...0.2.1) (2020-08-05) 96 | 97 | ### Bug Fixes 98 | 99 | - export `PersistentStorage` type ([313fd06](https://github.com/apollographql/apollo-cache-persist/commit/313fd066413c613cdc5602cfb0d69bde34b34de4)) 100 | - export persistCacheSync explicitly ([755b94c](https://github.com/apollographql/apollo-cache-persist/commit/755b94cda510bc95c2357e71a803ee48b26284d2)) 101 | - improve logging for persisting information ([878b13b](https://github.com/apollographql/apollo-cache-persist/commit/878b13b080fed2670f2ceb7cdb8199a9d0072a39)) 102 | - minor typo ([a7c785e](https://github.com/apollographql/apollo-cache-persist/commit/a7c785ec958ab8139dfd4f040e578fdd6d207090)) 103 | 104 | ### Features 105 | 106 | - Add ionic support ([8cdf2d2](https://github.com/apollographql/apollo-cache-persist/commit/8cdf2d2483bd34ccaa43eef8522b616f981ab7db)) 107 | 108 | ## [0.2.0](https://github.com/apollographql/apollo-cache-persist/compare/0.0.1...0.2.0) (2019-10-23) 109 | 110 | ### Features 111 | 112 | - Synchronous api 113 | - Storage bugfixing 114 | - Package updates and testing for storage solutions 115 | 116 | ## 0.0.1 (2017-12-01) 117 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Apollo Contributor Guide 2 | 3 | Excited about Apollo and want to make it better? We’re excited too! 4 | 5 | Apollo is a community of developers just like you, striving to create the best 6 | tools and libraries around GraphQL. We welcome anyone who wants to contribute or 7 | provide constructive feedback, no matter the age or level of experience. If you 8 | want to help but don't know where to start, let us know, and we'll find 9 | something for you. 10 | 11 | Oh, and if you haven't already, sign up for the 12 | [Apollo Slack](http://www.apollodata.com/#slack). 13 | 14 | Here are some ways to contribute to the project, from easiest to most difficult: 15 | 16 | - [Reporting bugs](#reporting-bugs) 17 | - [Improving the documentation](#improving-the-documentation) 18 | - [Responding to issues](#responding-to-issues) 19 | - [Small bug fixes](#small-bug-fixes) 20 | - [Suggesting features](#feature-requests) 21 | - [Big pull requests](#big-prs) 22 | 23 | ## Issues 24 | 25 | ### Reporting bugs 26 | 27 | If you encounter a bug, please file an issue on GitHub via the repository of the 28 | sub-project you think contains the bug. If an issue you have is already 29 | reported, please add additional information or add a 👍 reaction to indicate 30 | your agreement. 31 | 32 | While we will try to be as helpful as we can on any issue reported, please 33 | include the following to maximize the chances of a quick fix: 34 | 35 | 1. **Intended outcome:** What you were trying to accomplish when the bug 36 | occurred, and as much code as possible related to the source of the problem. 37 | 2. **Actual outcome:** A description of what actually happened, including a 38 | screenshot or copy-paste of any related error messages, logs, or other output 39 | that might be related. Places to look for information include your browser 40 | console, server console, and network logs. Please avoid non-specific phrases 41 | like “didn’t work” or “broke”. 42 | 3. **How to reproduce the issue:** Instructions for how the issue can be 43 | reproduced by a maintainer or contributor. Be as specific as possible, and 44 | only mention what is necessary to reproduce the bug. If possible, build a 45 | reproduction with our 46 | [error template](https://github.com/apollographql/react-apollo-error-template) 47 | to isolate the exact circumstances in which the bug occurs. Avoid speculation 48 | over what the cause might be. 49 | 50 | Creating a good reproduction really helps contributors investigate and resolve 51 | your issue quickly. In many cases, the act of creating a minimal reproduction 52 | illuminates that the source of the bug was somewhere outside the library in 53 | question, saving time and effort for everyone. 54 | 55 | ### Improving the documentation 56 | 57 | Improving the documentation, examples, and other open source content can be the 58 | easiest way to contribute to the library. If you see a piece of content that can 59 | be better, open a PR with an improvement, no matter how small! If you would like 60 | to suggest a big change or major rewrite, we’d love to hear your ideas but 61 | please open an issue for discussion before writing the PR. 62 | 63 | ### Responding to issues 64 | 65 | In addition to reporting issues, a great way to contribute to Apollo is to 66 | respond to other peoples' issues and try to identify the problem or help them 67 | work around it. If you’re interested in taking a more active role in this 68 | process, please go ahead and respond to issues. And don't forget to say "Hi" on 69 | Apollo Slack! 70 | 71 | ### Small bug fixes 72 | 73 | For a small bug fix change (less than 20 lines of code changed), feel free to 74 | open a pull request. We’ll try to merge it as fast as possible and ideally 75 | publish a new release on the same day. The only requirement is, make sure you 76 | also add a test that verifies the bug you are trying to fix. 77 | 78 | ### Suggesting features 79 | 80 | Most of the features in Apollo came from suggestions by you, the community! We 81 | welcome any ideas about how to make Apollo better for your use case. Unless 82 | there is overwhelming demand for a feature, it might not get implemented 83 | immediately, but please include as much information as possible that will help 84 | people have a discussion about your proposal: 85 | 86 | 1. **Use case:** What are you trying to accomplish, in specific terms? Often, 87 | there might already be a good way to do what you need and a new feature is 88 | unnecessary, but it’s hard to know without information about the specific use 89 | case. 90 | 2. **Could this be a plugin?** In many cases, a feature might be too niche to be 91 | included in the core of a library, and is better implemented as a companion 92 | package. If there isn’t a way to extend the library to do what you want, 93 | could we add additional plugin APIs? It’s important to make the case for why 94 | a feature should be part of the core functionality of the library. 95 | 3. **Is there a workaround?** Is this a more convenient way to do something that 96 | is already possible, or is there some blocker that makes a workaround 97 | unfeasible? 98 | 99 | Feature requests will be labeled as such, and we encourage using GitHub issues 100 | as a place to discuss new features and possible implementation designs. Please 101 | refrain from submitting a pull request to implement a proposed feature until 102 | there is consensus that it should be included. This way, you can avoid putting 103 | in work that can’t be merged in. 104 | 105 | Once there is a consensus on the need for a new feature, proceed as listed below 106 | under “Big PRs”. 107 | 108 | ## Coding Rules 109 | 110 | To ensure consistency throughout the source code, keep these rules in mind as you are working: 111 | 112 | - All features or bug fixes must be tested by one or more specs (unit-tests). 113 | - All public API methods must be documented. 114 | - All commits adhere to the commit message format. 115 | 116 | ### Commit Message Format 117 | 118 | This project utilizes conventional changelog for changelog generation. As such 119 | it's important that your commit messages follow a specific format. The easiest 120 | way to do this is by using either `npx cz` or `yarn run commit` instead of 121 | the conventional `git commit -m "..."`. 122 | 123 | Either of the above methods will bring up a CLI dialog that will walk you 124 | through the process. 125 | 126 | ## Big PRs 127 | 128 | This includes: 129 | 130 | - Big bug fixes 131 | - New features 132 | 133 | For significant changes to a repository, it’s important to settle on a design 134 | before starting on the implementation. This way, we can make sure that major 135 | improvements get the care and attention they deserve. Since big changes can be 136 | risky and might not always get merged, it’s good to reduce the amount of 137 | possible wasted effort by agreeing on an implementation design/plan first. 138 | 139 | 1. **Open an issue.** Open an issue about your bug or feature, as described 140 | above. 141 | 2. **Reach consensus.** Some contributors and community members should reach an 142 | agreement that this feature or bug is important, and that someone should work 143 | on implementing or fixing it. 144 | 3. **Agree on intended behavior.** On the issue, reach an agreement about the 145 | desired behavior. In the case of a bug fix, it should be clear what it means 146 | for the bug to be fixed, and in the case of a feature, it should be clear 147 | what it will be like for developers to use the new feature. 148 | 4. **Agree on implementation plan.** Write a plan for how this feature or bug 149 | fix should be implemented. What modules need to be added or rewritten? Should 150 | this be one pull request or multiple incremental improvements? Who is going 151 | to do each part? 152 | 5. **Submit PR.** In the case where multiple dependent patches need to be made 153 | to implement the change, only submit one at a time. Otherwise, the others 154 | might get stale while the first is reviewed and merged. Make sure to avoid 155 | “while we’re here” type changes - if something isn’t relevant to the 156 | improvement at hand, it should be in a separate PR; this especially includes 157 | code style changes of unrelated code. 158 | 6. **Review.** At least one core contributor should sign off on the change 159 | before it’s merged. Look at the “code review” section below to learn about 160 | factors are important in the code review. If you want to expedite the code 161 | being merged, try to review your own code first! 162 | 7. **Merge and release!** 163 | 164 | ### Code review guidelines 165 | 166 | It’s important that every piece of code in Apollo packages is reviewed by at 167 | least one core contributor familiar with that codebase. Here are some things we 168 | look for: 169 | 170 | 1. **Required CI checks pass.** This is a prerequisite for the review, and it is 171 | the PR author's responsibility. As long as the tests don’t pass, the PR won't 172 | get reviewed. 173 | 2. **Simplicity.** Is this the simplest way to achieve the intended goal? If 174 | there are too many files, redundant functions, or complex lines of code, 175 | suggest a simpler way to do the same thing. In particular, avoid implementing 176 | an overly general solution when a simple, small, and pragmatic fix will do. 177 | 3. **Testing.** Do the tests ensure this code won’t break when other stuff 178 | changes around it? When it does break, will the tests added help us identify 179 | which part of the library has the problem? Did we cover an appropriate set of 180 | edge cases? Look at the test coverage report if there is one. Are all 181 | significant code paths in the new code exercised at least once? 182 | 4. **No unnecessary or unrelated changes.** PRs shouldn’t come with random 183 | formatting changes, especially in unrelated parts of the code. If there is 184 | some refactoring that needs to be done, it should be in a separate PR from a 185 | bug fix or feature, if possible. 186 | 5. **Code has appropriate comments.** Code should be commented, or written in a 187 | clear “self-documenting” way. 188 | 6. **Idiomatic use of the language.** In TypeScript, make sure the typings are 189 | specific and correct. In ES2015, make sure to use imports rather than require 190 | and const instead of var, etc. Ideally a linter enforces a lot of this, but 191 | use your common sense and follow the style of the surrounding code. 192 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 - 2017 Meteor Development Group, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # apollo3-cache-persist [![npm version](https://badge.fury.io/js/apollo3-cache-persist.svg)](https://badge.fury.io/js/apollo3-cache-persist) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) 2 | 3 | Simple persistence for all Apollo Client 3.0 cache implementations, including 4 | [`InMemoryCache`][0] and [`Hermes`][1]. 5 | 6 | Supports web and React Native. [See all storage providers.](./docs/storage-providers.md) 7 | 8 | [0]: https://github.com/apollographql/apollo-client/tree/master/src/cache/inmemory 9 | [1]: https://github.com/convoyinc/apollo-cache-hermes 10 | 11 | 12 | - [Basic Usage](#basic-usage) 13 | - [React Native](#react-native) 14 | - [Web](#web) 15 | - [Storage Providers](./docs/storage-providers.md) 16 | - [Advanced Usage](./docs/advanced-usage.md) 17 | - [FAQ](./docs/faq.md) 18 | - [Contributing](#contributing) 19 | - [Maintainers](#maintainers) 20 | 21 | ## Basic Usage 22 | 23 | ```sh 24 | npm install --save apollo3-cache-persist 25 | ``` 26 | 27 | or 28 | 29 | ```sh 30 | yarn add apollo3-cache-persist 31 | ``` 32 | 33 | To get started, simply pass your Apollo cache and an 34 | [underlying storage provider](./docs/storage-providers.md) to `persistCache`. 35 | 36 | By default, the contents of your Apollo cache will be immediately restored 37 | (asynchronously, see [how to persist data before rendering](./docs/faq.md#how-do-i-wait-for-the-cache-to-be-restored-before-rendering-my-app)), and will be persisted upon every write to the cache (with a 38 | short debounce interval). 39 | 40 | ### Examples 41 | 42 | #### React Native 43 | 44 | ```js 45 | import AsyncStorage from '@react-native-async-storage/async-storage'; 46 | import { InMemoryCache } from '@apollo/client/core'; 47 | import { persistCache, AsyncStorageWrapper } from 'apollo3-cache-persist'; 48 | 49 | const cache = new InMemoryCache({...}); 50 | 51 | // await before instantiating ApolloClient, else queries might run before the cache is persisted 52 | await persistCache({ 53 | cache, 54 | storage: new AsyncStorageWrapper(AsyncStorage), 55 | }); 56 | 57 | // Continue setting up Apollo as usual. 58 | 59 | const client = new ApolloClient({ 60 | cache, 61 | ... 62 | }); 63 | ``` 64 | 65 | #### Web 66 | 67 | ```js 68 | import { InMemoryCache } from '@apollo/client/core'; 69 | import { persistCache, LocalStorageWrapper } from 'apollo3-cache-persist'; 70 | 71 | const cache = new InMemoryCache({...}); 72 | 73 | // await before instantiating ApolloClient, else queries might run before the cache is persisted 74 | await persistCache({ 75 | cache, 76 | storage: new LocalStorageWrapper(window.localStorage), 77 | }); 78 | 79 | // Continue setting up Apollo as usual. 80 | 81 | const client = new ApolloClient({ 82 | cache, 83 | ... 84 | }); 85 | ``` 86 | 87 | See a complete example in the [web example](./examples/web/src/App.tsx). 88 | 89 | ## Contributing 90 | 91 | Want to make the project better? Awesome! Please read through our [Contributing Guidelines](./CONTRIBUTING.md). 92 | 93 | ## Maintainers 94 | 95 | We all do this for free... so please be nice 😁. 96 | 97 | - [@wtrocki](https://github.com/wtrocki) 98 | - [@wodCZ](https://github.com/wodCZ) 99 | - [@jspizziri](https://github.com/jspizziri) 100 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | parsers: 3 | javascript: 4 | enable_partials: yes 5 | status: 6 | project: 7 | default: 8 | target: "60%" 9 | patch: 10 | enabled: false 11 | -------------------------------------------------------------------------------- /docs/advanced-usage.md: -------------------------------------------------------------------------------- 1 | # Advanced Usage 2 | 3 | - [Additional Options](#additional-options) 4 | - [Using `CachePersistor`](#using-cachepersistor) 5 | - [Custom Triggers](#custom-triggers) 6 | 7 | ## Additional Options 8 | 9 | `persistCache` and the constructor for `CachePersistor` accept the following 10 | options: 11 | 12 | ```ts 13 | persistCache({ 14 | /** 15 | * Required options. 16 | */ 17 | 18 | // Reference to your Apollo cache. 19 | cache: ApolloCache, 20 | 21 | // Reference to your storage provider wrapped in a storage wrapper implementing PersistentStorage interface. 22 | storage: PersistentStorage, 23 | 24 | /** 25 | * Trigger options. 26 | */ 27 | 28 | // When to persist the cache. 29 | // 30 | // 'write': Persist upon every write to the cache. Default. 31 | // 'background': Persist when your app moves to the background. React Native only. 32 | // 33 | // For a custom trigger, provide a function. See below for more information. 34 | // To disable automatic persistence and manage persistence manually, provide false. 35 | trigger?: 'write' | 'background' | function | false, 36 | 37 | // Debounce interval between persists (in ms). 38 | // Defaults to 0 for 'background' and 1000 for 'write' and custom triggers. 39 | debounce?: number, 40 | 41 | /** 42 | * Storage options. 43 | */ 44 | 45 | // Key to use with the storage provider. Defaults to 'apollo-cache-persist'. 46 | key?: string, 47 | 48 | // Whether to serialize to JSON before/after persisting. Defaults to true. 49 | serialize?: boolean, 50 | 51 | // Maximum size of cache to persist (in bytes). 52 | // Defaults to 1048576 (1 MB). For unlimited cache size, provide false. 53 | // If exceeded, persistence will pause and app will start up cold on next launch. 54 | maxSize?: number | false, 55 | 56 | /** 57 | * Debugging options. 58 | */ 59 | 60 | // Enable console logging. 61 | debug?: boolean, 62 | 63 | }): Promise; 64 | ``` 65 | 66 | ## Using `CachePersistor` 67 | 68 | Instead of using `persistCache`, you can instantiate a `CachePersistor`, which 69 | will give you fine-grained control of persistence. 70 | 71 | `CachePersistor` accepts the same options as `persistCache` and returns an 72 | object with the following methods: 73 | 74 | ```js 75 | const persistor = new CachePersistor({...}); 76 | 77 | persistor.restore(); // Immediately restore the cache. Returns a Promise. 78 | persistor.persist(); // Immediately persist the cache. Returns a Promise. 79 | persistor.purge(); // Immediately purge the stored cache. Returns a Promise. 80 | 81 | persistor.pause(); // Pause persistence. Triggers are ignored while paused. 82 | persistor.resume(); // Resume persistence. 83 | persistor.remove(); // Remove the persistence trigger. Manual persistence required after calling this. 84 | 85 | // Obtain the most recent 30 persistor loglines. 86 | // `print: true` will print them to the console; `false` will return an array. 87 | persistor.getLogs(print); 88 | 89 | // Obtain the current persisted cache size in bytes. Returns a Promise. 90 | // Resolves to 0 for empty and `null` when `serialize: true` is in use. 91 | persistor.getSize(); 92 | ``` 93 | 94 | Additionally, you can control what portions of your cache are persisted by passing 95 | a `persistenceMapper` function as an optional parameter to the `CachePersistor`. E.g. 96 | 97 | ```ts 98 | const persistor = new CachePersistor({ 99 | ... 100 | persistenceMapper: async (data: any) => { 101 | // filter your cached data and queries 102 | return filteredData; 103 | }, 104 | }) 105 | ``` 106 | 107 | ## Custom Triggers 108 | 109 | For control over persistence timing, provide a function to the `trigger` option. 110 | 111 | The custom trigger should accept one argument (a `persist` callback function), 112 | and it should return a function that can be called to uninstall the trigger. 113 | 114 | The TypeScript signature for this function is as follows: 115 | 116 | ```ts 117 | (persist: () => void) => (() => void) 118 | ``` 119 | 120 | For example, this custom trigger will persist every 10 seconds: 121 | 122 | ```js 123 | // This code is for illustration only. 124 | // We do not recommend persisting on an interval. 125 | 126 | const trigger = persist => { 127 | // Call `persist` every 10 seconds. 128 | const interval = setInterval(persist, 10000); 129 | 130 | // Return function to uninstall this custom trigger. 131 | return () => clearInterval(interval); 132 | }; 133 | ``` 134 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | - [Why is the 'background' trigger only available for React Native?](#why-is-the-background-trigger-only-available-for-React-Native) 4 | - [How do I wait for the cache to be restored before rendering my app?](#how-do-i-wait-for-the-cache-to-be-restored-before-rendering-my-app) 5 | - [React Using Hooks](#react-using-hooks) 6 | - [Using Synchronous Storage API](#using-synchronous-storage-api) 7 | - [I need to ensure certain data is not persisted. How do I filter my cache?](#i-need-to-ensure-certain-data-is-not-persisted-how-do-I-filter-my-cache) 8 | - [I've had a breaking schema change. How do I migrate or purge my cache?](#ive-had-a-breaking-schema-change-how-do-i-migrate-or-purge-my-cache) 9 | - [I'm seeing errors on Android.](#im-seeing-errors-on-android) 10 | - [Cache persist and changing user context](#cache-persist-and-changing-user-context) 11 | 12 | ## Why is the 'background' trigger only available for React Native? 13 | 14 | Quite simply, because mobile apps are different from web apps. 15 | 16 | Mobile apps are rarely terminated before transitioning to the background. This 17 | is helped by the fact that an app is moved to the background whenever the user 18 | returns home, activates the multitasking view, or follows a link to another app. 19 | There's almost always an opportunity to persist. 20 | 21 | On web, we _could_ support a 'background' trigger with the 22 | [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API); 23 | however, data would be lost if the user closed the tab/window directly. Given 24 | this prevalence of this user behavior and the substantially better performance 25 | of the 'write' trigger on web, we've omitted a 'background' trigger on web. 26 | 27 | ## How do I wait for the cache to be restored before rendering my app? 28 | 29 | `persistCache` (as well as `persistor.restore()`) returns a promise that will 30 | resolve once the cache has been restored, which you can await before rendering 31 | your app. 32 | 33 | This library, like Apollo Client, is framework-agnostic; however, since many 34 | people have asked, here's an example of how to handle this in React. PRs with 35 | examples from other frameworks are welcome. 36 | 37 | You can find all examples in the [examples](./../examples) directory. 38 | 39 | ## React Using Hooks 40 | 41 | ```js 42 | import React, { useEffect, useState } from 'react'; 43 | 44 | import { ApolloClient, ApolloProvider } from '@apollo/client'; 45 | import { InMemoryCache } from '@apollo/client/core'; 46 | import { LocalStorageWrapper, persistCache } from 'apollo3-cache-persist'; 47 | 48 | const App = () => { 49 | const [client, setClient] = useState(); 50 | 51 | useEffect(() => { 52 | async function init() { 53 | const cache = new InMemoryCache(); 54 | await persistCache({ 55 | cache, 56 | storage: new LocalStorageWrapper(window.localStorage), 57 | }); 58 | setClient( 59 | new ApolloClient({ 60 | cache, 61 | }), 62 | ); 63 | } 64 | 65 | init().catch(console.error); 66 | }, []); 67 | 68 | if (!client) { 69 | return

Initializing app...

; 70 | } 71 | 72 | return ( 73 | 74 | {/* the rest of your app goes here */} 75 | 76 | ); 77 | }; 78 | 79 | export default App; 80 | ``` 81 | 82 | ## Using Synchronous Storage API 83 | 84 | `persistCache` method is asynchronous to conform to production ready storage interfaces 85 | which offer only asynchronous API. 86 | 87 | apollo-cache-persist offers alternative `persistCacheSync` method that should be used only with small cache sizes and synchronous storage provider (e.g. window.localStorage). `persistCacheSync` is best suited for demo applications because it blocks UI rendering until the cache is restored. 88 | 89 | ```js 90 | import { InMemoryCache } from '@apollo/client/core'; 91 | import { persistCacheSync, LocalStorageWrapper } from 'apollo3-cache-persist'; 92 | 93 | const cache = new InMemoryCache({...}); 94 | 95 | persistCacheSync({ 96 | cache, 97 | storage: new LocalStorageWrapper(window.localStorage), 98 | }); 99 | ``` 100 | 101 | `persistCacheSync` works by instantiating subclasses of `CachePeristor`, `Persistor`, and `Storage` that implement a method for restoring the cache synchronously. 102 | 103 | ## I need to ensure certain data is not persisted. How do I filter my cache? 104 | 105 | You can optionally pass a `persistenceMapper` function to the `CachePersistor` which 106 | will allow you to control what parts of the Apollo Client cache get persisted. Please 107 | refer to the [Advanced Usage of the `CachePersistor`](https://github.com/apollographql/apollo-cache-persist/blob/master/docs/advanced-usage.md#using-cachepersistor) for more 108 | details. 109 | 110 | Other alternatives have been recommended in 111 | [#2](https://github.com/apollographql/apollo3-cache-persist/issues/2#issuecomment-350823835), 112 | including using logic in your UI to filter potentially-outdated information. 113 | Furthermore, the `maxSize` option and methods on `CachePersistor` provide facilities to 114 | manage the growth of the cache. 115 | 116 | For total control over the cache contents, you can setup a background task to 117 | periodically reset the cache to contain only your app’s most important data. (On 118 | the web, you can use a service worker; on React Native, there’s 119 | [`react-native-background-task`](https://github.com/jamesisaac/react-native-background-task).) 120 | The background task would start with an empty cache, query the most important 121 | data from your GraphQL API, and then persist. This strategy has the added 122 | benefit of ensuring the cache is loaded with fresh data when your app launches. 123 | 124 | ## I've had a breaking schema change. How do I migrate or purge my cache? 125 | 126 | For the same reasons given in the preceding answer, it's not possible to migrate 127 | or transform your persisted cache data. However, by using the 128 | methods on `CachePersistor`, it's simple to reset the 129 | cache upon changes to the schema. 130 | 131 | Simply instantiate a `CachePersistor` and only call `restore()` if the app's 132 | schema hasn't changed. (You'll need to track your schema version yourself.) 133 | 134 | Here's an example of how this could look: 135 | 136 | ```js 137 | import AsyncStorage from '@react-native-community/async-storage'; 138 | import { InMemoryCache } from '@apollo/client/core'; 139 | import { CachePersistor, AsyncStorageWrapper } from 'apollo3-cache-persist'; 140 | 141 | const SCHEMA_VERSION = '3'; // Must be a string. 142 | const SCHEMA_VERSION_KEY = 'apollo-schema-version'; 143 | 144 | async function setupApollo() { 145 | const cache = new InMemoryCache({...}); 146 | 147 | const persistor = new CachePersistor({ 148 | cache, 149 | storage: new AsyncStorageWrapper(AsyncStorage), 150 | }); 151 | 152 | // Read the current schema version from AsyncStorage. 153 | const currentVersion = await AsyncStorage.getItem(SCHEMA_VERSION_KEY); 154 | 155 | if (currentVersion === SCHEMA_VERSION) { 156 | // If the current version matches the latest version, 157 | // we're good to go and can restore the cache. 158 | await persistor.restore(); 159 | } else { 160 | // Otherwise, we'll want to purge the outdated persisted cache 161 | // and mark ourselves as having updated to the latest version. 162 | await persistor.purge(); 163 | await AsyncStorage.setItem(SCHEMA_VERSION_KEY, SCHEMA_VERSION); 164 | } 165 | 166 | // Continue setting up Apollo as usual. 167 | } 168 | ``` 169 | 170 | ## I'm seeing errors on Android. 171 | 172 | Specifically, this error: 173 | 174 | ``` 175 | BaseError: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 176 | ``` 177 | 178 | This is the result of a 2 MB per key limitation of `AsyncStorage` on Android. 179 | Set a smaller `maxSize` or switch to a different storage provider, such 180 | as 181 | [`redux-persist-fs-storage`](https://github.com/leethree/redux-persist-fs-storage) or [`react-native-mmkv-storage`](https://github.com/ammarahm-ed/react-native-mmkv-storage). 182 | 183 | ## Cache persist and changing user context 184 | 185 | In some cases like user logout we want to wipe out application cache. 186 | To do it effectively with Apollo Cache Persist please use `client.clearStore()` method that will 187 | eventually reset persistence layer. 188 | -------------------------------------------------------------------------------- /docs/release.md: -------------------------------------------------------------------------------- 1 | # Release 2 | 3 | The standard release command for this project is: 4 | 5 | ```sh 6 | yarn version [--new-version | --major | --minor | --patch] 7 | ``` 8 | 9 | This command will: 10 | 11 | 1. Generate/update the Changelog 12 | 1. Bump the package version 13 | 1. Tag & pushing the commit 14 | 1. Publish the package to NPM (assuming you are logged in to NPM and have the correct access) 15 | 16 | e.g. 17 | 18 | ```sh 19 | yarn version --patch // 1.0.0 -> 1.0.1 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/storage-providers.md: -------------------------------------------------------------------------------- 1 | ## Storage Providers 2 | 3 | - [Natively Supported Providers](#natively-supported-providers) 4 | - [Redux Persist Providers](#redux-persist-providers) 5 | - [`AsyncStorage` Caveat](#asyncstorage-caveat) 6 | - [Using other storage providers](#using-other-storage-providers) 7 | 8 | ## Natively Supported Providers 9 | 10 | `apollo3-cache-persist` provides wrappers for the following storage providers, with no additional dependencies: 11 | 12 | | Storage provider | Platform | Wrapper class | 13 | | ------------------------------------------------------------------------------- | -------------- | ----------------------- | 14 | | [`AsyncStorage`](https://github.com/react-native-async-storage/async-storage)\* | React Native | `AsyncStorageWrapper` | 15 | | `window.localStorage` | web | `LocalStorageWrapper` | 16 | | `window.sessionStorage` | web | `SessionStorageWrapper` | 17 | | [`localForage`](https://github.com/localForage/localForage) | web | `LocalForageWrapper` | 18 | | [`Ionic storage`](https://ionicframework.com/docs/building/storage) | web and mobile | `IonicStorageWrapper` | 19 | | [`MMKV Storage`](https://github.com/ammarahm-ed/react-native-mmkv-storage) | React Native | `MMKVStorageWrapper` | 20 | | [`MMKV`](https://github.com/mrousavy/react-native-mmkv) | React Native | `MMKVWrapper` | 21 | 22 | 23 | ## Redux Persist Providers 24 | `apollo3-cache-persist` uses the same storage provider API as 25 | [`redux-persist`](https://github.com/rt2zz/redux-persist), so you can also make 26 | use of the providers 27 | [listed here](https://github.com/rt2zz/redux-persist#storage-engines), 28 | including: 29 | 30 | - [`redux-persist-node-storage`](https://github.com/pellejacobs/redux-persist-node-storage) 31 | - [`redux-persist-fs-storage`](https://github.com/leethree/redux-persist-fs-storage) 32 | - [`redux-persist-cookie-storage`](https://github.com/abersager/redux-persist-cookie-storage) 33 | 34 | 35 | ## `AsyncStorage` Caveat 36 | \*`AsyncStorage` 37 | [does not support](https://github.com/facebook/react-native/issues/12529#issuecomment-345326643) 38 | individual values in excess of 2 MB on Android. If you set `maxSize` to more than 2 MB or to `false`, 39 | use a different storage provider, such as 40 | [`react-native-mmkv-storage`](https://github.com/ammarahm-ed/react-native-mmkv-storage) or 41 | [`redux-persist-fs-storage`](https://github.com/leethree/redux-persist-fs-storage). 42 | 43 | ## Using other storage providers 44 | 45 | `apollo3-cache-persist` supports stable versions of storage providers mentioned above. 46 | If you want to use other storage provider, or there's a breaking change in `next` version of supported provider, 47 | you can create your own wrapper. For an example of a simple wrapper have a look at [`AsyncStorageWrapper`](/src/storageWrappers/AsyncStorageWrapper.ts). 48 | 49 | If you found that stable version of supported provider is no-longer compatible, please [submit an issue or a Pull Request](https://github.com/apollographql/apollo-cache-persist/blob/master/CONTRIBUTING.md#issues). 50 | -------------------------------------------------------------------------------- /examples/web/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apollographql/apollo-cache-persist/719048da47f9a3885598c3093d02bd1f106bc2de/examples/web/.DS_Store -------------------------------------------------------------------------------- /examples/web/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | .yarn -------------------------------------------------------------------------------- /examples/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Apollo Cache Persist example 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic-apollo-app", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@apollo/client": "^3.9.9", 13 | "apollo3-cache-persist": "file:../../lib", 14 | "graphql": "^16.8.1", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.2.71", 20 | "@types/react-dom": "^18.2.22", 21 | "@vitejs/plugin-react": "^4.2.1", 22 | "typescript": "^5.4.3", 23 | "vite": "^5.2.6" 24 | }, 25 | "packageManager": "yarn@4.1.1", 26 | "resolutions": { 27 | "apollo3-cache-persist": "portal:../.." 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/web/src/App.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | display: flex; 3 | } 4 | .content { 5 | flex: 1; 6 | padding: 20px; 7 | } 8 | .controls { 9 | flex: 1; 10 | padding: 20px; 11 | } 12 | .item { 13 | padding: 10px; 14 | } 15 | -------------------------------------------------------------------------------- /examples/web/src/App.tsx: -------------------------------------------------------------------------------- 1 | import {useCallback, useEffect, useState} from 'react' 2 | 3 | 4 | import { 5 | ApolloClient, 6 | ApolloProvider, 7 | NormalizedCacheObject, 8 | useQuery, 9 | } from '@apollo/client'; 10 | import gql from 'graphql-tag'; 11 | import { InMemoryCache } from '@apollo/client/core'; 12 | import { CachePersistor, LocalStorageWrapper } from 'apollo3-cache-persist'; 13 | import styles from './App.module.css'; 14 | 15 | const episodesGQL = gql` 16 | query episodes { 17 | episodes { 18 | results { 19 | episode 20 | id 21 | name 22 | air_date 23 | } 24 | } 25 | } 26 | `; 27 | 28 | type EpisodesQuery = { 29 | episodes: { 30 | results: { 31 | episode: string; 32 | id: string; 33 | name: string; 34 | air_date: string; 35 | }[]; 36 | } 37 | }; 38 | 39 | const Launches = () => { 40 | const { error, data, loading } = useQuery(episodesGQL, { 41 | fetchPolicy: 'cache-and-network', 42 | }); 43 | 44 | if (!data) { 45 | // we don't have data yet 46 | 47 | if (loading) { 48 | // but we're loading some 49 | return

Loading initial data...

; 50 | } 51 | if (error) { 52 | // and we have an error 53 | return

Error loading data :(

; 54 | } 55 | return

Unknown error :(

; 56 | } 57 | 58 | return ( 59 |
60 | {loading ?

Loading fresh data...

: null} 61 | {data.episodes.results.map(episode => ( 62 |
63 | {episode.episode}: {episode.name} 64 |
65 | {episode.air_date} 66 |
67 | ))} 68 |
69 | ); 70 | }; 71 | 72 | const App = () => { 73 | const [client, setClient] = useState>(); 74 | const [persistor, setPersistor] = useState< 75 | CachePersistor 76 | >(); 77 | 78 | useEffect(() => { 79 | async function init() { 80 | const cache = new InMemoryCache(); 81 | let newPersistor = new CachePersistor({ 82 | cache, 83 | storage: new LocalStorageWrapper(window.localStorage), 84 | debug: true, 85 | trigger: 'write', 86 | }); 87 | await newPersistor.restore(); 88 | setPersistor(newPersistor); 89 | setClient( 90 | new ApolloClient({ 91 | uri: 'https://rickandmortyapi.com/graphql', 92 | cache, 93 | }), 94 | ); 95 | } 96 | 97 | init().catch(console.error); 98 | }, []); 99 | 100 | const clearCache = useCallback(() => { 101 | if (!persistor) { 102 | return; 103 | } 104 | persistor.purge(); 105 | }, [persistor]); 106 | 107 | const reload = useCallback(() => { 108 | window.location.reload(); 109 | }, []); 110 | 111 | if (!client) { 112 | return

Initializing app...

; 113 | } 114 | 115 | return ( 116 | 117 |
118 |
119 | 120 |
121 |
122 |

Example controls

123 |

Use the following buttons to control apollo3-cache-persist.

124 |

125 | Once you've loaded the initial data, you should see "Loading fresh 126 | data" followed by the list of cached Launches every time you reload 127 | the page. 128 |

129 |

130 | Clear cache should remove everything from the localstorage, so that 131 | when you reload the page, you should see "Loading initial data..." 132 | for a moment. 133 |

134 |

135 | Debugging output is enabled,{' '} 136 | make sure to open Developer console to see what's 137 | going on. You can see the cached data under{' '} 138 | Application → Local Storage. 139 |

140 | 141 | 142 |
143 |
144 |
145 | ); 146 | }; 147 | 148 | export default App 149 | -------------------------------------------------------------------------------- /examples/web/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | 5 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /examples/web/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /examples/web/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/web/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /examples/web/yarn.lock: -------------------------------------------------------------------------------- 1 | # This file is generated by running "yarn install" inside your project. 2 | # Manual changes might be lost - proceed with caution! 3 | 4 | __metadata: 5 | version: 8 6 | cacheKey: 10c0 7 | 8 | "@ampproject/remapping@npm:^2.2.0": 9 | version: 2.3.0 10 | resolution: "@ampproject/remapping@npm:2.3.0" 11 | dependencies: 12 | "@jridgewell/gen-mapping": "npm:^0.3.5" 13 | "@jridgewell/trace-mapping": "npm:^0.3.24" 14 | checksum: 10c0/81d63cca5443e0f0c72ae18b544cc28c7c0ec2cea46e7cb888bb0e0f411a1191d0d6b7af798d54e30777d8d1488b2ec0732aac2be342d3d7d3ffd271c6f489ed 15 | languageName: node 16 | linkType: hard 17 | 18 | "@apollo/client@npm:^3.9.9": 19 | version: 3.9.9 20 | resolution: "@apollo/client@npm:3.9.9" 21 | dependencies: 22 | "@graphql-typed-document-node/core": "npm:^3.1.1" 23 | "@wry/caches": "npm:^1.0.0" 24 | "@wry/equality": "npm:^0.5.6" 25 | "@wry/trie": "npm:^0.5.0" 26 | graphql-tag: "npm:^2.12.6" 27 | hoist-non-react-statics: "npm:^3.3.2" 28 | optimism: "npm:^0.18.0" 29 | prop-types: "npm:^15.7.2" 30 | rehackt: "npm:0.0.6" 31 | response-iterator: "npm:^0.2.6" 32 | symbol-observable: "npm:^4.0.0" 33 | ts-invariant: "npm:^0.10.3" 34 | tslib: "npm:^2.3.0" 35 | zen-observable-ts: "npm:^1.2.5" 36 | peerDependencies: 37 | graphql: ^15.0.0 || ^16.0.0 38 | graphql-ws: ^5.5.5 39 | react: ^16.8.0 || ^17.0.0 || ^18.0.0 40 | react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 41 | subscriptions-transport-ws: ^0.9.0 || ^0.11.0 42 | peerDependenciesMeta: 43 | graphql-ws: 44 | optional: true 45 | react: 46 | optional: true 47 | react-dom: 48 | optional: true 49 | subscriptions-transport-ws: 50 | optional: true 51 | checksum: 10c0/133e866eeebaceeb8f059d9bde3884f6c362f78d0aa9f4c1c51034af39259b0db154ec77c96fdad28fd7bc3b82ba920586d29aed1920933fabd2c5188b51a2b9 52 | languageName: node 53 | linkType: hard 54 | 55 | "@babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.1, @babel/code-frame@npm:^7.24.2": 56 | version: 7.24.2 57 | resolution: "@babel/code-frame@npm:7.24.2" 58 | dependencies: 59 | "@babel/highlight": "npm:^7.24.2" 60 | picocolors: "npm:^1.0.0" 61 | checksum: 10c0/d1d4cba89475ab6aab7a88242e1fd73b15ecb9f30c109b69752956434d10a26a52cbd37727c4eca104b6d45227bd1dfce39a6a6f4a14c9b2f07f871e968cf406 62 | languageName: node 63 | linkType: hard 64 | 65 | "@babel/compat-data@npm:^7.23.5": 66 | version: 7.24.1 67 | resolution: "@babel/compat-data@npm:7.24.1" 68 | checksum: 10c0/8a1935450345c326b14ea632174696566ef9b353bd0d6fb682456c0774342eeee7654877ced410f24a731d386fdcbf980b75083fc764964d6f816b65792af2f5 69 | languageName: node 70 | linkType: hard 71 | 72 | "@babel/core@npm:^7.23.5": 73 | version: 7.24.3 74 | resolution: "@babel/core@npm:7.24.3" 75 | dependencies: 76 | "@ampproject/remapping": "npm:^2.2.0" 77 | "@babel/code-frame": "npm:^7.24.2" 78 | "@babel/generator": "npm:^7.24.1" 79 | "@babel/helper-compilation-targets": "npm:^7.23.6" 80 | "@babel/helper-module-transforms": "npm:^7.23.3" 81 | "@babel/helpers": "npm:^7.24.1" 82 | "@babel/parser": "npm:^7.24.1" 83 | "@babel/template": "npm:^7.24.0" 84 | "@babel/traverse": "npm:^7.24.1" 85 | "@babel/types": "npm:^7.24.0" 86 | convert-source-map: "npm:^2.0.0" 87 | debug: "npm:^4.1.0" 88 | gensync: "npm:^1.0.0-beta.2" 89 | json5: "npm:^2.2.3" 90 | semver: "npm:^6.3.1" 91 | checksum: 10c0/e6e756b6de27d0312514a005688fa1915c521ad4269a388913eff2120a546538078f8488d6d16e86f851872f263cb45a6bbae08738297afb9382600d2ac342a9 92 | languageName: node 93 | linkType: hard 94 | 95 | "@babel/generator@npm:^7.24.1": 96 | version: 7.24.1 97 | resolution: "@babel/generator@npm:7.24.1" 98 | dependencies: 99 | "@babel/types": "npm:^7.24.0" 100 | "@jridgewell/gen-mapping": "npm:^0.3.5" 101 | "@jridgewell/trace-mapping": "npm:^0.3.25" 102 | jsesc: "npm:^2.5.1" 103 | checksum: 10c0/f0eea7497657cdf68cfb4b7d181588e1498eefd1f303d73b0d8ca9b21a6db27136a6f5beb8f988b6bdcd4249870826080950450fd310951de42ecf36df274881 104 | languageName: node 105 | linkType: hard 106 | 107 | "@babel/helper-compilation-targets@npm:^7.23.6": 108 | version: 7.23.6 109 | resolution: "@babel/helper-compilation-targets@npm:7.23.6" 110 | dependencies: 111 | "@babel/compat-data": "npm:^7.23.5" 112 | "@babel/helper-validator-option": "npm:^7.23.5" 113 | browserslist: "npm:^4.22.2" 114 | lru-cache: "npm:^5.1.1" 115 | semver: "npm:^6.3.1" 116 | checksum: 10c0/ba38506d11185f48b79abf439462ece271d3eead1673dd8814519c8c903c708523428806f05f2ec5efd0c56e4e278698fac967e5a4b5ee842c32415da54bc6fa 117 | languageName: node 118 | linkType: hard 119 | 120 | "@babel/helper-environment-visitor@npm:^7.22.20": 121 | version: 7.22.20 122 | resolution: "@babel/helper-environment-visitor@npm:7.22.20" 123 | checksum: 10c0/e762c2d8f5d423af89bd7ae9abe35bd4836d2eb401af868a63bbb63220c513c783e25ef001019418560b3fdc6d9a6fb67e6c0b650bcdeb3a2ac44b5c3d2bdd94 124 | languageName: node 125 | linkType: hard 126 | 127 | "@babel/helper-function-name@npm:^7.23.0": 128 | version: 7.23.0 129 | resolution: "@babel/helper-function-name@npm:7.23.0" 130 | dependencies: 131 | "@babel/template": "npm:^7.22.15" 132 | "@babel/types": "npm:^7.23.0" 133 | checksum: 10c0/d771dd1f3222b120518176733c52b7cadac1c256ff49b1889dbbe5e3fed81db855b8cc4e40d949c9d3eae0e795e8229c1c8c24c0e83f27cfa6ee3766696c6428 134 | languageName: node 135 | linkType: hard 136 | 137 | "@babel/helper-hoist-variables@npm:^7.22.5": 138 | version: 7.22.5 139 | resolution: "@babel/helper-hoist-variables@npm:7.22.5" 140 | dependencies: 141 | "@babel/types": "npm:^7.22.5" 142 | checksum: 10c0/60a3077f756a1cd9f14eb89f0037f487d81ede2b7cfe652ea6869cd4ec4c782b0fb1de01b8494b9a2d2050e3d154d7d5ad3be24806790acfb8cbe2073bf1e208 143 | languageName: node 144 | linkType: hard 145 | 146 | "@babel/helper-module-imports@npm:^7.22.15": 147 | version: 7.24.3 148 | resolution: "@babel/helper-module-imports@npm:7.24.3" 149 | dependencies: 150 | "@babel/types": "npm:^7.24.0" 151 | checksum: 10c0/052c188adcd100f5e8b6ff0c9643ddaabc58b6700d3bbbc26804141ad68375a9f97d9d173658d373d31853019e65f62610239e3295cdd58e573bdcb2fded188d 152 | languageName: node 153 | linkType: hard 154 | 155 | "@babel/helper-module-transforms@npm:^7.23.3": 156 | version: 7.23.3 157 | resolution: "@babel/helper-module-transforms@npm:7.23.3" 158 | dependencies: 159 | "@babel/helper-environment-visitor": "npm:^7.22.20" 160 | "@babel/helper-module-imports": "npm:^7.22.15" 161 | "@babel/helper-simple-access": "npm:^7.22.5" 162 | "@babel/helper-split-export-declaration": "npm:^7.22.6" 163 | "@babel/helper-validator-identifier": "npm:^7.22.20" 164 | peerDependencies: 165 | "@babel/core": ^7.0.0 166 | checksum: 10c0/211e1399d0c4993671e8e5c2b25383f08bee40004ace5404ed4065f0e9258cc85d99c1b82fd456c030ce5cfd4d8f310355b54ef35de9924eabfc3dff1331d946 167 | languageName: node 168 | linkType: hard 169 | 170 | "@babel/helper-plugin-utils@npm:^7.24.0": 171 | version: 7.24.0 172 | resolution: "@babel/helper-plugin-utils@npm:7.24.0" 173 | checksum: 10c0/90f41bd1b4dfe7226b1d33a4bb745844c5c63e400f9e4e8bf9103a7ceddd7d425d65333b564d9daba3cebd105985764d51b4bd4c95822b97c2e3ac1201a8a5da 174 | languageName: node 175 | linkType: hard 176 | 177 | "@babel/helper-simple-access@npm:^7.22.5": 178 | version: 7.22.5 179 | resolution: "@babel/helper-simple-access@npm:7.22.5" 180 | dependencies: 181 | "@babel/types": "npm:^7.22.5" 182 | checksum: 10c0/f0cf81a30ba3d09a625fd50e5a9069e575c5b6719234e04ee74247057f8104beca89ed03e9217b6e9b0493434cedc18c5ecca4cea6244990836f1f893e140369 183 | languageName: node 184 | linkType: hard 185 | 186 | "@babel/helper-split-export-declaration@npm:^7.22.6": 187 | version: 7.22.6 188 | resolution: "@babel/helper-split-export-declaration@npm:7.22.6" 189 | dependencies: 190 | "@babel/types": "npm:^7.22.5" 191 | checksum: 10c0/d83e4b623eaa9622c267d3c83583b72f3aac567dc393dda18e559d79187961cb29ae9c57b2664137fc3d19508370b12ec6a81d28af73a50e0846819cb21c6e44 192 | languageName: node 193 | linkType: hard 194 | 195 | "@babel/helper-string-parser@npm:^7.23.4": 196 | version: 7.24.1 197 | resolution: "@babel/helper-string-parser@npm:7.24.1" 198 | checksum: 10c0/2f9bfcf8d2f9f083785df0501dbab92770111ece2f90d120352fda6dd2a7d47db11b807d111e6f32aa1ba6d763fe2dc6603d153068d672a5d0ad33ca802632b2 199 | languageName: node 200 | linkType: hard 201 | 202 | "@babel/helper-validator-identifier@npm:^7.22.20": 203 | version: 7.22.20 204 | resolution: "@babel/helper-validator-identifier@npm:7.22.20" 205 | checksum: 10c0/dcad63db345fb110e032de46c3688384b0008a42a4845180ce7cd62b1a9c0507a1bed727c4d1060ed1a03ae57b4d918570259f81724aaac1a5b776056f37504e 206 | languageName: node 207 | linkType: hard 208 | 209 | "@babel/helper-validator-option@npm:^7.23.5": 210 | version: 7.23.5 211 | resolution: "@babel/helper-validator-option@npm:7.23.5" 212 | checksum: 10c0/af45d5c0defb292ba6fd38979e8f13d7da63f9623d8ab9ededc394f67eb45857d2601278d151ae9affb6e03d5d608485806cd45af08b4468a0515cf506510e94 213 | languageName: node 214 | linkType: hard 215 | 216 | "@babel/helpers@npm:^7.24.1": 217 | version: 7.24.1 218 | resolution: "@babel/helpers@npm:7.24.1" 219 | dependencies: 220 | "@babel/template": "npm:^7.24.0" 221 | "@babel/traverse": "npm:^7.24.1" 222 | "@babel/types": "npm:^7.24.0" 223 | checksum: 10c0/b3445860ae749fc664682b291f092285e949114e8336784ae29f88eb4c176279b01cc6740005a017a0389ae4b4e928d5bbbc01de7da7e400c972e3d6f792063a 224 | languageName: node 225 | linkType: hard 226 | 227 | "@babel/highlight@npm:^7.24.2": 228 | version: 7.24.2 229 | resolution: "@babel/highlight@npm:7.24.2" 230 | dependencies: 231 | "@babel/helper-validator-identifier": "npm:^7.22.20" 232 | chalk: "npm:^2.4.2" 233 | js-tokens: "npm:^4.0.0" 234 | picocolors: "npm:^1.0.0" 235 | checksum: 10c0/98ce00321daedeed33a4ed9362dc089a70375ff1b3b91228b9f05e6591d387a81a8cba68886e207861b8871efa0bc997ceabdd9c90f6cce3ee1b2f7f941b42db 236 | languageName: node 237 | linkType: hard 238 | 239 | "@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1": 240 | version: 7.24.1 241 | resolution: "@babel/parser@npm:7.24.1" 242 | bin: 243 | parser: ./bin/babel-parser.js 244 | checksum: 10c0/d2a8b99aa5f33182b69d5569367403a40e7c027ae3b03a1f81fd8ac9b06ceb85b31f6ee4267fb90726dc2ac99909c6bdaa9cf16c379efab73d8dfe85cee32c50 245 | languageName: node 246 | linkType: hard 247 | 248 | "@babel/plugin-transform-react-jsx-self@npm:^7.23.3": 249 | version: 7.24.1 250 | resolution: "@babel/plugin-transform-react-jsx-self@npm:7.24.1" 251 | dependencies: 252 | "@babel/helper-plugin-utils": "npm:^7.24.0" 253 | peerDependencies: 254 | "@babel/core": ^7.0.0-0 255 | checksum: 10c0/ea362ff94b535c753f560eb1f5e063dc72bbbca17ed58837a949a7b289d5eacc7b0a28296d1932c94429b168d6040cdee5484a59b9e3c021f169e0ee137e6a27 256 | languageName: node 257 | linkType: hard 258 | 259 | "@babel/plugin-transform-react-jsx-source@npm:^7.23.3": 260 | version: 7.24.1 261 | resolution: "@babel/plugin-transform-react-jsx-source@npm:7.24.1" 262 | dependencies: 263 | "@babel/helper-plugin-utils": "npm:^7.24.0" 264 | peerDependencies: 265 | "@babel/core": ^7.0.0-0 266 | checksum: 10c0/ea8e3263c0dc51fbc97c156cc647150a757cc56de10781287353d0ce9b2dcd6b6d93d573c0142d7daf5d6fb554c74fa1971ae60764924ea711161d8458739b63 267 | languageName: node 268 | linkType: hard 269 | 270 | "@babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0": 271 | version: 7.24.0 272 | resolution: "@babel/template@npm:7.24.0" 273 | dependencies: 274 | "@babel/code-frame": "npm:^7.23.5" 275 | "@babel/parser": "npm:^7.24.0" 276 | "@babel/types": "npm:^7.24.0" 277 | checksum: 10c0/9d3dd8d22fe1c36bc3bdef6118af1f4b030aaf6d7d2619f5da203efa818a2185d717523486c111de8d99a8649ddf4bbf6b2a7a64962d8411cf6a8fa89f010e54 278 | languageName: node 279 | linkType: hard 280 | 281 | "@babel/traverse@npm:^7.24.1": 282 | version: 7.24.1 283 | resolution: "@babel/traverse@npm:7.24.1" 284 | dependencies: 285 | "@babel/code-frame": "npm:^7.24.1" 286 | "@babel/generator": "npm:^7.24.1" 287 | "@babel/helper-environment-visitor": "npm:^7.22.20" 288 | "@babel/helper-function-name": "npm:^7.23.0" 289 | "@babel/helper-hoist-variables": "npm:^7.22.5" 290 | "@babel/helper-split-export-declaration": "npm:^7.22.6" 291 | "@babel/parser": "npm:^7.24.1" 292 | "@babel/types": "npm:^7.24.0" 293 | debug: "npm:^4.3.1" 294 | globals: "npm:^11.1.0" 295 | checksum: 10c0/c087b918f6823776537ba246136c70e7ce0719fc05361ebcbfd16f4e6f2f6f1f8f4f9167f1d9b675f27d12074839605189cc9d689de20b89a85e7c140f23daab 296 | languageName: node 297 | linkType: hard 298 | 299 | "@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.0, @babel/types@npm:^7.8.3": 300 | version: 7.24.0 301 | resolution: "@babel/types@npm:7.24.0" 302 | dependencies: 303 | "@babel/helper-string-parser": "npm:^7.23.4" 304 | "@babel/helper-validator-identifier": "npm:^7.22.20" 305 | to-fast-properties: "npm:^2.0.0" 306 | checksum: 10c0/777a0bb5dbe038ca4c905fdafb1cdb6bdd10fe9d63ce13eca0bd91909363cbad554a53dc1f902004b78c1dcbc742056f877f2c99eeedff647333b1fadf51235d 307 | languageName: node 308 | linkType: hard 309 | 310 | "@esbuild/aix-ppc64@npm:0.20.2": 311 | version: 0.20.2 312 | resolution: "@esbuild/aix-ppc64@npm:0.20.2" 313 | conditions: os=aix & cpu=ppc64 314 | languageName: node 315 | linkType: hard 316 | 317 | "@esbuild/android-arm64@npm:0.20.2": 318 | version: 0.20.2 319 | resolution: "@esbuild/android-arm64@npm:0.20.2" 320 | conditions: os=android & cpu=arm64 321 | languageName: node 322 | linkType: hard 323 | 324 | "@esbuild/android-arm@npm:0.20.2": 325 | version: 0.20.2 326 | resolution: "@esbuild/android-arm@npm:0.20.2" 327 | conditions: os=android & cpu=arm 328 | languageName: node 329 | linkType: hard 330 | 331 | "@esbuild/android-x64@npm:0.20.2": 332 | version: 0.20.2 333 | resolution: "@esbuild/android-x64@npm:0.20.2" 334 | conditions: os=android & cpu=x64 335 | languageName: node 336 | linkType: hard 337 | 338 | "@esbuild/darwin-arm64@npm:0.20.2": 339 | version: 0.20.2 340 | resolution: "@esbuild/darwin-arm64@npm:0.20.2" 341 | conditions: os=darwin & cpu=arm64 342 | languageName: node 343 | linkType: hard 344 | 345 | "@esbuild/darwin-x64@npm:0.20.2": 346 | version: 0.20.2 347 | resolution: "@esbuild/darwin-x64@npm:0.20.2" 348 | conditions: os=darwin & cpu=x64 349 | languageName: node 350 | linkType: hard 351 | 352 | "@esbuild/freebsd-arm64@npm:0.20.2": 353 | version: 0.20.2 354 | resolution: "@esbuild/freebsd-arm64@npm:0.20.2" 355 | conditions: os=freebsd & cpu=arm64 356 | languageName: node 357 | linkType: hard 358 | 359 | "@esbuild/freebsd-x64@npm:0.20.2": 360 | version: 0.20.2 361 | resolution: "@esbuild/freebsd-x64@npm:0.20.2" 362 | conditions: os=freebsd & cpu=x64 363 | languageName: node 364 | linkType: hard 365 | 366 | "@esbuild/linux-arm64@npm:0.20.2": 367 | version: 0.20.2 368 | resolution: "@esbuild/linux-arm64@npm:0.20.2" 369 | conditions: os=linux & cpu=arm64 370 | languageName: node 371 | linkType: hard 372 | 373 | "@esbuild/linux-arm@npm:0.20.2": 374 | version: 0.20.2 375 | resolution: "@esbuild/linux-arm@npm:0.20.2" 376 | conditions: os=linux & cpu=arm 377 | languageName: node 378 | linkType: hard 379 | 380 | "@esbuild/linux-ia32@npm:0.20.2": 381 | version: 0.20.2 382 | resolution: "@esbuild/linux-ia32@npm:0.20.2" 383 | conditions: os=linux & cpu=ia32 384 | languageName: node 385 | linkType: hard 386 | 387 | "@esbuild/linux-loong64@npm:0.20.2": 388 | version: 0.20.2 389 | resolution: "@esbuild/linux-loong64@npm:0.20.2" 390 | conditions: os=linux & cpu=loong64 391 | languageName: node 392 | linkType: hard 393 | 394 | "@esbuild/linux-mips64el@npm:0.20.2": 395 | version: 0.20.2 396 | resolution: "@esbuild/linux-mips64el@npm:0.20.2" 397 | conditions: os=linux & cpu=mips64el 398 | languageName: node 399 | linkType: hard 400 | 401 | "@esbuild/linux-ppc64@npm:0.20.2": 402 | version: 0.20.2 403 | resolution: "@esbuild/linux-ppc64@npm:0.20.2" 404 | conditions: os=linux & cpu=ppc64 405 | languageName: node 406 | linkType: hard 407 | 408 | "@esbuild/linux-riscv64@npm:0.20.2": 409 | version: 0.20.2 410 | resolution: "@esbuild/linux-riscv64@npm:0.20.2" 411 | conditions: os=linux & cpu=riscv64 412 | languageName: node 413 | linkType: hard 414 | 415 | "@esbuild/linux-s390x@npm:0.20.2": 416 | version: 0.20.2 417 | resolution: "@esbuild/linux-s390x@npm:0.20.2" 418 | conditions: os=linux & cpu=s390x 419 | languageName: node 420 | linkType: hard 421 | 422 | "@esbuild/linux-x64@npm:0.20.2": 423 | version: 0.20.2 424 | resolution: "@esbuild/linux-x64@npm:0.20.2" 425 | conditions: os=linux & cpu=x64 426 | languageName: node 427 | linkType: hard 428 | 429 | "@esbuild/netbsd-x64@npm:0.20.2": 430 | version: 0.20.2 431 | resolution: "@esbuild/netbsd-x64@npm:0.20.2" 432 | conditions: os=netbsd & cpu=x64 433 | languageName: node 434 | linkType: hard 435 | 436 | "@esbuild/openbsd-x64@npm:0.20.2": 437 | version: 0.20.2 438 | resolution: "@esbuild/openbsd-x64@npm:0.20.2" 439 | conditions: os=openbsd & cpu=x64 440 | languageName: node 441 | linkType: hard 442 | 443 | "@esbuild/sunos-x64@npm:0.20.2": 444 | version: 0.20.2 445 | resolution: "@esbuild/sunos-x64@npm:0.20.2" 446 | conditions: os=sunos & cpu=x64 447 | languageName: node 448 | linkType: hard 449 | 450 | "@esbuild/win32-arm64@npm:0.20.2": 451 | version: 0.20.2 452 | resolution: "@esbuild/win32-arm64@npm:0.20.2" 453 | conditions: os=win32 & cpu=arm64 454 | languageName: node 455 | linkType: hard 456 | 457 | "@esbuild/win32-ia32@npm:0.20.2": 458 | version: 0.20.2 459 | resolution: "@esbuild/win32-ia32@npm:0.20.2" 460 | conditions: os=win32 & cpu=ia32 461 | languageName: node 462 | linkType: hard 463 | 464 | "@esbuild/win32-x64@npm:0.20.2": 465 | version: 0.20.2 466 | resolution: "@esbuild/win32-x64@npm:0.20.2" 467 | conditions: os=win32 & cpu=x64 468 | languageName: node 469 | linkType: hard 470 | 471 | "@graphql-typed-document-node/core@npm:^3.1.1": 472 | version: 3.2.0 473 | resolution: "@graphql-typed-document-node/core@npm:3.2.0" 474 | peerDependencies: 475 | graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 476 | checksum: 10c0/94e9d75c1f178bbae8d874f5a9361708a3350c8def7eaeb6920f2c820e82403b7d4f55b3735856d68e145e86c85cbfe2adc444fdc25519cd51f108697e99346c 477 | languageName: node 478 | linkType: hard 479 | 480 | "@isaacs/cliui@npm:^8.0.2": 481 | version: 8.0.2 482 | resolution: "@isaacs/cliui@npm:8.0.2" 483 | dependencies: 484 | string-width: "npm:^5.1.2" 485 | string-width-cjs: "npm:string-width@^4.2.0" 486 | strip-ansi: "npm:^7.0.1" 487 | strip-ansi-cjs: "npm:strip-ansi@^6.0.1" 488 | wrap-ansi: "npm:^8.1.0" 489 | wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" 490 | checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e 491 | languageName: node 492 | linkType: hard 493 | 494 | "@jridgewell/gen-mapping@npm:^0.3.5": 495 | version: 0.3.5 496 | resolution: "@jridgewell/gen-mapping@npm:0.3.5" 497 | dependencies: 498 | "@jridgewell/set-array": "npm:^1.2.1" 499 | "@jridgewell/sourcemap-codec": "npm:^1.4.10" 500 | "@jridgewell/trace-mapping": "npm:^0.3.24" 501 | checksum: 10c0/1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb 502 | languageName: node 503 | linkType: hard 504 | 505 | "@jridgewell/resolve-uri@npm:^3.1.0": 506 | version: 3.1.2 507 | resolution: "@jridgewell/resolve-uri@npm:3.1.2" 508 | checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e 509 | languageName: node 510 | linkType: hard 511 | 512 | "@jridgewell/set-array@npm:^1.2.1": 513 | version: 1.2.1 514 | resolution: "@jridgewell/set-array@npm:1.2.1" 515 | checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4 516 | languageName: node 517 | linkType: hard 518 | 519 | "@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": 520 | version: 1.4.15 521 | resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" 522 | checksum: 10c0/0c6b5ae663087558039052a626d2d7ed5208da36cfd707dcc5cea4a07cfc918248403dcb5989a8f7afaf245ce0573b7cc6fd94c4a30453bd10e44d9363940ba5 523 | languageName: node 524 | linkType: hard 525 | 526 | "@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": 527 | version: 0.3.25 528 | resolution: "@jridgewell/trace-mapping@npm:0.3.25" 529 | dependencies: 530 | "@jridgewell/resolve-uri": "npm:^3.1.0" 531 | "@jridgewell/sourcemap-codec": "npm:^1.4.14" 532 | checksum: 10c0/3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4 533 | languageName: node 534 | linkType: hard 535 | 536 | "@npmcli/agent@npm:^2.0.0": 537 | version: 2.2.1 538 | resolution: "@npmcli/agent@npm:2.2.1" 539 | dependencies: 540 | agent-base: "npm:^7.1.0" 541 | http-proxy-agent: "npm:^7.0.0" 542 | https-proxy-agent: "npm:^7.0.1" 543 | lru-cache: "npm:^10.0.1" 544 | socks-proxy-agent: "npm:^8.0.1" 545 | checksum: 10c0/38ee5cbe8f3cde13be916e717bfc54fd1a7605c07af056369ff894e244c221e0b56b08ca5213457477f9bc15bca9e729d51a4788829b5c3cf296b3c996147f76 546 | languageName: node 547 | linkType: hard 548 | 549 | "@npmcli/fs@npm:^3.1.0": 550 | version: 3.1.0 551 | resolution: "@npmcli/fs@npm:3.1.0" 552 | dependencies: 553 | semver: "npm:^7.3.5" 554 | checksum: 10c0/162b4a0b8705cd6f5c2470b851d1dc6cd228c86d2170e1769d738c1fbb69a87160901411c3c035331e9e99db72f1f1099a8b734bf1637cc32b9a5be1660e4e1e 555 | languageName: node 556 | linkType: hard 557 | 558 | "@pkgjs/parseargs@npm:^0.11.0": 559 | version: 0.11.0 560 | resolution: "@pkgjs/parseargs@npm:0.11.0" 561 | checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd 562 | languageName: node 563 | linkType: hard 564 | 565 | "@rollup/rollup-android-arm-eabi@npm:4.13.0": 566 | version: 4.13.0 567 | resolution: "@rollup/rollup-android-arm-eabi@npm:4.13.0" 568 | conditions: os=android & cpu=arm 569 | languageName: node 570 | linkType: hard 571 | 572 | "@rollup/rollup-android-arm64@npm:4.13.0": 573 | version: 4.13.0 574 | resolution: "@rollup/rollup-android-arm64@npm:4.13.0" 575 | conditions: os=android & cpu=arm64 576 | languageName: node 577 | linkType: hard 578 | 579 | "@rollup/rollup-darwin-arm64@npm:4.13.0": 580 | version: 4.13.0 581 | resolution: "@rollup/rollup-darwin-arm64@npm:4.13.0" 582 | conditions: os=darwin & cpu=arm64 583 | languageName: node 584 | linkType: hard 585 | 586 | "@rollup/rollup-darwin-x64@npm:4.13.0": 587 | version: 4.13.0 588 | resolution: "@rollup/rollup-darwin-x64@npm:4.13.0" 589 | conditions: os=darwin & cpu=x64 590 | languageName: node 591 | linkType: hard 592 | 593 | "@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0": 594 | version: 4.13.0 595 | resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0" 596 | conditions: os=linux & cpu=arm 597 | languageName: node 598 | linkType: hard 599 | 600 | "@rollup/rollup-linux-arm64-gnu@npm:4.13.0": 601 | version: 4.13.0 602 | resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.13.0" 603 | conditions: os=linux & cpu=arm64 & libc=glibc 604 | languageName: node 605 | linkType: hard 606 | 607 | "@rollup/rollup-linux-arm64-musl@npm:4.13.0": 608 | version: 4.13.0 609 | resolution: "@rollup/rollup-linux-arm64-musl@npm:4.13.0" 610 | conditions: os=linux & cpu=arm64 & libc=musl 611 | languageName: node 612 | linkType: hard 613 | 614 | "@rollup/rollup-linux-riscv64-gnu@npm:4.13.0": 615 | version: 4.13.0 616 | resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.13.0" 617 | conditions: os=linux & cpu=riscv64 & libc=glibc 618 | languageName: node 619 | linkType: hard 620 | 621 | "@rollup/rollup-linux-x64-gnu@npm:4.13.0": 622 | version: 4.13.0 623 | resolution: "@rollup/rollup-linux-x64-gnu@npm:4.13.0" 624 | conditions: os=linux & cpu=x64 & libc=glibc 625 | languageName: node 626 | linkType: hard 627 | 628 | "@rollup/rollup-linux-x64-musl@npm:4.13.0": 629 | version: 4.13.0 630 | resolution: "@rollup/rollup-linux-x64-musl@npm:4.13.0" 631 | conditions: os=linux & cpu=x64 & libc=musl 632 | languageName: node 633 | linkType: hard 634 | 635 | "@rollup/rollup-win32-arm64-msvc@npm:4.13.0": 636 | version: 4.13.0 637 | resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.13.0" 638 | conditions: os=win32 & cpu=arm64 639 | languageName: node 640 | linkType: hard 641 | 642 | "@rollup/rollup-win32-ia32-msvc@npm:4.13.0": 643 | version: 4.13.0 644 | resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.13.0" 645 | conditions: os=win32 & cpu=ia32 646 | languageName: node 647 | linkType: hard 648 | 649 | "@rollup/rollup-win32-x64-msvc@npm:4.13.0": 650 | version: 4.13.0 651 | resolution: "@rollup/rollup-win32-x64-msvc@npm:4.13.0" 652 | conditions: os=win32 & cpu=x64 653 | languageName: node 654 | linkType: hard 655 | 656 | "@types/babel__core@npm:^7.20.5": 657 | version: 7.20.5 658 | resolution: "@types/babel__core@npm:7.20.5" 659 | dependencies: 660 | "@babel/parser": "npm:^7.20.7" 661 | "@babel/types": "npm:^7.20.7" 662 | "@types/babel__generator": "npm:*" 663 | "@types/babel__template": "npm:*" 664 | "@types/babel__traverse": "npm:*" 665 | checksum: 10c0/bdee3bb69951e833a4b811b8ee9356b69a61ed5b7a23e1a081ec9249769117fa83aaaf023bb06562a038eb5845155ff663e2d5c75dd95c1d5ccc91db012868ff 666 | languageName: node 667 | linkType: hard 668 | 669 | "@types/babel__generator@npm:*": 670 | version: 7.6.8 671 | resolution: "@types/babel__generator@npm:7.6.8" 672 | dependencies: 673 | "@babel/types": "npm:^7.0.0" 674 | checksum: 10c0/f0ba105e7d2296bf367d6e055bb22996886c114261e2cb70bf9359556d0076c7a57239d019dee42bb063f565bade5ccb46009bce2044b2952d964bf9a454d6d2 675 | languageName: node 676 | linkType: hard 677 | 678 | "@types/babel__template@npm:*": 679 | version: 7.4.4 680 | resolution: "@types/babel__template@npm:7.4.4" 681 | dependencies: 682 | "@babel/parser": "npm:^7.1.0" 683 | "@babel/types": "npm:^7.0.0" 684 | checksum: 10c0/cc84f6c6ab1eab1427e90dd2b76ccee65ce940b778a9a67be2c8c39e1994e6f5bbc8efa309f6cea8dc6754994524cd4d2896558df76d92e7a1f46ecffee7112b 685 | languageName: node 686 | linkType: hard 687 | 688 | "@types/babel__traverse@npm:*": 689 | version: 7.20.5 690 | resolution: "@types/babel__traverse@npm:7.20.5" 691 | dependencies: 692 | "@babel/types": "npm:^7.20.7" 693 | checksum: 10c0/033abcb2f4c084ad33e30c3efaad82161240f351e3c71b6154ed289946b33b363696c0fbd42502b68e4582a87413c418321f40eb1ea863e34fe525641345e05b 694 | languageName: node 695 | linkType: hard 696 | 697 | "@types/estree@npm:1.0.5": 698 | version: 1.0.5 699 | resolution: "@types/estree@npm:1.0.5" 700 | checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d 701 | languageName: node 702 | linkType: hard 703 | 704 | "@types/prop-types@npm:*": 705 | version: 15.7.12 706 | resolution: "@types/prop-types@npm:15.7.12" 707 | checksum: 10c0/1babcc7db6a1177779f8fde0ccc78d64d459906e6ef69a4ed4dd6339c920c2e05b074ee5a92120fe4e9d9f1a01c952f843ebd550bee2332fc2ef81d1706878f8 708 | languageName: node 709 | linkType: hard 710 | 711 | "@types/react-dom@npm:^18.2.22": 712 | version: 18.2.22 713 | resolution: "@types/react-dom@npm:18.2.22" 714 | dependencies: 715 | "@types/react": "npm:*" 716 | checksum: 10c0/cd85b5f402126e44b8c7b573e74737389816abcc931b2b14d8f946ba81cce8637ea490419488fcae842efb1e2f69853bc30522e43fd8359e1007d4d14b8d8146 717 | languageName: node 718 | linkType: hard 719 | 720 | "@types/react@npm:*, @types/react@npm:^18.2.71": 721 | version: 18.2.71 722 | resolution: "@types/react@npm:18.2.71" 723 | dependencies: 724 | "@types/prop-types": "npm:*" 725 | "@types/scheduler": "npm:*" 726 | csstype: "npm:^3.0.2" 727 | checksum: 10c0/0b2fc05a33aa83f09880c1172f6112450fa507ea56a168521172161e057277a8a474ff2fae02fa4910ce74853d7b5cff560586f912a0c9d8102cfd316bdb1b19 728 | languageName: node 729 | linkType: hard 730 | 731 | "@types/scheduler@npm:*": 732 | version: 0.23.0 733 | resolution: "@types/scheduler@npm:0.23.0" 734 | checksum: 10c0/5cf7f2ba3732b74877559eb20b19f95fcd0a20c17dcb20e75a7ca7c7369cd455aeb2d406b3ff5a38168a9750da3bad78dd20d96d11118468b78f4959b8e56090 735 | languageName: node 736 | linkType: hard 737 | 738 | "@vitejs/plugin-react@npm:^4.2.1": 739 | version: 4.2.1 740 | resolution: "@vitejs/plugin-react@npm:4.2.1" 741 | dependencies: 742 | "@babel/core": "npm:^7.23.5" 743 | "@babel/plugin-transform-react-jsx-self": "npm:^7.23.3" 744 | "@babel/plugin-transform-react-jsx-source": "npm:^7.23.3" 745 | "@types/babel__core": "npm:^7.20.5" 746 | react-refresh: "npm:^0.14.0" 747 | peerDependencies: 748 | vite: ^4.2.0 || ^5.0.0 749 | checksum: 10c0/de1eec44d703f32e5b58e776328ca20793657fe991835d15b290230b19a2a08be5d31501d424279ae13ecfed28044c117b69d746891c8d9b92c69e8a8907e989 750 | languageName: node 751 | linkType: hard 752 | 753 | "@wry/caches@npm:^1.0.0": 754 | version: 1.0.1 755 | resolution: "@wry/caches@npm:1.0.1" 756 | dependencies: 757 | tslib: "npm:^2.3.0" 758 | checksum: 10c0/a7bca3377f1131d3f1080f2e39d0692c9d1ca86bfd55734786f167f46aad28a4c8e772107324e8319843fb8068fdf98abcdea376d8a589316b1f0cdadf81f8b1 759 | languageName: node 760 | linkType: hard 761 | 762 | "@wry/context@npm:^0.7.0": 763 | version: 0.7.4 764 | resolution: "@wry/context@npm:0.7.4" 765 | dependencies: 766 | tslib: "npm:^2.3.0" 767 | checksum: 10c0/6cc8249b8ba195cda7643bffb30969e33d54a99f118a29dd12f1c34064ee0adf04253cfa0ba5b9893afde0a9588745828962877b9585106f7488e8299757638b 768 | languageName: node 769 | linkType: hard 770 | 771 | "@wry/equality@npm:^0.5.6": 772 | version: 0.5.7 773 | resolution: "@wry/equality@npm:0.5.7" 774 | dependencies: 775 | tslib: "npm:^2.3.0" 776 | checksum: 10c0/8503ff6d4eb80f303d1387e71e51da59ccfc2160fa6d464618be80946fe43a654ea73f0c5b90d659fc4dfc3e38cbbdd6650d595fe5865be476636e444470853e 777 | languageName: node 778 | linkType: hard 779 | 780 | "@wry/trie@npm:^0.4.3": 781 | version: 0.4.3 782 | resolution: "@wry/trie@npm:0.4.3" 783 | dependencies: 784 | tslib: "npm:^2.3.0" 785 | checksum: 10c0/1a14edba595b1967d0cf38208c2660b2952a8e8a649bb669b67907df48f602c7f2acbe16c1e1b115afa7d7effb9f1a4dbde38eef16ee92e7521a511262a53281 786 | languageName: node 787 | linkType: hard 788 | 789 | "@wry/trie@npm:^0.5.0": 790 | version: 0.5.0 791 | resolution: "@wry/trie@npm:0.5.0" 792 | dependencies: 793 | tslib: "npm:^2.3.0" 794 | checksum: 10c0/8c8cfcac96ba4bc69dabf02740e19e613f501b398e80bacc32cd95e87228f75ecb41cd1a76a65abae9756c0f61ab3536e0da52de28857456f9381ffdf5995d3e 795 | languageName: node 796 | linkType: hard 797 | 798 | "abbrev@npm:^2.0.0": 799 | version: 2.0.0 800 | resolution: "abbrev@npm:2.0.0" 801 | checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 802 | languageName: node 803 | linkType: hard 804 | 805 | "agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": 806 | version: 7.1.0 807 | resolution: "agent-base@npm:7.1.0" 808 | dependencies: 809 | debug: "npm:^4.3.4" 810 | checksum: 10c0/fc974ab57ffdd8421a2bc339644d312a9cca320c20c3393c9d8b1fd91731b9bbabdb985df5fc860f5b79d81c3e350daa3fcb31c5c07c0bb385aafc817df004ce 811 | languageName: node 812 | linkType: hard 813 | 814 | "aggregate-error@npm:^3.0.0": 815 | version: 3.1.0 816 | resolution: "aggregate-error@npm:3.1.0" 817 | dependencies: 818 | clean-stack: "npm:^2.0.0" 819 | indent-string: "npm:^4.0.0" 820 | checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 821 | languageName: node 822 | linkType: hard 823 | 824 | "ansi-regex@npm:^5.0.1": 825 | version: 5.0.1 826 | resolution: "ansi-regex@npm:5.0.1" 827 | checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 828 | languageName: node 829 | linkType: hard 830 | 831 | "ansi-regex@npm:^6.0.1": 832 | version: 6.0.1 833 | resolution: "ansi-regex@npm:6.0.1" 834 | checksum: 10c0/cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08 835 | languageName: node 836 | linkType: hard 837 | 838 | "ansi-styles@npm:^3.2.1": 839 | version: 3.2.1 840 | resolution: "ansi-styles@npm:3.2.1" 841 | dependencies: 842 | color-convert: "npm:^1.9.0" 843 | checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b 844 | languageName: node 845 | linkType: hard 846 | 847 | "ansi-styles@npm:^4.0.0": 848 | version: 4.3.0 849 | resolution: "ansi-styles@npm:4.3.0" 850 | dependencies: 851 | color-convert: "npm:^2.0.1" 852 | checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 853 | languageName: node 854 | linkType: hard 855 | 856 | "ansi-styles@npm:^6.1.0": 857 | version: 6.2.1 858 | resolution: "ansi-styles@npm:6.2.1" 859 | checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c 860 | languageName: node 861 | linkType: hard 862 | 863 | "apollo3-cache-persist@portal:../..::locator=basic-apollo-app%40workspace%3A.": 864 | version: 0.0.0-use.local 865 | resolution: "apollo3-cache-persist@portal:../..::locator=basic-apollo-app%40workspace%3A." 866 | peerDependencies: 867 | "@apollo/client": ^3.7.17 868 | languageName: node 869 | linkType: soft 870 | 871 | "balanced-match@npm:^1.0.0": 872 | version: 1.0.2 873 | resolution: "balanced-match@npm:1.0.2" 874 | checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee 875 | languageName: node 876 | linkType: hard 877 | 878 | "basic-apollo-app@workspace:.": 879 | version: 0.0.0-use.local 880 | resolution: "basic-apollo-app@workspace:." 881 | dependencies: 882 | "@apollo/client": "npm:^3.9.9" 883 | "@types/react": "npm:^18.2.71" 884 | "@types/react-dom": "npm:^18.2.22" 885 | "@vitejs/plugin-react": "npm:^4.2.1" 886 | apollo3-cache-persist: "file:../../lib" 887 | graphql: "npm:^16.8.1" 888 | react: "npm:^18.2.0" 889 | react-dom: "npm:^18.2.0" 890 | typescript: "npm:^5.4.3" 891 | vite: "npm:^5.2.6" 892 | languageName: unknown 893 | linkType: soft 894 | 895 | "brace-expansion@npm:^2.0.1": 896 | version: 2.0.1 897 | resolution: "brace-expansion@npm:2.0.1" 898 | dependencies: 899 | balanced-match: "npm:^1.0.0" 900 | checksum: 10c0/b358f2fe060e2d7a87aa015979ecea07f3c37d4018f8d6deb5bd4c229ad3a0384fe6029bb76cd8be63c81e516ee52d1a0673edbe2023d53a5191732ae3c3e49f 901 | languageName: node 902 | linkType: hard 903 | 904 | "browserslist@npm:^4.22.2": 905 | version: 4.23.0 906 | resolution: "browserslist@npm:4.23.0" 907 | dependencies: 908 | caniuse-lite: "npm:^1.0.30001587" 909 | electron-to-chromium: "npm:^1.4.668" 910 | node-releases: "npm:^2.0.14" 911 | update-browserslist-db: "npm:^1.0.13" 912 | bin: 913 | browserslist: cli.js 914 | checksum: 10c0/8e9cc154529062128d02a7af4d8adeead83ca1df8cd9ee65a88e2161039f3d68a4d40fea7353cab6bae4c16182dec2fdd9a1cf7dc2a2935498cee1af0e998943 915 | languageName: node 916 | linkType: hard 917 | 918 | "cacache@npm:^18.0.0": 919 | version: 18.0.2 920 | resolution: "cacache@npm:18.0.2" 921 | dependencies: 922 | "@npmcli/fs": "npm:^3.1.0" 923 | fs-minipass: "npm:^3.0.0" 924 | glob: "npm:^10.2.2" 925 | lru-cache: "npm:^10.0.1" 926 | minipass: "npm:^7.0.3" 927 | minipass-collect: "npm:^2.0.1" 928 | minipass-flush: "npm:^1.0.5" 929 | minipass-pipeline: "npm:^1.2.4" 930 | p-map: "npm:^4.0.0" 931 | ssri: "npm:^10.0.0" 932 | tar: "npm:^6.1.11" 933 | unique-filename: "npm:^3.0.0" 934 | checksum: 10c0/7992665305cc251a984f4fdbab1449d50e88c635bc43bf2785530c61d239c61b349e5734461baa461caaee65f040ab14e2d58e694f479c0810cffd181ba5eabc 935 | languageName: node 936 | linkType: hard 937 | 938 | "caniuse-lite@npm:^1.0.30001587": 939 | version: 1.0.30001600 940 | resolution: "caniuse-lite@npm:1.0.30001600" 941 | checksum: 10c0/b4f764db5d4f8cb3eb2827a170a20e6b2f4b8c3d80169efcf56bf3d6b8b3e6dd1c740141f0d0b10b2233f49ee8b496e2d1e044a36c54750a106bad2f6477f2db 942 | languageName: node 943 | linkType: hard 944 | 945 | "chalk@npm:^2.4.2": 946 | version: 2.4.2 947 | resolution: "chalk@npm:2.4.2" 948 | dependencies: 949 | ansi-styles: "npm:^3.2.1" 950 | escape-string-regexp: "npm:^1.0.5" 951 | supports-color: "npm:^5.3.0" 952 | checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 953 | languageName: node 954 | linkType: hard 955 | 956 | "chownr@npm:^2.0.0": 957 | version: 2.0.0 958 | resolution: "chownr@npm:2.0.0" 959 | checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 960 | languageName: node 961 | linkType: hard 962 | 963 | "clean-stack@npm:^2.0.0": 964 | version: 2.2.0 965 | resolution: "clean-stack@npm:2.2.0" 966 | checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 967 | languageName: node 968 | linkType: hard 969 | 970 | "color-convert@npm:^1.9.0": 971 | version: 1.9.3 972 | resolution: "color-convert@npm:1.9.3" 973 | dependencies: 974 | color-name: "npm:1.1.3" 975 | checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c 976 | languageName: node 977 | linkType: hard 978 | 979 | "color-convert@npm:^2.0.1": 980 | version: 2.0.1 981 | resolution: "color-convert@npm:2.0.1" 982 | dependencies: 983 | color-name: "npm:~1.1.4" 984 | checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 985 | languageName: node 986 | linkType: hard 987 | 988 | "color-name@npm:1.1.3": 989 | version: 1.1.3 990 | resolution: "color-name@npm:1.1.3" 991 | checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 992 | languageName: node 993 | linkType: hard 994 | 995 | "color-name@npm:~1.1.4": 996 | version: 1.1.4 997 | resolution: "color-name@npm:1.1.4" 998 | checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 999 | languageName: node 1000 | linkType: hard 1001 | 1002 | "convert-source-map@npm:^2.0.0": 1003 | version: 2.0.0 1004 | resolution: "convert-source-map@npm:2.0.0" 1005 | checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b 1006 | languageName: node 1007 | linkType: hard 1008 | 1009 | "cross-spawn@npm:^7.0.0": 1010 | version: 7.0.3 1011 | resolution: "cross-spawn@npm:7.0.3" 1012 | dependencies: 1013 | path-key: "npm:^3.1.0" 1014 | shebang-command: "npm:^2.0.0" 1015 | which: "npm:^2.0.1" 1016 | checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750 1017 | languageName: node 1018 | linkType: hard 1019 | 1020 | "csstype@npm:^3.0.2": 1021 | version: 3.1.3 1022 | resolution: "csstype@npm:3.1.3" 1023 | checksum: 10c0/80c089d6f7e0c5b2bd83cf0539ab41474198579584fa10d86d0cafe0642202343cbc119e076a0b1aece191989477081415d66c9fefbf3c957fc2fc4b7009f248 1024 | languageName: node 1025 | linkType: hard 1026 | 1027 | "debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.4": 1028 | version: 4.3.4 1029 | resolution: "debug@npm:4.3.4" 1030 | dependencies: 1031 | ms: "npm:2.1.2" 1032 | peerDependenciesMeta: 1033 | supports-color: 1034 | optional: true 1035 | checksum: 10c0/cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736 1036 | languageName: node 1037 | linkType: hard 1038 | 1039 | "eastasianwidth@npm:^0.2.0": 1040 | version: 0.2.0 1041 | resolution: "eastasianwidth@npm:0.2.0" 1042 | checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 1043 | languageName: node 1044 | linkType: hard 1045 | 1046 | "electron-to-chromium@npm:^1.4.668": 1047 | version: 1.4.717 1048 | resolution: "electron-to-chromium@npm:1.4.717" 1049 | checksum: 10c0/1de0a9f078211471442010d574634d147491c06f415cc3c178dd378004c4ee5e743cda288973ac01f5204abc6b5bc7bec1d770807b60eb012b49aae4c9570985 1050 | languageName: node 1051 | linkType: hard 1052 | 1053 | "emoji-regex@npm:^8.0.0": 1054 | version: 8.0.0 1055 | resolution: "emoji-regex@npm:8.0.0" 1056 | checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 1057 | languageName: node 1058 | linkType: hard 1059 | 1060 | "emoji-regex@npm:^9.2.2": 1061 | version: 9.2.2 1062 | resolution: "emoji-regex@npm:9.2.2" 1063 | checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 1064 | languageName: node 1065 | linkType: hard 1066 | 1067 | "encoding@npm:^0.1.13": 1068 | version: 0.1.13 1069 | resolution: "encoding@npm:0.1.13" 1070 | dependencies: 1071 | iconv-lite: "npm:^0.6.2" 1072 | checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 1073 | languageName: node 1074 | linkType: hard 1075 | 1076 | "env-paths@npm:^2.2.0": 1077 | version: 2.2.1 1078 | resolution: "env-paths@npm:2.2.1" 1079 | checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 1080 | languageName: node 1081 | linkType: hard 1082 | 1083 | "err-code@npm:^2.0.2": 1084 | version: 2.0.3 1085 | resolution: "err-code@npm:2.0.3" 1086 | checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 1087 | languageName: node 1088 | linkType: hard 1089 | 1090 | "esbuild@npm:^0.20.1": 1091 | version: 0.20.2 1092 | resolution: "esbuild@npm:0.20.2" 1093 | dependencies: 1094 | "@esbuild/aix-ppc64": "npm:0.20.2" 1095 | "@esbuild/android-arm": "npm:0.20.2" 1096 | "@esbuild/android-arm64": "npm:0.20.2" 1097 | "@esbuild/android-x64": "npm:0.20.2" 1098 | "@esbuild/darwin-arm64": "npm:0.20.2" 1099 | "@esbuild/darwin-x64": "npm:0.20.2" 1100 | "@esbuild/freebsd-arm64": "npm:0.20.2" 1101 | "@esbuild/freebsd-x64": "npm:0.20.2" 1102 | "@esbuild/linux-arm": "npm:0.20.2" 1103 | "@esbuild/linux-arm64": "npm:0.20.2" 1104 | "@esbuild/linux-ia32": "npm:0.20.2" 1105 | "@esbuild/linux-loong64": "npm:0.20.2" 1106 | "@esbuild/linux-mips64el": "npm:0.20.2" 1107 | "@esbuild/linux-ppc64": "npm:0.20.2" 1108 | "@esbuild/linux-riscv64": "npm:0.20.2" 1109 | "@esbuild/linux-s390x": "npm:0.20.2" 1110 | "@esbuild/linux-x64": "npm:0.20.2" 1111 | "@esbuild/netbsd-x64": "npm:0.20.2" 1112 | "@esbuild/openbsd-x64": "npm:0.20.2" 1113 | "@esbuild/sunos-x64": "npm:0.20.2" 1114 | "@esbuild/win32-arm64": "npm:0.20.2" 1115 | "@esbuild/win32-ia32": "npm:0.20.2" 1116 | "@esbuild/win32-x64": "npm:0.20.2" 1117 | dependenciesMeta: 1118 | "@esbuild/aix-ppc64": 1119 | optional: true 1120 | "@esbuild/android-arm": 1121 | optional: true 1122 | "@esbuild/android-arm64": 1123 | optional: true 1124 | "@esbuild/android-x64": 1125 | optional: true 1126 | "@esbuild/darwin-arm64": 1127 | optional: true 1128 | "@esbuild/darwin-x64": 1129 | optional: true 1130 | "@esbuild/freebsd-arm64": 1131 | optional: true 1132 | "@esbuild/freebsd-x64": 1133 | optional: true 1134 | "@esbuild/linux-arm": 1135 | optional: true 1136 | "@esbuild/linux-arm64": 1137 | optional: true 1138 | "@esbuild/linux-ia32": 1139 | optional: true 1140 | "@esbuild/linux-loong64": 1141 | optional: true 1142 | "@esbuild/linux-mips64el": 1143 | optional: true 1144 | "@esbuild/linux-ppc64": 1145 | optional: true 1146 | "@esbuild/linux-riscv64": 1147 | optional: true 1148 | "@esbuild/linux-s390x": 1149 | optional: true 1150 | "@esbuild/linux-x64": 1151 | optional: true 1152 | "@esbuild/netbsd-x64": 1153 | optional: true 1154 | "@esbuild/openbsd-x64": 1155 | optional: true 1156 | "@esbuild/sunos-x64": 1157 | optional: true 1158 | "@esbuild/win32-arm64": 1159 | optional: true 1160 | "@esbuild/win32-ia32": 1161 | optional: true 1162 | "@esbuild/win32-x64": 1163 | optional: true 1164 | bin: 1165 | esbuild: bin/esbuild 1166 | checksum: 10c0/66398f9fb2c65e456a3e649747b39af8a001e47963b25e86d9c09d2a48d61aa641b27da0ce5cad63df95ad246105e1d83e7fee0e1e22a0663def73b1c5101112 1167 | languageName: node 1168 | linkType: hard 1169 | 1170 | "escalade@npm:^3.1.1": 1171 | version: 3.1.2 1172 | resolution: "escalade@npm:3.1.2" 1173 | checksum: 10c0/6b4adafecd0682f3aa1cd1106b8fff30e492c7015b178bc81b2d2f75106dabea6c6d6e8508fc491bd58e597c74abb0e8e2368f943ecb9393d4162e3c2f3cf287 1174 | languageName: node 1175 | linkType: hard 1176 | 1177 | "escape-string-regexp@npm:^1.0.5": 1178 | version: 1.0.5 1179 | resolution: "escape-string-regexp@npm:1.0.5" 1180 | checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 1181 | languageName: node 1182 | linkType: hard 1183 | 1184 | "exponential-backoff@npm:^3.1.1": 1185 | version: 3.1.1 1186 | resolution: "exponential-backoff@npm:3.1.1" 1187 | checksum: 10c0/160456d2d647e6019640bd07111634d8c353038d9fa40176afb7cd49b0548bdae83b56d05e907c2cce2300b81cae35d800ef92fefb9d0208e190fa3b7d6bb579 1188 | languageName: node 1189 | linkType: hard 1190 | 1191 | "foreground-child@npm:^3.1.0": 1192 | version: 3.1.1 1193 | resolution: "foreground-child@npm:3.1.1" 1194 | dependencies: 1195 | cross-spawn: "npm:^7.0.0" 1196 | signal-exit: "npm:^4.0.1" 1197 | checksum: 10c0/9700a0285628abaeb37007c9a4d92bd49f67210f09067638774338e146c8e9c825c5c877f072b2f75f41dc6a2d0be8664f79ffc03f6576649f54a84fb9b47de0 1198 | languageName: node 1199 | linkType: hard 1200 | 1201 | "fs-minipass@npm:^2.0.0": 1202 | version: 2.1.0 1203 | resolution: "fs-minipass@npm:2.1.0" 1204 | dependencies: 1205 | minipass: "npm:^3.0.0" 1206 | checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 1207 | languageName: node 1208 | linkType: hard 1209 | 1210 | "fs-minipass@npm:^3.0.0": 1211 | version: 3.0.3 1212 | resolution: "fs-minipass@npm:3.0.3" 1213 | dependencies: 1214 | minipass: "npm:^7.0.3" 1215 | checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 1216 | languageName: node 1217 | linkType: hard 1218 | 1219 | "fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": 1220 | version: 2.3.3 1221 | resolution: "fsevents@npm:2.3.3" 1222 | dependencies: 1223 | node-gyp: "npm:latest" 1224 | checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 1225 | conditions: os=darwin 1226 | languageName: node 1227 | linkType: hard 1228 | 1229 | "fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": 1230 | version: 2.3.3 1231 | resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" 1232 | dependencies: 1233 | node-gyp: "npm:latest" 1234 | conditions: os=darwin 1235 | languageName: node 1236 | linkType: hard 1237 | 1238 | "gensync@npm:^1.0.0-beta.2": 1239 | version: 1.0.0-beta.2 1240 | resolution: "gensync@npm:1.0.0-beta.2" 1241 | checksum: 10c0/782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8 1242 | languageName: node 1243 | linkType: hard 1244 | 1245 | "glob@npm:^10.2.2, glob@npm:^10.3.10": 1246 | version: 10.3.10 1247 | resolution: "glob@npm:10.3.10" 1248 | dependencies: 1249 | foreground-child: "npm:^3.1.0" 1250 | jackspeak: "npm:^2.3.5" 1251 | minimatch: "npm:^9.0.1" 1252 | minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" 1253 | path-scurry: "npm:^1.10.1" 1254 | bin: 1255 | glob: dist/esm/bin.mjs 1256 | checksum: 10c0/13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d 1257 | languageName: node 1258 | linkType: hard 1259 | 1260 | "globals@npm:^11.1.0": 1261 | version: 11.12.0 1262 | resolution: "globals@npm:11.12.0" 1263 | checksum: 10c0/758f9f258e7b19226bd8d4af5d3b0dcf7038780fb23d82e6f98932c44e239f884847f1766e8fa9cc5635ccb3204f7fa7314d4408dd4002a5e8ea827b4018f0a1 1264 | languageName: node 1265 | linkType: hard 1266 | 1267 | "graceful-fs@npm:^4.2.6": 1268 | version: 4.2.11 1269 | resolution: "graceful-fs@npm:4.2.11" 1270 | checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 1271 | languageName: node 1272 | linkType: hard 1273 | 1274 | "graphql-tag@npm:^2.12.6": 1275 | version: 2.12.6 1276 | resolution: "graphql-tag@npm:2.12.6" 1277 | dependencies: 1278 | tslib: "npm:^2.1.0" 1279 | peerDependencies: 1280 | graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 1281 | checksum: 10c0/7763a72011bda454ed8ff1a0d82325f43ca6478e4ce4ab8b7910c4c651dd00db553132171c04d80af5d5aebf1ef6a8a9fd53ccfa33b90ddc00aa3d4be6114419 1282 | languageName: node 1283 | linkType: hard 1284 | 1285 | "graphql@npm:^16.8.1": 1286 | version: 16.8.1 1287 | resolution: "graphql@npm:16.8.1" 1288 | checksum: 10c0/129c318156b466f440914de80dbf7bc67d17f776f2a088a40cb0da611d19a97c224b1c6d2b13cbcbc6e5776e45ed7468b8432f9c3536724e079b44f1a3d57a8a 1289 | languageName: node 1290 | linkType: hard 1291 | 1292 | "has-flag@npm:^3.0.0": 1293 | version: 3.0.0 1294 | resolution: "has-flag@npm:3.0.0" 1295 | checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 1296 | languageName: node 1297 | linkType: hard 1298 | 1299 | "hoist-non-react-statics@npm:^3.3.2": 1300 | version: 3.3.2 1301 | resolution: "hoist-non-react-statics@npm:3.3.2" 1302 | dependencies: 1303 | react-is: "npm:^16.7.0" 1304 | checksum: 10c0/fe0889169e845d738b59b64badf5e55fa3cf20454f9203d1eb088df322d49d4318df774828e789898dcb280e8a5521bb59b3203385662ca5e9218a6ca5820e74 1305 | languageName: node 1306 | linkType: hard 1307 | 1308 | "http-cache-semantics@npm:^4.1.1": 1309 | version: 4.1.1 1310 | resolution: "http-cache-semantics@npm:4.1.1" 1311 | checksum: 10c0/ce1319b8a382eb3cbb4a37c19f6bfe14e5bb5be3d09079e885e8c513ab2d3cd9214902f8a31c9dc4e37022633ceabfc2d697405deeaf1b8f3552bb4ed996fdfc 1312 | languageName: node 1313 | linkType: hard 1314 | 1315 | "http-proxy-agent@npm:^7.0.0": 1316 | version: 7.0.2 1317 | resolution: "http-proxy-agent@npm:7.0.2" 1318 | dependencies: 1319 | agent-base: "npm:^7.1.0" 1320 | debug: "npm:^4.3.4" 1321 | checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921 1322 | languageName: node 1323 | linkType: hard 1324 | 1325 | "https-proxy-agent@npm:^7.0.1": 1326 | version: 7.0.4 1327 | resolution: "https-proxy-agent@npm:7.0.4" 1328 | dependencies: 1329 | agent-base: "npm:^7.0.2" 1330 | debug: "npm:4" 1331 | checksum: 10c0/bc4f7c38da32a5fc622450b6cb49a24ff596f9bd48dcedb52d2da3fa1c1a80e100fb506bd59b326c012f21c863c69b275c23de1a01d0b84db396822fdf25e52b 1332 | languageName: node 1333 | linkType: hard 1334 | 1335 | "iconv-lite@npm:^0.6.2": 1336 | version: 0.6.3 1337 | resolution: "iconv-lite@npm:0.6.3" 1338 | dependencies: 1339 | safer-buffer: "npm:>= 2.1.2 < 3.0.0" 1340 | checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 1341 | languageName: node 1342 | linkType: hard 1343 | 1344 | "imurmurhash@npm:^0.1.4": 1345 | version: 0.1.4 1346 | resolution: "imurmurhash@npm:0.1.4" 1347 | checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 1348 | languageName: node 1349 | linkType: hard 1350 | 1351 | "indent-string@npm:^4.0.0": 1352 | version: 4.0.0 1353 | resolution: "indent-string@npm:4.0.0" 1354 | checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f 1355 | languageName: node 1356 | linkType: hard 1357 | 1358 | "ip-address@npm:^9.0.5": 1359 | version: 9.0.5 1360 | resolution: "ip-address@npm:9.0.5" 1361 | dependencies: 1362 | jsbn: "npm:1.1.0" 1363 | sprintf-js: "npm:^1.1.3" 1364 | checksum: 10c0/331cd07fafcb3b24100613e4b53e1a2b4feab11e671e655d46dc09ee233da5011284d09ca40c4ecbdfe1d0004f462958675c224a804259f2f78d2465a87824bc 1365 | languageName: node 1366 | linkType: hard 1367 | 1368 | "is-fullwidth-code-point@npm:^3.0.0": 1369 | version: 3.0.0 1370 | resolution: "is-fullwidth-code-point@npm:3.0.0" 1371 | checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc 1372 | languageName: node 1373 | linkType: hard 1374 | 1375 | "is-lambda@npm:^1.0.1": 1376 | version: 1.0.1 1377 | resolution: "is-lambda@npm:1.0.1" 1378 | checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d 1379 | languageName: node 1380 | linkType: hard 1381 | 1382 | "isexe@npm:^2.0.0": 1383 | version: 2.0.0 1384 | resolution: "isexe@npm:2.0.0" 1385 | checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d 1386 | languageName: node 1387 | linkType: hard 1388 | 1389 | "isexe@npm:^3.1.1": 1390 | version: 3.1.1 1391 | resolution: "isexe@npm:3.1.1" 1392 | checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 1393 | languageName: node 1394 | linkType: hard 1395 | 1396 | "jackspeak@npm:^2.3.5": 1397 | version: 2.3.6 1398 | resolution: "jackspeak@npm:2.3.6" 1399 | dependencies: 1400 | "@isaacs/cliui": "npm:^8.0.2" 1401 | "@pkgjs/parseargs": "npm:^0.11.0" 1402 | dependenciesMeta: 1403 | "@pkgjs/parseargs": 1404 | optional: true 1405 | checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 1406 | languageName: node 1407 | linkType: hard 1408 | 1409 | "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": 1410 | version: 4.0.0 1411 | resolution: "js-tokens@npm:4.0.0" 1412 | checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed 1413 | languageName: node 1414 | linkType: hard 1415 | 1416 | "jsbn@npm:1.1.0": 1417 | version: 1.1.0 1418 | resolution: "jsbn@npm:1.1.0" 1419 | checksum: 10c0/4f907fb78d7b712e11dea8c165fe0921f81a657d3443dde75359ed52eb2b5d33ce6773d97985a089f09a65edd80b11cb75c767b57ba47391fee4c969f7215c96 1420 | languageName: node 1421 | linkType: hard 1422 | 1423 | "jsesc@npm:^2.5.1": 1424 | version: 2.5.2 1425 | resolution: "jsesc@npm:2.5.2" 1426 | bin: 1427 | jsesc: bin/jsesc 1428 | checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88 1429 | languageName: node 1430 | linkType: hard 1431 | 1432 | "json5@npm:^2.2.3": 1433 | version: 2.2.3 1434 | resolution: "json5@npm:2.2.3" 1435 | bin: 1436 | json5: lib/cli.js 1437 | checksum: 10c0/5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c 1438 | languageName: node 1439 | linkType: hard 1440 | 1441 | "loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": 1442 | version: 1.4.0 1443 | resolution: "loose-envify@npm:1.4.0" 1444 | dependencies: 1445 | js-tokens: "npm:^3.0.0 || ^4.0.0" 1446 | bin: 1447 | loose-envify: cli.js 1448 | checksum: 10c0/655d110220983c1a4b9c0c679a2e8016d4b67f6e9c7b5435ff5979ecdb20d0813f4dec0a08674fcbdd4846a3f07edbb50a36811fd37930b94aaa0d9daceb017e 1449 | languageName: node 1450 | linkType: hard 1451 | 1452 | "lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": 1453 | version: 10.2.0 1454 | resolution: "lru-cache@npm:10.2.0" 1455 | checksum: 10c0/c9847612aa2daaef102d30542a8d6d9b2c2bb36581c1bf0dc3ebf5e5f3352c772a749e604afae2e46873b930a9e9523743faac4e5b937c576ab29196774712ee 1456 | languageName: node 1457 | linkType: hard 1458 | 1459 | "lru-cache@npm:^5.1.1": 1460 | version: 5.1.1 1461 | resolution: "lru-cache@npm:5.1.1" 1462 | dependencies: 1463 | yallist: "npm:^3.0.2" 1464 | checksum: 10c0/89b2ef2ef45f543011e38737b8a8622a2f8998cddf0e5437174ef8f1f70a8b9d14a918ab3e232cb3ba343b7abddffa667f0b59075b2b80e6b4d63c3de6127482 1465 | languageName: node 1466 | linkType: hard 1467 | 1468 | "lru-cache@npm:^6.0.0": 1469 | version: 6.0.0 1470 | resolution: "lru-cache@npm:6.0.0" 1471 | dependencies: 1472 | yallist: "npm:^4.0.0" 1473 | checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 1474 | languageName: node 1475 | linkType: hard 1476 | 1477 | "make-fetch-happen@npm:^13.0.0": 1478 | version: 13.0.0 1479 | resolution: "make-fetch-happen@npm:13.0.0" 1480 | dependencies: 1481 | "@npmcli/agent": "npm:^2.0.0" 1482 | cacache: "npm:^18.0.0" 1483 | http-cache-semantics: "npm:^4.1.1" 1484 | is-lambda: "npm:^1.0.1" 1485 | minipass: "npm:^7.0.2" 1486 | minipass-fetch: "npm:^3.0.0" 1487 | minipass-flush: "npm:^1.0.5" 1488 | minipass-pipeline: "npm:^1.2.4" 1489 | negotiator: "npm:^0.6.3" 1490 | promise-retry: "npm:^2.0.1" 1491 | ssri: "npm:^10.0.0" 1492 | checksum: 10c0/43b9f6dcbc6fe8b8604cb6396957c3698857a15ba4dbc38284f7f0e61f248300585ef1eb8cc62df54e9c724af977e45b5cdfd88320ef7f53e45070ed3488da55 1493 | languageName: node 1494 | linkType: hard 1495 | 1496 | "minimatch@npm:^9.0.1": 1497 | version: 9.0.3 1498 | resolution: "minimatch@npm:9.0.3" 1499 | dependencies: 1500 | brace-expansion: "npm:^2.0.1" 1501 | checksum: 10c0/85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac 1502 | languageName: node 1503 | linkType: hard 1504 | 1505 | "minipass-collect@npm:^2.0.1": 1506 | version: 2.0.1 1507 | resolution: "minipass-collect@npm:2.0.1" 1508 | dependencies: 1509 | minipass: "npm:^7.0.3" 1510 | checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e 1511 | languageName: node 1512 | linkType: hard 1513 | 1514 | "minipass-fetch@npm:^3.0.0": 1515 | version: 3.0.4 1516 | resolution: "minipass-fetch@npm:3.0.4" 1517 | dependencies: 1518 | encoding: "npm:^0.1.13" 1519 | minipass: "npm:^7.0.3" 1520 | minipass-sized: "npm:^1.0.3" 1521 | minizlib: "npm:^2.1.2" 1522 | dependenciesMeta: 1523 | encoding: 1524 | optional: true 1525 | checksum: 10c0/1b63c1f3313e88eeac4689f1b71c9f086598db9a189400e3ee960c32ed89e06737fa23976c9305c2d57464fb3fcdc12749d3378805c9d6176f5569b0d0ee8a75 1526 | languageName: node 1527 | linkType: hard 1528 | 1529 | "minipass-flush@npm:^1.0.5": 1530 | version: 1.0.5 1531 | resolution: "minipass-flush@npm:1.0.5" 1532 | dependencies: 1533 | minipass: "npm:^3.0.0" 1534 | checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd 1535 | languageName: node 1536 | linkType: hard 1537 | 1538 | "minipass-pipeline@npm:^1.2.4": 1539 | version: 1.2.4 1540 | resolution: "minipass-pipeline@npm:1.2.4" 1541 | dependencies: 1542 | minipass: "npm:^3.0.0" 1543 | checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 1544 | languageName: node 1545 | linkType: hard 1546 | 1547 | "minipass-sized@npm:^1.0.3": 1548 | version: 1.0.3 1549 | resolution: "minipass-sized@npm:1.0.3" 1550 | dependencies: 1551 | minipass: "npm:^3.0.0" 1552 | checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb 1553 | languageName: node 1554 | linkType: hard 1555 | 1556 | "minipass@npm:^3.0.0": 1557 | version: 3.3.6 1558 | resolution: "minipass@npm:3.3.6" 1559 | dependencies: 1560 | yallist: "npm:^4.0.0" 1561 | checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c 1562 | languageName: node 1563 | linkType: hard 1564 | 1565 | "minipass@npm:^5.0.0": 1566 | version: 5.0.0 1567 | resolution: "minipass@npm:5.0.0" 1568 | checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 1569 | languageName: node 1570 | linkType: hard 1571 | 1572 | "minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": 1573 | version: 7.0.4 1574 | resolution: "minipass@npm:7.0.4" 1575 | checksum: 10c0/6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 1576 | languageName: node 1577 | linkType: hard 1578 | 1579 | "minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": 1580 | version: 2.1.2 1581 | resolution: "minizlib@npm:2.1.2" 1582 | dependencies: 1583 | minipass: "npm:^3.0.0" 1584 | yallist: "npm:^4.0.0" 1585 | checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 1586 | languageName: node 1587 | linkType: hard 1588 | 1589 | "mkdirp@npm:^1.0.3": 1590 | version: 1.0.4 1591 | resolution: "mkdirp@npm:1.0.4" 1592 | bin: 1593 | mkdirp: bin/cmd.js 1594 | checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf 1595 | languageName: node 1596 | linkType: hard 1597 | 1598 | "ms@npm:2.1.2": 1599 | version: 2.1.2 1600 | resolution: "ms@npm:2.1.2" 1601 | checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc 1602 | languageName: node 1603 | linkType: hard 1604 | 1605 | "nanoid@npm:^3.3.7": 1606 | version: 3.3.7 1607 | resolution: "nanoid@npm:3.3.7" 1608 | bin: 1609 | nanoid: bin/nanoid.cjs 1610 | checksum: 10c0/e3fb661aa083454f40500473bb69eedb85dc160e763150b9a2c567c7e9ff560ce028a9f833123b618a6ea742e311138b591910e795614a629029e86e180660f3 1611 | languageName: node 1612 | linkType: hard 1613 | 1614 | "negotiator@npm:^0.6.3": 1615 | version: 0.6.3 1616 | resolution: "negotiator@npm:0.6.3" 1617 | checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 1618 | languageName: node 1619 | linkType: hard 1620 | 1621 | "node-gyp@npm:latest": 1622 | version: 10.1.0 1623 | resolution: "node-gyp@npm:10.1.0" 1624 | dependencies: 1625 | env-paths: "npm:^2.2.0" 1626 | exponential-backoff: "npm:^3.1.1" 1627 | glob: "npm:^10.3.10" 1628 | graceful-fs: "npm:^4.2.6" 1629 | make-fetch-happen: "npm:^13.0.0" 1630 | nopt: "npm:^7.0.0" 1631 | proc-log: "npm:^3.0.0" 1632 | semver: "npm:^7.3.5" 1633 | tar: "npm:^6.1.2" 1634 | which: "npm:^4.0.0" 1635 | bin: 1636 | node-gyp: bin/node-gyp.js 1637 | checksum: 10c0/9cc821111ca244a01fb7f054db7523ab0a0cd837f665267eb962eb87695d71fb1e681f9e21464cc2fd7c05530dc4c81b810bca1a88f7d7186909b74477491a3c 1638 | languageName: node 1639 | linkType: hard 1640 | 1641 | "node-releases@npm:^2.0.14": 1642 | version: 2.0.14 1643 | resolution: "node-releases@npm:2.0.14" 1644 | checksum: 10c0/199fc93773ae70ec9969bc6d5ac5b2bbd6eb986ed1907d751f411fef3ede0e4bfdb45ceb43711f8078bea237b6036db8b1bf208f6ff2b70c7d615afd157f3ab9 1645 | languageName: node 1646 | linkType: hard 1647 | 1648 | "nopt@npm:^7.0.0": 1649 | version: 7.2.0 1650 | resolution: "nopt@npm:7.2.0" 1651 | dependencies: 1652 | abbrev: "npm:^2.0.0" 1653 | bin: 1654 | nopt: bin/nopt.js 1655 | checksum: 10c0/9bd7198df6f16eb29ff16892c77bcf7f0cc41f9fb5c26280ac0def2cf8cf319f3b821b3af83eba0e74c85807cc430a16efe0db58fe6ae1f41e69519f585b6aff 1656 | languageName: node 1657 | linkType: hard 1658 | 1659 | "object-assign@npm:^4.1.1": 1660 | version: 4.1.1 1661 | resolution: "object-assign@npm:4.1.1" 1662 | checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 1663 | languageName: node 1664 | linkType: hard 1665 | 1666 | "optimism@npm:^0.18.0": 1667 | version: 0.18.0 1668 | resolution: "optimism@npm:0.18.0" 1669 | dependencies: 1670 | "@wry/caches": "npm:^1.0.0" 1671 | "@wry/context": "npm:^0.7.0" 1672 | "@wry/trie": "npm:^0.4.3" 1673 | tslib: "npm:^2.3.0" 1674 | checksum: 10c0/8e97c6d660cb80cf5f444209b9dd29ee6951fa7b344d4c4fc6d4aaf0ad0710dddaf834d0f5d7211b3658b15ef6c6a22cbcb98c7a8121e3fee9666fe0fd62d876 1675 | languageName: node 1676 | linkType: hard 1677 | 1678 | "p-map@npm:^4.0.0": 1679 | version: 4.0.0 1680 | resolution: "p-map@npm:4.0.0" 1681 | dependencies: 1682 | aggregate-error: "npm:^3.0.0" 1683 | checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 1684 | languageName: node 1685 | linkType: hard 1686 | 1687 | "path-key@npm:^3.1.0": 1688 | version: 3.1.1 1689 | resolution: "path-key@npm:3.1.1" 1690 | checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c 1691 | languageName: node 1692 | linkType: hard 1693 | 1694 | "path-scurry@npm:^1.10.1": 1695 | version: 1.10.1 1696 | resolution: "path-scurry@npm:1.10.1" 1697 | dependencies: 1698 | lru-cache: "npm:^9.1.1 || ^10.0.0" 1699 | minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" 1700 | checksum: 10c0/e5dc78a7348d25eec61ab166317e9e9c7b46818aa2c2b9006c507a6ff48c672d011292d9662527213e558f5652ce0afcc788663a061d8b59ab495681840c0c1e 1701 | languageName: node 1702 | linkType: hard 1703 | 1704 | "picocolors@npm:^1.0.0": 1705 | version: 1.0.0 1706 | resolution: "picocolors@npm:1.0.0" 1707 | checksum: 10c0/20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7 1708 | languageName: node 1709 | linkType: hard 1710 | 1711 | "postcss@npm:^8.4.36": 1712 | version: 8.4.38 1713 | resolution: "postcss@npm:8.4.38" 1714 | dependencies: 1715 | nanoid: "npm:^3.3.7" 1716 | picocolors: "npm:^1.0.0" 1717 | source-map-js: "npm:^1.2.0" 1718 | checksum: 10c0/955407b8f70cf0c14acf35dab3615899a2a60a26718a63c848cf3c29f2467b0533991b985a2b994430d890bd7ec2b1963e36352b0774a19143b5f591540f7c06 1719 | languageName: node 1720 | linkType: hard 1721 | 1722 | "proc-log@npm:^3.0.0": 1723 | version: 3.0.0 1724 | resolution: "proc-log@npm:3.0.0" 1725 | checksum: 10c0/f66430e4ff947dbb996058f6fd22de2c66612ae1a89b097744e17fb18a4e8e7a86db99eda52ccf15e53f00b63f4ec0b0911581ff2aac0355b625c8eac509b0dc 1726 | languageName: node 1727 | linkType: hard 1728 | 1729 | "promise-retry@npm:^2.0.1": 1730 | version: 2.0.1 1731 | resolution: "promise-retry@npm:2.0.1" 1732 | dependencies: 1733 | err-code: "npm:^2.0.2" 1734 | retry: "npm:^0.12.0" 1735 | checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 1736 | languageName: node 1737 | linkType: hard 1738 | 1739 | "prop-types@npm:^15.7.2": 1740 | version: 15.8.1 1741 | resolution: "prop-types@npm:15.8.1" 1742 | dependencies: 1743 | loose-envify: "npm:^1.4.0" 1744 | object-assign: "npm:^4.1.1" 1745 | react-is: "npm:^16.13.1" 1746 | checksum: 10c0/59ece7ca2fb9838031d73a48d4becb9a7cc1ed10e610517c7d8f19a1e02fa47f7c27d557d8a5702bec3cfeccddc853579832b43f449e54635803f277b1c78077 1747 | languageName: node 1748 | linkType: hard 1749 | 1750 | "react-dom@npm:^18.2.0": 1751 | version: 18.2.0 1752 | resolution: "react-dom@npm:18.2.0" 1753 | dependencies: 1754 | loose-envify: "npm:^1.1.0" 1755 | scheduler: "npm:^0.23.0" 1756 | peerDependencies: 1757 | react: ^18.2.0 1758 | checksum: 10c0/66dfc5f93e13d0674e78ef41f92ed21dfb80f9c4ac4ac25a4b51046d41d4d2186abc915b897f69d3d0ebbffe6184e7c5876f2af26bfa956f179225d921be713a 1759 | languageName: node 1760 | linkType: hard 1761 | 1762 | "react-is@npm:^16.13.1, react-is@npm:^16.7.0": 1763 | version: 16.13.1 1764 | resolution: "react-is@npm:16.13.1" 1765 | checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 1766 | languageName: node 1767 | linkType: hard 1768 | 1769 | "react-refresh@npm:^0.14.0": 1770 | version: 0.14.0 1771 | resolution: "react-refresh@npm:0.14.0" 1772 | checksum: 10c0/b8ae07ad153357d77830928a7f1fc2df837aabefee907fa273ba04c7643f3b860e986f1d4b7ada9b721c8d79b8c24b5b911a314a1a2398b105f1b13d19ea2b8d 1773 | languageName: node 1774 | linkType: hard 1775 | 1776 | "react@npm:^18.2.0": 1777 | version: 18.2.0 1778 | resolution: "react@npm:18.2.0" 1779 | dependencies: 1780 | loose-envify: "npm:^1.1.0" 1781 | checksum: 10c0/b562d9b569b0cb315e44b48099f7712283d93df36b19a39a67c254c6686479d3980b7f013dc931f4a5a3ae7645eae6386b4aa5eea933baa54ecd0f9acb0902b8 1782 | languageName: node 1783 | linkType: hard 1784 | 1785 | "rehackt@npm:0.0.6": 1786 | version: 0.0.6 1787 | resolution: "rehackt@npm:0.0.6" 1788 | peerDependencies: 1789 | "@types/react": "*" 1790 | react: "*" 1791 | peerDependenciesMeta: 1792 | "@types/react": 1793 | optional: true 1794 | react: 1795 | optional: true 1796 | checksum: 10c0/814c9b80b2680dc0572639ecad1ed1961b23b606e53a00976ee4c4876f6ed736ea702381235ac40ed2a5c826fb55641b46ae23343e4ddd6378ced1da3d51ada7 1797 | languageName: node 1798 | linkType: hard 1799 | 1800 | "response-iterator@npm:^0.2.6": 1801 | version: 0.2.6 1802 | resolution: "response-iterator@npm:0.2.6" 1803 | checksum: 10c0/60e6b552cd610643269d5d916d270cc8a4bea978cbe4779d6ef8083ac6b89006795508034e4c4ebe204eded75ac32bf243589ba82c1184591dde0674f6db785e 1804 | languageName: node 1805 | linkType: hard 1806 | 1807 | "retry@npm:^0.12.0": 1808 | version: 0.12.0 1809 | resolution: "retry@npm:0.12.0" 1810 | checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe 1811 | languageName: node 1812 | linkType: hard 1813 | 1814 | "rollup@npm:^4.13.0": 1815 | version: 4.13.0 1816 | resolution: "rollup@npm:4.13.0" 1817 | dependencies: 1818 | "@rollup/rollup-android-arm-eabi": "npm:4.13.0" 1819 | "@rollup/rollup-android-arm64": "npm:4.13.0" 1820 | "@rollup/rollup-darwin-arm64": "npm:4.13.0" 1821 | "@rollup/rollup-darwin-x64": "npm:4.13.0" 1822 | "@rollup/rollup-linux-arm-gnueabihf": "npm:4.13.0" 1823 | "@rollup/rollup-linux-arm64-gnu": "npm:4.13.0" 1824 | "@rollup/rollup-linux-arm64-musl": "npm:4.13.0" 1825 | "@rollup/rollup-linux-riscv64-gnu": "npm:4.13.0" 1826 | "@rollup/rollup-linux-x64-gnu": "npm:4.13.0" 1827 | "@rollup/rollup-linux-x64-musl": "npm:4.13.0" 1828 | "@rollup/rollup-win32-arm64-msvc": "npm:4.13.0" 1829 | "@rollup/rollup-win32-ia32-msvc": "npm:4.13.0" 1830 | "@rollup/rollup-win32-x64-msvc": "npm:4.13.0" 1831 | "@types/estree": "npm:1.0.5" 1832 | fsevents: "npm:~2.3.2" 1833 | dependenciesMeta: 1834 | "@rollup/rollup-android-arm-eabi": 1835 | optional: true 1836 | "@rollup/rollup-android-arm64": 1837 | optional: true 1838 | "@rollup/rollup-darwin-arm64": 1839 | optional: true 1840 | "@rollup/rollup-darwin-x64": 1841 | optional: true 1842 | "@rollup/rollup-linux-arm-gnueabihf": 1843 | optional: true 1844 | "@rollup/rollup-linux-arm64-gnu": 1845 | optional: true 1846 | "@rollup/rollup-linux-arm64-musl": 1847 | optional: true 1848 | "@rollup/rollup-linux-riscv64-gnu": 1849 | optional: true 1850 | "@rollup/rollup-linux-x64-gnu": 1851 | optional: true 1852 | "@rollup/rollup-linux-x64-musl": 1853 | optional: true 1854 | "@rollup/rollup-win32-arm64-msvc": 1855 | optional: true 1856 | "@rollup/rollup-win32-ia32-msvc": 1857 | optional: true 1858 | "@rollup/rollup-win32-x64-msvc": 1859 | optional: true 1860 | fsevents: 1861 | optional: true 1862 | bin: 1863 | rollup: dist/bin/rollup 1864 | checksum: 10c0/90f8cdf9c2115223cbcfe91d932170a85c0928ae1943f45af6877907ea150585b80f656cf2bc471c6f809cb7e158dd85dbea9f91ab4fd5bce0eaf6c3f5f4fd92 1865 | languageName: node 1866 | linkType: hard 1867 | 1868 | "safer-buffer@npm:>= 2.1.2 < 3.0.0": 1869 | version: 2.1.2 1870 | resolution: "safer-buffer@npm:2.1.2" 1871 | checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 1872 | languageName: node 1873 | linkType: hard 1874 | 1875 | "scheduler@npm:^0.23.0": 1876 | version: 0.23.0 1877 | resolution: "scheduler@npm:0.23.0" 1878 | dependencies: 1879 | loose-envify: "npm:^1.1.0" 1880 | checksum: 10c0/b777f7ca0115e6d93e126ac490dbd82642d14983b3079f58f35519d992fa46260be7d6e6cede433a92db70306310c6f5f06e144f0e40c484199e09c1f7be53dd 1881 | languageName: node 1882 | linkType: hard 1883 | 1884 | "semver@npm:^6.3.1": 1885 | version: 6.3.1 1886 | resolution: "semver@npm:6.3.1" 1887 | bin: 1888 | semver: bin/semver.js 1889 | checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d 1890 | languageName: node 1891 | linkType: hard 1892 | 1893 | "semver@npm:^7.3.5": 1894 | version: 7.6.0 1895 | resolution: "semver@npm:7.6.0" 1896 | dependencies: 1897 | lru-cache: "npm:^6.0.0" 1898 | bin: 1899 | semver: bin/semver.js 1900 | checksum: 10c0/fbfe717094ace0aa8d6332d7ef5ce727259815bd8d8815700853f4faf23aacbd7192522f0dc5af6df52ef4fa85a355ebd2f5d39f554bd028200d6cf481ab9b53 1901 | languageName: node 1902 | linkType: hard 1903 | 1904 | "shebang-command@npm:^2.0.0": 1905 | version: 2.0.0 1906 | resolution: "shebang-command@npm:2.0.0" 1907 | dependencies: 1908 | shebang-regex: "npm:^3.0.0" 1909 | checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e 1910 | languageName: node 1911 | linkType: hard 1912 | 1913 | "shebang-regex@npm:^3.0.0": 1914 | version: 3.0.0 1915 | resolution: "shebang-regex@npm:3.0.0" 1916 | checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 1917 | languageName: node 1918 | linkType: hard 1919 | 1920 | "signal-exit@npm:^4.0.1": 1921 | version: 4.1.0 1922 | resolution: "signal-exit@npm:4.1.0" 1923 | checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 1924 | languageName: node 1925 | linkType: hard 1926 | 1927 | "smart-buffer@npm:^4.2.0": 1928 | version: 4.2.0 1929 | resolution: "smart-buffer@npm:4.2.0" 1930 | checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 1931 | languageName: node 1932 | linkType: hard 1933 | 1934 | "socks-proxy-agent@npm:^8.0.1": 1935 | version: 8.0.2 1936 | resolution: "socks-proxy-agent@npm:8.0.2" 1937 | dependencies: 1938 | agent-base: "npm:^7.0.2" 1939 | debug: "npm:^4.3.4" 1940 | socks: "npm:^2.7.1" 1941 | checksum: 10c0/a842402fc9b8848a31367f2811ca3cd14c4106588b39a0901cd7a69029998adfc6456b0203617c18ed090542ad0c24ee4e9d4c75a0c4b75071e214227c177eb7 1942 | languageName: node 1943 | linkType: hard 1944 | 1945 | "socks@npm:^2.7.1": 1946 | version: 2.8.1 1947 | resolution: "socks@npm:2.8.1" 1948 | dependencies: 1949 | ip-address: "npm:^9.0.5" 1950 | smart-buffer: "npm:^4.2.0" 1951 | checksum: 10c0/ac77b515c260473cc7c4452f09b20939e22510ce3ae48385c516d1d5784374d5cc75be3cb18ff66cc985a7f4f2ef8fef84e984c5ec70aad58355ed59241f40a8 1952 | languageName: node 1953 | linkType: hard 1954 | 1955 | "source-map-js@npm:^1.2.0": 1956 | version: 1.2.0 1957 | resolution: "source-map-js@npm:1.2.0" 1958 | checksum: 10c0/7e5f896ac10a3a50fe2898e5009c58ff0dc102dcb056ed27a354623a0ece8954d4b2649e1a1b2b52ef2e161d26f8859c7710350930751640e71e374fe2d321a4 1959 | languageName: node 1960 | linkType: hard 1961 | 1962 | "sprintf-js@npm:^1.1.3": 1963 | version: 1.1.3 1964 | resolution: "sprintf-js@npm:1.1.3" 1965 | checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec 1966 | languageName: node 1967 | linkType: hard 1968 | 1969 | "ssri@npm:^10.0.0": 1970 | version: 10.0.5 1971 | resolution: "ssri@npm:10.0.5" 1972 | dependencies: 1973 | minipass: "npm:^7.0.3" 1974 | checksum: 10c0/b091f2ae92474183c7ac5ed3f9811457e1df23df7a7e70c9476eaa9a0c4a0c8fc190fb45acefbf023ca9ee864dd6754237a697dc52a0fb182afe65d8e77443d8 1975 | languageName: node 1976 | linkType: hard 1977 | 1978 | "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": 1979 | version: 4.2.3 1980 | resolution: "string-width@npm:4.2.3" 1981 | dependencies: 1982 | emoji-regex: "npm:^8.0.0" 1983 | is-fullwidth-code-point: "npm:^3.0.0" 1984 | strip-ansi: "npm:^6.0.1" 1985 | checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b 1986 | languageName: node 1987 | linkType: hard 1988 | 1989 | "string-width@npm:^5.0.1, string-width@npm:^5.1.2": 1990 | version: 5.1.2 1991 | resolution: "string-width@npm:5.1.2" 1992 | dependencies: 1993 | eastasianwidth: "npm:^0.2.0" 1994 | emoji-regex: "npm:^9.2.2" 1995 | strip-ansi: "npm:^7.0.1" 1996 | checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca 1997 | languageName: node 1998 | linkType: hard 1999 | 2000 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": 2001 | version: 6.0.1 2002 | resolution: "strip-ansi@npm:6.0.1" 2003 | dependencies: 2004 | ansi-regex: "npm:^5.0.1" 2005 | checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 2006 | languageName: node 2007 | linkType: hard 2008 | 2009 | "strip-ansi@npm:^7.0.1": 2010 | version: 7.1.0 2011 | resolution: "strip-ansi@npm:7.1.0" 2012 | dependencies: 2013 | ansi-regex: "npm:^6.0.1" 2014 | checksum: 10c0/a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4 2015 | languageName: node 2016 | linkType: hard 2017 | 2018 | "supports-color@npm:^5.3.0": 2019 | version: 5.5.0 2020 | resolution: "supports-color@npm:5.5.0" 2021 | dependencies: 2022 | has-flag: "npm:^3.0.0" 2023 | checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 2024 | languageName: node 2025 | linkType: hard 2026 | 2027 | "symbol-observable@npm:^4.0.0": 2028 | version: 4.0.0 2029 | resolution: "symbol-observable@npm:4.0.0" 2030 | checksum: 10c0/5e9a3ab08263a6be8cbee76587ad5880dcc62a47002787ed5ebea56b1eb30dc87da6f0183d67e88286806799fbe21c69077fbd677be4be2188e92318d6c6f31d 2031 | languageName: node 2032 | linkType: hard 2033 | 2034 | "tar@npm:^6.1.11, tar@npm:^6.1.2": 2035 | version: 6.2.1 2036 | resolution: "tar@npm:6.2.1" 2037 | dependencies: 2038 | chownr: "npm:^2.0.0" 2039 | fs-minipass: "npm:^2.0.0" 2040 | minipass: "npm:^5.0.0" 2041 | minizlib: "npm:^2.1.1" 2042 | mkdirp: "npm:^1.0.3" 2043 | yallist: "npm:^4.0.0" 2044 | checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 2045 | languageName: node 2046 | linkType: hard 2047 | 2048 | "to-fast-properties@npm:^2.0.0": 2049 | version: 2.0.0 2050 | resolution: "to-fast-properties@npm:2.0.0" 2051 | checksum: 10c0/b214d21dbfb4bce3452b6244b336806ffea9c05297148d32ebb428d5c43ce7545bdfc65a1ceb58c9ef4376a65c0cb2854d645f33961658b3e3b4f84910ddcdd7 2052 | languageName: node 2053 | linkType: hard 2054 | 2055 | "ts-invariant@npm:^0.10.3": 2056 | version: 0.10.3 2057 | resolution: "ts-invariant@npm:0.10.3" 2058 | dependencies: 2059 | tslib: "npm:^2.1.0" 2060 | checksum: 10c0/2fbc178d5903d325ee0b87fad38827eac11888b6e86979b06754fd4bcdcf44c2a99b8bcd5d59d149c0464ede55ae810b02a2aee6835ad10efe4dd0e22efd68c0 2061 | languageName: node 2062 | linkType: hard 2063 | 2064 | "tslib@npm:^2.1.0, tslib@npm:^2.3.0": 2065 | version: 2.6.2 2066 | resolution: "tslib@npm:2.6.2" 2067 | checksum: 10c0/e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb 2068 | languageName: node 2069 | linkType: hard 2070 | 2071 | "typescript@npm:^5.4.3": 2072 | version: 5.4.3 2073 | resolution: "typescript@npm:5.4.3" 2074 | bin: 2075 | tsc: bin/tsc 2076 | tsserver: bin/tsserver 2077 | checksum: 10c0/22443a8760c3668e256c0b34b6b45c359ef6cecc10c42558806177a7d500ab1a7d7aac1f976d712e26989ddf6731d2fbdd3212b7c73290a45127c1c43ba2005a 2078 | languageName: node 2079 | linkType: hard 2080 | 2081 | "typescript@patch:typescript@npm%3A^5.4.3#optional!builtin": 2082 | version: 5.4.3 2083 | resolution: "typescript@patch:typescript@npm%3A5.4.3#optional!builtin::version=5.4.3&hash=5adc0c" 2084 | bin: 2085 | tsc: bin/tsc 2086 | tsserver: bin/tsserver 2087 | checksum: 10c0/6e51f8b7e6ec55b897b9e56b67e864fe8f44e30f4a14357aad5dc0f7432db2f01efc0522df0b6c36d361c51f2dc3dcac5c832efd96a404cfabf884e915d38828 2088 | languageName: node 2089 | linkType: hard 2090 | 2091 | "unique-filename@npm:^3.0.0": 2092 | version: 3.0.0 2093 | resolution: "unique-filename@npm:3.0.0" 2094 | dependencies: 2095 | unique-slug: "npm:^4.0.0" 2096 | checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f 2097 | languageName: node 2098 | linkType: hard 2099 | 2100 | "unique-slug@npm:^4.0.0": 2101 | version: 4.0.0 2102 | resolution: "unique-slug@npm:4.0.0" 2103 | dependencies: 2104 | imurmurhash: "npm:^0.1.4" 2105 | checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635 2106 | languageName: node 2107 | linkType: hard 2108 | 2109 | "update-browserslist-db@npm:^1.0.13": 2110 | version: 1.0.13 2111 | resolution: "update-browserslist-db@npm:1.0.13" 2112 | dependencies: 2113 | escalade: "npm:^3.1.1" 2114 | picocolors: "npm:^1.0.0" 2115 | peerDependencies: 2116 | browserslist: ">= 4.21.0" 2117 | bin: 2118 | update-browserslist-db: cli.js 2119 | checksum: 10c0/e52b8b521c78ce1e0c775f356cd16a9c22c70d25f3e01180839c407a5dc787fb05a13f67560cbaf316770d26fa99f78f1acd711b1b54a4f35d4820d4ea7136e6 2120 | languageName: node 2121 | linkType: hard 2122 | 2123 | "vite@npm:^5.2.6": 2124 | version: 5.2.6 2125 | resolution: "vite@npm:5.2.6" 2126 | dependencies: 2127 | esbuild: "npm:^0.20.1" 2128 | fsevents: "npm:~2.3.3" 2129 | postcss: "npm:^8.4.36" 2130 | rollup: "npm:^4.13.0" 2131 | peerDependencies: 2132 | "@types/node": ^18.0.0 || >=20.0.0 2133 | less: "*" 2134 | lightningcss: ^1.21.0 2135 | sass: "*" 2136 | stylus: "*" 2137 | sugarss: "*" 2138 | terser: ^5.4.0 2139 | dependenciesMeta: 2140 | fsevents: 2141 | optional: true 2142 | peerDependenciesMeta: 2143 | "@types/node": 2144 | optional: true 2145 | less: 2146 | optional: true 2147 | lightningcss: 2148 | optional: true 2149 | sass: 2150 | optional: true 2151 | stylus: 2152 | optional: true 2153 | sugarss: 2154 | optional: true 2155 | terser: 2156 | optional: true 2157 | bin: 2158 | vite: bin/vite.js 2159 | checksum: 10c0/9ccaa65521b738ed5d6ad9cd118584a833191d29649eaa77ccb8096a60ded2ca9014193b8b866ad76054d0c89443f7b68b578686e4e2ef83147273e7788408c2 2160 | languageName: node 2161 | linkType: hard 2162 | 2163 | "which@npm:^2.0.1": 2164 | version: 2.0.2 2165 | resolution: "which@npm:2.0.2" 2166 | dependencies: 2167 | isexe: "npm:^2.0.0" 2168 | bin: 2169 | node-which: ./bin/node-which 2170 | checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f 2171 | languageName: node 2172 | linkType: hard 2173 | 2174 | "which@npm:^4.0.0": 2175 | version: 4.0.0 2176 | resolution: "which@npm:4.0.0" 2177 | dependencies: 2178 | isexe: "npm:^3.1.1" 2179 | bin: 2180 | node-which: bin/which.js 2181 | checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a 2182 | languageName: node 2183 | linkType: hard 2184 | 2185 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": 2186 | version: 7.0.0 2187 | resolution: "wrap-ansi@npm:7.0.0" 2188 | dependencies: 2189 | ansi-styles: "npm:^4.0.0" 2190 | string-width: "npm:^4.1.0" 2191 | strip-ansi: "npm:^6.0.0" 2192 | checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da 2193 | languageName: node 2194 | linkType: hard 2195 | 2196 | "wrap-ansi@npm:^8.1.0": 2197 | version: 8.1.0 2198 | resolution: "wrap-ansi@npm:8.1.0" 2199 | dependencies: 2200 | ansi-styles: "npm:^6.1.0" 2201 | string-width: "npm:^5.0.1" 2202 | strip-ansi: "npm:^7.0.1" 2203 | checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 2204 | languageName: node 2205 | linkType: hard 2206 | 2207 | "yallist@npm:^3.0.2": 2208 | version: 3.1.1 2209 | resolution: "yallist@npm:3.1.1" 2210 | checksum: 10c0/c66a5c46bc89af1625476f7f0f2ec3653c1a1791d2f9407cfb4c2ba812a1e1c9941416d71ba9719876530e3340a99925f697142989371b72d93b9ee628afd8c1 2211 | languageName: node 2212 | linkType: hard 2213 | 2214 | "yallist@npm:^4.0.0": 2215 | version: 4.0.0 2216 | resolution: "yallist@npm:4.0.0" 2217 | checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a 2218 | languageName: node 2219 | linkType: hard 2220 | 2221 | "zen-observable-ts@npm:^1.2.5": 2222 | version: 1.2.5 2223 | resolution: "zen-observable-ts@npm:1.2.5" 2224 | dependencies: 2225 | zen-observable: "npm:0.8.15" 2226 | checksum: 10c0/21d586f3d0543e1d6f05d9333a137b407dbf337907c1ee1c2fa7a7da044f7e1262e4baf4ef8902f230c6f5acb561047659eb7df73df33307233cc451efe46db1 2227 | languageName: node 2228 | linkType: hard 2229 | 2230 | "zen-observable@npm:0.8.15": 2231 | version: 0.8.15 2232 | resolution: "zen-observable@npm:0.8.15" 2233 | checksum: 10c0/71cc2f2bbb537300c3f569e25693d37b3bc91f225cefce251a71c30bc6bb3e7f8e9420ca0eb57f2ac9e492b085b8dfa075fd1e8195c40b83c951dd59c6e4fbf8 2234 | languageName: node 2235 | linkType: hard 2236 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "apollo3-cache-persist", 3 | "version": "0.15.0", 4 | "description": "Simple persistence for all Apollo cache implementations", 5 | "author": "James Reggio ", 6 | "contributors": [ 7 | "James Reggio ", 8 | "Peggy Rayzis " 9 | ], 10 | "license": "MIT", 11 | "main": "./lib/cjs/index.js", 12 | "module": "./lib/index.js", 13 | "jsnext:main": "./lib/index.js", 14 | "typings": "./lib/index.d.ts", 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/apollographql/apollo-cache-persist.git" 18 | }, 19 | "homepage": "https://github.com/apollographql/apollo-cache-persist#readme", 20 | "bugs": "https://github.com/apollographql/apollo-cache-persist/issues", 21 | "scripts": { 22 | "version": "yarn run changelog && git add CHANGELOG.md", 23 | "postversion": "yarn run publish:git && yarn run publish:npm", 24 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 1", 25 | "build:browser": "browserify ./lib/bundle.umd.js -o=./lib/bundle.js && npm run minify:browser", 26 | "build": "tsc -p . && tsc -p ./tsconfig.cjs.json", 27 | "bundle": "rollup -c", 28 | "clean": "rimraf lib/* && rimraf coverage/*", 29 | "coverage:upload": "codecov", 30 | "minify:browser": "uglifyjs -c -m -o ./lib/bundle.min.js -- ./lib/bundle.js", 31 | "postbuild": "npm run bundle", 32 | "prebuild": "npm run clean", 33 | "precommit": "lint-staged", 34 | "test": "jest", 35 | "test:watch": "jest --watchAll", 36 | "coverage": "jest --coverage", 37 | "watch": "tsc -w -p .", 38 | "publish:git": "git push && git push --tags", 39 | "publish:npm": "yarn run build && npm publish --access public", 40 | "commit": "cz" 41 | }, 42 | "lint-staged": { 43 | "*.{md,ts,js,json}": [ 44 | "prettier --write es5", 45 | "git add" 46 | ] 47 | }, 48 | "jest": { 49 | "moduleFileExtensions": [ 50 | "js", 51 | "json", 52 | "ts" 53 | ], 54 | "transform": { 55 | "\\.ts$": [ 56 | "ts-jest", 57 | { 58 | "babelConfig": true 59 | } 60 | ] 61 | }, 62 | "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|js)$", 63 | "transformIgnorePatterns": [ 64 | "node_modules/(?!apollo-cache-hermes)" 65 | ], 66 | "preset": "ts-jest" 67 | }, 68 | "peerDependencies": { 69 | "@apollo/client": "^3.7.17" 70 | }, 71 | "devDependencies": { 72 | "@apollo/client": "3.9.9", 73 | "@types/jest": "29.5.12", 74 | "@types/node": "20.11.30", 75 | "@types/react-native": "0.73.0", 76 | "apollo-cache-hermes": "0.8.16", 77 | "browserify": "17.0.0", 78 | "codecov": "3.8.3", 79 | "commitizen": "4.3.0", 80 | "conventional-changelog-cli": "4.1.0", 81 | "cz-conventional-changelog": "3.3.0", 82 | "graphql": "16.8.1", 83 | "husky": "9.0.11", 84 | "jest": "29.7.0", 85 | "lint-staged": "15.2.2", 86 | "prettier": "3.2.5", 87 | "react": "18.2.0", 88 | "rimraf": "5.0.5", 89 | "rollup": "4.13.0", 90 | "ts-jest": "29.1.2", 91 | "typescript": "5.4.3", 92 | "uglify-js": "3.17.4" 93 | }, 94 | "config": { 95 | "commitizen": { 96 | "path": "./node_modules/cz-conventional-changelog" 97 | } 98 | }, 99 | "packageManager": "yarn@4.1.1" 100 | } 101 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | trailingComma: 'all', 4 | }; 5 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | ":pinVersions" 5 | ], 6 | "prCreation": "not-pending", 7 | "pinVersions": true, 8 | "semanticCommits": true, 9 | "labels": ["tooling", "dependencies"], 10 | "packageRules": [ 11 | { 12 | "packageNames": ["graphql"], 13 | "versionStrategy": "widen" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /rollup.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'lib/index.js', 3 | output: { 4 | name: 'apollo-cache-persist', 5 | file: 'lib/bundle.umd.js', 6 | format: 'umd', 7 | sourcemap: true, 8 | exports: 'named', 9 | }, 10 | onwarn, 11 | }; 12 | 13 | function onwarn(message) { 14 | const suppressed = ['UNRESOLVED_IMPORT', 'THIS_IS_UNDEFINED']; 15 | 16 | if (!suppressed.find(code => message.code === code)) { 17 | return console.warn(message.message); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Cache.ts: -------------------------------------------------------------------------------- 1 | import { ApolloCache } from '@apollo/client/core'; 2 | import { ApolloPersistOptions, PersistedData } from './types'; 3 | 4 | export default class Cache { 5 | cache: ApolloCache; 6 | serialize: boolean; 7 | 8 | constructor(options: Pick, 'cache' | 'serialize'>) { 9 | const { cache, serialize = true } = options; 10 | 11 | this.cache = cache; 12 | this.serialize = serialize; 13 | } 14 | 15 | extract(): PersistedData { 16 | let data: PersistedData = this.cache.extract() as T; 17 | 18 | if (this.serialize) { 19 | data = JSON.stringify(data) as string; 20 | } 21 | 22 | return data; 23 | } 24 | 25 | restore(data: PersistedData): void { 26 | if (this.serialize && typeof data === 'string') { 27 | data = JSON.parse(data); 28 | } 29 | 30 | if (data != null) { 31 | this.cache.restore(data as T); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/CachePersistor.ts: -------------------------------------------------------------------------------- 1 | import Log from './Log'; 2 | import Cache from './Cache'; 3 | import Storage from './Storage'; 4 | import Persistor from './Persistor'; 5 | import Trigger from './Trigger'; 6 | 7 | import { ApolloPersistOptions, LogLine } from './types'; 8 | 9 | export default class CachePersistor { 10 | log: Log; 11 | cache: Cache; 12 | storage: Storage; 13 | persistor: Persistor; 14 | trigger: Trigger; 15 | 16 | constructor(options: ApolloPersistOptions) { 17 | if (!options.cache) { 18 | throw new Error( 19 | 'In order to persist your Apollo Cache, you need to pass in a cache. ' + 20 | 'Please see https://www.apollographql.com/docs/react/basics/caching.html for our default InMemoryCache.', 21 | ); 22 | } 23 | 24 | if (!options.storage) { 25 | throw new Error( 26 | 'In order to persist your Apollo Cache, you need to pass in an underlying storage provider. ' + 27 | 'Please see https://github.com/apollographql/apollo-cache-persist#storage-providers', 28 | ); 29 | } 30 | 31 | const log = new Log(options); 32 | const cache = new Cache(options); 33 | const storage = new Storage(options); 34 | const persistor = new Persistor({ log, cache, storage }, options); 35 | const trigger = new Trigger({ log, persistor }, options); 36 | 37 | this.log = log; 38 | this.cache = cache; 39 | // TODO: remove type assertion 40 | this.storage = storage as Storage; 41 | this.persistor = persistor as Persistor; 42 | this.trigger = trigger as Trigger; 43 | } 44 | 45 | /** 46 | * Manual persistence controls. 47 | */ 48 | 49 | persist(): Promise { 50 | return this.persistor.persist(); 51 | } 52 | 53 | restore(): Promise { 54 | return this.persistor.restore(); 55 | } 56 | 57 | purge(): Promise { 58 | return this.persistor.purge(); 59 | } 60 | 61 | /** 62 | * Trigger controls. 63 | */ 64 | 65 | pause(): void { 66 | this.trigger.pause(); 67 | } 68 | 69 | resume(): void { 70 | this.trigger.resume(); 71 | } 72 | 73 | remove(): void { 74 | this.trigger.remove(); 75 | } 76 | 77 | /** 78 | * Info accessor. 79 | */ 80 | 81 | getLogs(print = false): Array | void { 82 | if (print) { 83 | this.log.tailLogs(); 84 | } else { 85 | return this.log.getLogs(); 86 | } 87 | } 88 | 89 | getSize(): Promise { 90 | return this.storage.getSize(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Log.ts: -------------------------------------------------------------------------------- 1 | import { ApolloPersistOptions, LogLevel, LogLine } from './types'; 2 | 3 | export default class Log { 4 | debug: boolean; 5 | lines: Array; 6 | 7 | static buffer = 30; 8 | static prefix = '[apollo-cache-persist]'; 9 | 10 | constructor(options: Pick, 'debug'>) { 11 | const { debug = false } = options; 12 | 13 | this.debug = debug; 14 | this.lines = []; 15 | } 16 | 17 | emit(level: LogLevel, message: any[]): void { 18 | if (level in console) { 19 | const { prefix } = Log; 20 | console[level](prefix, ...message); 21 | } 22 | } 23 | 24 | tailLogs(): void { 25 | this.lines.forEach(([level, message]) => this.emit(level, message)); 26 | } 27 | 28 | getLogs(): Array { 29 | return this.lines; 30 | } 31 | 32 | write(level: LogLevel, message: any[]): void { 33 | const { buffer } = Log; 34 | 35 | this.lines = [...this.lines.slice(1 - buffer), [level, message]]; 36 | 37 | if (this.debug || level !== 'log') { 38 | this.emit(level, message); 39 | } 40 | } 41 | 42 | info(...message: any[]): void { 43 | this.write('log', message); 44 | } 45 | 46 | warn(...message: any[]): void { 47 | this.write('warn', message); 48 | } 49 | 50 | error(...message: any[]): void { 51 | this.write('error', message); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Persistor.ts: -------------------------------------------------------------------------------- 1 | import Log from './Log'; 2 | import Storage from './Storage'; 3 | import Cache from './Cache'; 4 | 5 | import { ApolloPersistOptions, PersistenceMapperFunction } from './types'; 6 | 7 | export interface PersistorConfig { 8 | log: Log; 9 | cache: Cache; 10 | storage: Storage; 11 | } 12 | 13 | export default class Persistor { 14 | log: Log; 15 | cache: Cache; 16 | storage: Storage; 17 | maxSize?: number; 18 | paused: boolean; 19 | persistenceMapper?: PersistenceMapperFunction; 20 | 21 | constructor( 22 | { log, cache, storage }: PersistorConfig, 23 | options: Pick, 'maxSize' | 'persistenceMapper'>, 24 | ) { 25 | const { maxSize = 1024 * 1024, persistenceMapper } = options; 26 | 27 | this.log = log; 28 | this.cache = cache; 29 | this.storage = storage; 30 | this.paused = false; 31 | 32 | if (persistenceMapper) { 33 | this.persistenceMapper = persistenceMapper; 34 | } 35 | 36 | if (maxSize) { 37 | this.maxSize = maxSize; 38 | } 39 | } 40 | 41 | async persist(): Promise { 42 | try { 43 | let data = this.cache.extract(); 44 | 45 | if (!this.paused && this.persistenceMapper) { 46 | data = await this.persistenceMapper(data); 47 | } 48 | 49 | if ( 50 | this.maxSize != null && 51 | typeof data === 'string' && 52 | data.length > this.maxSize && 53 | !this.paused 54 | ) { 55 | await this.purge(); 56 | this.paused = true; 57 | return; 58 | } 59 | 60 | if (this.paused) { 61 | return; 62 | } 63 | 64 | await this.storage.write(data); 65 | 66 | this.log.info( 67 | typeof data === 'string' 68 | ? `Persisted cache of size ${data.length} characters` 69 | : 'Persisted cache', 70 | ); 71 | } catch (error) { 72 | this.log.error('Error persisting cache', error); 73 | throw error; 74 | } 75 | } 76 | 77 | async restore(): Promise { 78 | try { 79 | const data = await this.storage.read(); 80 | 81 | if (data != null) { 82 | await this.cache.restore(data); 83 | 84 | this.log.info( 85 | typeof data === 'string' 86 | ? `Restored cache of size ${data.length} characters` 87 | : 'Restored cache', 88 | ); 89 | } else { 90 | this.log.info('No stored cache to restore'); 91 | } 92 | } catch (error) { 93 | this.log.error('Error restoring cache', error); 94 | throw error; 95 | } 96 | } 97 | 98 | async purge(): Promise { 99 | try { 100 | await this.storage.purge(); 101 | this.log.info('Purged cache storage'); 102 | } catch (error) { 103 | this.log.error('Error purging cache storage', error); 104 | throw error; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/Storage.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApolloPersistOptions, 3 | PersistentStorage, 4 | PersistedData, 5 | } from './types'; 6 | 7 | export default class Storage { 8 | storage: PersistentStorage>; 9 | key: string; 10 | 11 | constructor(options: Pick, 'storage' | 'key'>) { 12 | const { storage, key = 'apollo-cache-persist' } = options; 13 | 14 | this.storage = storage; 15 | this.key = key; 16 | } 17 | 18 | async read(): Promise> { 19 | return this.storage.getItem(this.key); 20 | } 21 | 22 | async write(data: PersistedData): Promise { 23 | await this.storage.setItem(this.key, data); 24 | } 25 | 26 | async purge(): Promise { 27 | await this.storage.removeItem(this.key); 28 | } 29 | 30 | async getSize(): Promise { 31 | const data = await this.storage.getItem(this.key); 32 | 33 | if (data == null) { 34 | return 0; 35 | } else { 36 | return typeof data === 'string' ? data.length : null; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Trigger.ts: -------------------------------------------------------------------------------- 1 | import onCacheWrite from './onCacheWrite'; 2 | import onAppBackground from './onAppBackground'; 3 | 4 | import Log from './Log'; 5 | import Persistor from './Persistor'; 6 | import { ApolloPersistOptions, TriggerUninstallFunction } from './types'; 7 | 8 | export interface TriggerConfig { 9 | log: Log; 10 | persistor: Persistor; 11 | } 12 | 13 | export default class Trigger { 14 | debounce: number; 15 | persistor: Persistor; 16 | paused: boolean; 17 | timeout: any; 18 | uninstall: TriggerUninstallFunction; 19 | 20 | static defaultDebounce = 1000; 21 | 22 | constructor( 23 | { log, persistor }: TriggerConfig, 24 | options: Pick, 'cache' | 'debounce' | 'trigger'>, 25 | ) { 26 | const { defaultDebounce } = Trigger; 27 | const { cache, debounce, trigger = 'write' } = options; 28 | 29 | if (!trigger) { 30 | return; 31 | } 32 | 33 | this.debounce = debounce != null ? debounce : defaultDebounce; 34 | this.persistor = persistor; 35 | this.paused = false; 36 | 37 | switch (trigger) { 38 | case 'write': 39 | this.uninstall = onCacheWrite({ cache })(this.fire); 40 | break; 41 | 42 | case 'background': 43 | if (debounce) { 44 | log.warn('Debounce is not recommended with `background` trigger'); 45 | } 46 | this.debounce = debounce; 47 | this.uninstall = onAppBackground({ cache, log })(this.fire); 48 | break; 49 | 50 | default: 51 | if (typeof trigger === 'function') { 52 | this.uninstall = trigger(this.fire); 53 | } else { 54 | throw Error(`Unrecognized trigger option: ${trigger}`); 55 | } 56 | } 57 | } 58 | 59 | pause(): void { 60 | this.paused = true; 61 | } 62 | 63 | resume(): void { 64 | this.paused = false; 65 | } 66 | 67 | remove(): void { 68 | if (this.uninstall) { 69 | this.uninstall(); 70 | this.uninstall = null; 71 | this.paused = true; 72 | } 73 | } 74 | 75 | fire = () => { 76 | if (!this.debounce) { 77 | this.persist(); 78 | return; 79 | } 80 | 81 | if (this.timeout != null) { 82 | clearTimeout(this.timeout); 83 | } 84 | 85 | this.timeout = setTimeout(this.persist, this.debounce); 86 | }; 87 | 88 | persist = () => { 89 | if (this.paused) { 90 | return; 91 | } 92 | 93 | this.persistor.persist(); 94 | }; 95 | } 96 | -------------------------------------------------------------------------------- /src/__mocks__/MockCache.ts: -------------------------------------------------------------------------------- 1 | import Cache from '../Cache'; 2 | import { ApolloPersistOptions, PersistedData } from '../types'; 3 | 4 | export default class MockCache 5 | implements Cache 6 | { 7 | cache: null; 8 | serialize: boolean; 9 | data: PersistedData; 10 | 11 | constructor(options: Pick, 'serialize'>) { 12 | const { serialize = true } = options; 13 | this.serialize = serialize; 14 | } 15 | 16 | extract(): PersistedData { 17 | let data: PersistedData = this.data; 18 | 19 | if (this.serialize) { 20 | data = JSON.stringify(this.data) as string; 21 | } 22 | 23 | return data; 24 | } 25 | 26 | restore(data: PersistedData): void { 27 | if (this.serialize && typeof data === 'string') { 28 | data = JSON.parse(data); 29 | } 30 | 31 | if (data != null) { 32 | this.data = data; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/__mocks__/MockStorage.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | export default class MockStorage implements PersistentStorage { 4 | storage: Map; 5 | 6 | constructor() { 7 | this.storage = new Map(); 8 | } 9 | 10 | setItem(key: string, data: string): Promise { 11 | return new Promise(resolve => { 12 | this.storage.set(key, data); 13 | resolve(); 14 | }); 15 | } 16 | 17 | removeItem(key: string): Promise { 18 | return new Promise((resolve, reject) => { 19 | this.storage.delete(key); 20 | resolve(); 21 | }); 22 | } 23 | 24 | getItem(key: string): Promise { 25 | return new Promise((resolve, reject) => { 26 | resolve(this.storage.get(key)); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/__mocks__/MockStorageSync.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | export default class MockStorageSync implements PersistentStorage { 4 | storage: Map; 5 | 6 | constructor() { 7 | this.storage = new Map(); 8 | } 9 | 10 | setItem(key: string, data: string): void { 11 | this.storage.set(key, data); 12 | } 13 | 14 | removeItem(key: string): void { 15 | this.storage.delete(key); 16 | } 17 | 18 | getItem(key: string): any { 19 | return this.storage.get(key); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/__mocks__/simulate.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApolloClient, 3 | ApolloLink, 4 | DocumentNode, 5 | InMemoryCache, 6 | Observable, 7 | } from '@apollo/client/core'; 8 | 9 | import { persistCache } from '../'; 10 | import MockStorage from './MockStorage'; 11 | import { ApolloPersistOptions } from '../types'; 12 | 13 | export const simulateApp = async ({ 14 | result, 15 | operation, 16 | persistOptions = {}, 17 | }: { 18 | result: T; 19 | operation: DocumentNode; 20 | persistOptions?: Partial>; 21 | }) => { 22 | const storage = persistOptions.storage || new MockStorage(); 23 | const cache = persistOptions.cache || new InMemoryCache(); 24 | 25 | await persistCache({ ...persistOptions, cache, storage }); 26 | 27 | const link = new ApolloLink(() => Observable.of(result)); 28 | const client = new ApolloClient({ cache, link }); 29 | 30 | await client.query({ query: operation }); 31 | jest.advanceTimersByTime( 32 | persistOptions.debounce ? persistOptions.debounce + 1 : 1001, 33 | ); 34 | 35 | // cache is now persisted 36 | const cache2 = cache.constructor(); 37 | await persistCache({ ...persistOptions, cache: cache2, storage }); 38 | const client2 = new ApolloClient({ cache: cache2, link }); 39 | 40 | return [client, client2]; 41 | }; 42 | 43 | export const simulateWrite = async ({ 44 | result, 45 | operation, 46 | persistOptions = {}, 47 | }: { 48 | result: T; 49 | operation: DocumentNode; 50 | persistOptions?: Partial>; 51 | }) => { 52 | const storage = persistOptions.storage || new MockStorage(); 53 | const cache = persistOptions.cache || new InMemoryCache(); 54 | 55 | await persistCache({ ...persistOptions, cache, storage }); 56 | 57 | const link = new ApolloLink(() => Observable.of(result)); 58 | const client = new ApolloClient({ cache, link }); 59 | await client.query({ query: operation }); 60 | }; 61 | -------------------------------------------------------------------------------- /src/__tests__/Persistor.ts: -------------------------------------------------------------------------------- 1 | import MockStorage from '../__mocks__/MockStorage'; 2 | import MockCache from '../__mocks__/MockCache'; 3 | import Persistor from '../Persistor'; 4 | import Storage from '../Storage'; 5 | import Log from '../Log'; 6 | 7 | describe('Persistor', () => { 8 | const cache = new MockCache({ serialize: false }); 9 | const storage = new Storage({ storage: new MockStorage() }); 10 | jest.spyOn(storage, 'write'); 11 | const persistor = new Persistor( 12 | { 13 | log: new Log({ debug: false }), 14 | storage, 15 | cache, 16 | }, 17 | { maxSize: 100 }, 18 | ); 19 | 20 | it('should not write more than maxSize', async () => { 21 | cache.restore('0'.repeat(101)); 22 | await persistor.persist(); 23 | expect(storage.write).not.toHaveBeenCalled(); 24 | }); 25 | 26 | it('should not commit writes after pause', async () => { 27 | cache.restore('0'.repeat(101)); 28 | persistor.persist(); 29 | expect(storage.write).not.toHaveBeenCalled(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /src/__tests__/Storage.ts: -------------------------------------------------------------------------------- 1 | import MockStorage from '../__mocks__/MockStorage'; 2 | import Storage from '../Storage'; 3 | 4 | describe('Storage', () => { 5 | const storage = new Storage({ 6 | storage: new MockStorage(), 7 | }); 8 | 9 | it('writes, reads, & deletes data from persistent storage', async () => { 10 | await expect(storage.write('yo yo yo')).resolves.toBe(undefined); 11 | await expect(storage.read()).resolves.toBe('yo yo yo'); 12 | await storage.purge(); 13 | await expect(storage.read()).resolves.toBe(undefined); 14 | }); 15 | 16 | describe('when data is an object', () => { 17 | it('writes an object to persistent storage', async () => { 18 | const obj = { 19 | yo: 'yo yo', 20 | }; 21 | 22 | await expect(storage.write(obj)).resolves.toBe(undefined); 23 | await expect(storage.read()).resolves.toBe(obj); 24 | }); 25 | }); 26 | 27 | describe('when data is a string', () => { 28 | it('writes a string to persistent storage', async () => { 29 | await expect(storage.write('yo yo yo')).resolves.toBe(undefined); 30 | await expect(storage.read()).resolves.toBe('yo yo yo'); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /src/__tests__/__snapshots__/persistCache.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`persistCache advanced usage passing a persistence mapper properly maps the persisted cache 1`] = `"{"User:1":{"__typename":"User","id":1,"first":"Jane","last":"Doe"},"ROOT_QUERY":{"__typename":"Query","user({\\"id\\":1})":{"__ref":"User:1"}}}"`; 4 | 5 | exports[`persistCache advanced usage passing in debounce configures the debounce interval 1`] = `"{"ROOT_QUERY":{"__typename":"Query","hello":"world"}}"`; 6 | 7 | exports[`persistCache advanced usage passing in key customizes the storage key 1`] = `"{"ROOT_QUERY":{"__typename":"Query","hello":"world"}}"`; 8 | 9 | exports[`persistCache advanced usage setting maxSize purges the Apollo cache & storage if it crosses a threshold 1`] = `undefined`; 10 | 11 | exports[`persistCache setup requires a cache 1`] = `"In order to persist your Apollo Cache, you need to pass in a cache. Please see https://www.apollographql.com/docs/react/basics/caching.html for our default InMemoryCache."`; 12 | 13 | exports[`persistCache setup requires storage 1`] = `"In order to persist your Apollo Cache, you need to pass in an underlying storage provider. Please see https://github.com/apollographql/apollo-cache-persist#storage-providers"`; 14 | -------------------------------------------------------------------------------- /src/__tests__/persistCache.ts: -------------------------------------------------------------------------------- 1 | import { InMemoryCache, gql } from '@apollo/client/core'; 2 | import { Hermes } from 'apollo-cache-hermes'; 3 | 4 | import { persistCache } from '../'; 5 | import MockStorage from '../__mocks__/MockStorage'; 6 | import { simulateApp, simulateWrite } from '../__mocks__/simulate'; 7 | 8 | jest.useFakeTimers(); 9 | describe('persistCache', () => { 10 | describe('setup', () => { 11 | it('requires a cache', async () => { 12 | try { 13 | // @ts-expect-error cache is required 14 | await persistCache({ storage: new MockStorage() }); 15 | fail('invoking persistCache without a cache should throw an error'); 16 | } catch (e) { 17 | expect(() => { 18 | throw e; 19 | }).toThrowErrorMatchingSnapshot(); 20 | } 21 | }); 22 | it('requires storage', async () => { 23 | try { 24 | // @ts-expect-error storage is required 25 | await persistCache({ cache: new InMemoryCache() }); 26 | fail('invoking persistCache without storage should throw an error'); 27 | } catch (e) { 28 | expect(() => { 29 | throw e; 30 | }).toThrowErrorMatchingSnapshot(); 31 | } 32 | }); 33 | }); 34 | 35 | describe('basic usage', () => { 36 | const operation = gql` 37 | { 38 | hello 39 | } 40 | `; 41 | const result = { data: { hello: 'world' } }; 42 | 43 | it('extracts a previously filled InMemoryCache from storage', async () => { 44 | const [client, client2] = await simulateApp({ 45 | operation, 46 | result, 47 | }); 48 | expect(client.extract()).toEqual(client2.extract()); 49 | }); 50 | xit('extracts a previously filled HermesCache from storage', async () => { 51 | const [client, client2] = await simulateApp({ 52 | operation, 53 | result, 54 | persistOptions: { 55 | cache: new Hermes(), 56 | }, 57 | }); 58 | expect(client.extract()).toEqual(client2.extract()); 59 | }); 60 | }); 61 | 62 | describe('nested queries', () => { 63 | const operation = gql` 64 | { 65 | user(id: 1) { 66 | name { 67 | last 68 | first 69 | } 70 | posts { 71 | title 72 | comments { 73 | name 74 | } 75 | } 76 | } 77 | } 78 | `; 79 | const result = { 80 | data: { 81 | user: { 82 | name: { last: 'Doe', first: 'Jane', __typename: 'Name' }, 83 | posts: [ 84 | { 85 | title: 'Apollo is awesome', 86 | comments: [{ name: 'foo', __typename: 'Comment' }], 87 | __typename: 'Post', 88 | }, 89 | ], 90 | __typename: 'User', 91 | }, 92 | }, 93 | }; 94 | 95 | it('extracts a previously filled InMemoryCache from storage', async () => { 96 | const [client, client2] = await simulateApp({ 97 | operation, 98 | result, 99 | }); 100 | expect(client.extract()).toEqual(client2.extract()); 101 | }); 102 | xit('extracts a previously filled HermesCache from storage', async () => { 103 | const [client, client2] = await simulateApp({ 104 | operation, 105 | result, 106 | persistOptions: { 107 | cache: new Hermes(), 108 | }, 109 | }); 110 | expect(client.extract()).toEqual(client2.extract()); 111 | }); 112 | }); 113 | 114 | describe('advanced usage', () => { 115 | const operation = gql` 116 | { 117 | hello 118 | } 119 | `; 120 | const result = { data: { hello: 'world' } }; 121 | 122 | it('passing in debounce configures the debounce interval', async () => { 123 | const debounce = 600; 124 | const storage = new MockStorage(); 125 | 126 | await simulateWrite({ 127 | result, 128 | operation, 129 | persistOptions: { debounce, storage }, 130 | }); 131 | 132 | expect(await storage.getItem('apollo-cache-persist')).toBe(undefined); 133 | jest.advanceTimersByTime(debounce + 1); 134 | expect(await storage.getItem('apollo-cache-persist')).toMatchSnapshot(); 135 | }); 136 | it('passing in key customizes the storage key', async () => { 137 | const storage = new MockStorage(); 138 | const key = 'testing-1-2-3'; 139 | 140 | await simulateWrite({ 141 | result, 142 | operation, 143 | persistOptions: { key, storage }, 144 | }); 145 | 146 | jest.advanceTimersByTime(1001); 147 | expect(await storage.getItem('apollo-cache-persist')).toBe(undefined); 148 | expect(await storage.getItem(key)).toMatchSnapshot(); 149 | }); 150 | it('setting maxSize purges the Apollo cache & storage if it crosses a threshold', async () => { 151 | const storage = new MockStorage(); 152 | 153 | await simulateWrite({ 154 | result, 155 | operation, 156 | persistOptions: { storage, maxSize: 20 }, 157 | }); 158 | 159 | jest.advanceTimersByTime(1001); 160 | expect(await storage.getItem('apollo-cache-persist')).toMatchSnapshot(); 161 | }); 162 | xit('setting the trigger to background does not persist on a write', async () => { 163 | const storage = new MockStorage(); 164 | await simulateWrite({ 165 | result, 166 | operation, 167 | persistOptions: { trigger: 'background', storage }, 168 | }); 169 | 170 | jest.advanceTimersByTime(1001); 171 | expect(await storage.getItem('apollo-cache-persist')).toBe(undefined); 172 | }); 173 | xit('setting the trigger to background persists in the background', () => {}); 174 | it('passing a persistence mapper properly maps the persisted cache', async () => { 175 | const storage = new MockStorage(); 176 | 177 | const persistenceMapper = async (data: any) => { 178 | const parsed = JSON.parse(data); 179 | delete parsed['Post:1']; 180 | delete parsed['ROOT_QUERY']['posts']; 181 | return JSON.stringify(parsed); 182 | }; 183 | 184 | const mappableOperation = gql` 185 | { 186 | user(id: 1) { 187 | id 188 | first 189 | last 190 | } 191 | posts { 192 | id 193 | title 194 | } 195 | } 196 | `; 197 | 198 | const mappableResult = { data: { 199 | user: { 200 | id: 1, 201 | first: 'Jane', 202 | last: 'Doe', 203 | __typename: 'User', 204 | }, 205 | posts: [ 206 | { 207 | id: 1, 208 | title: 'Apollo is awesome', 209 | __typename: 'Post', 210 | }, 211 | ], 212 | }}; 213 | 214 | await simulateWrite({ 215 | result: mappableResult, 216 | operation: mappableOperation, 217 | persistOptions: { storage, persistenceMapper }, 218 | }); 219 | 220 | jest.advanceTimersByTime(1001); 221 | // without this line, this test won't pass. 222 | // see https://github.com/facebook/jest/issues/2157 223 | await Promise.resolve(); 224 | const received = await storage.getItem('apollo-cache-persist'); 225 | expect(received).toMatchSnapshot(); 226 | }); 227 | }); 228 | }); 229 | -------------------------------------------------------------------------------- /src/__tests__/persistCacheSync.ts: -------------------------------------------------------------------------------- 1 | import { SynchronousCachePersistor } from '../'; 2 | import MockStorageSync from '../__mocks__/MockStorageSync'; 3 | import { 4 | ApolloClient, 5 | Observable, 6 | ApolloLink, 7 | InMemoryCache, 8 | NormalizedCacheObject, 9 | } from '@apollo/client/core'; 10 | import gql from 'graphql-tag'; 11 | import { ApolloPersistOptions } from '../types'; 12 | 13 | jest.useFakeTimers(); 14 | describe('persistCacheSync', () => { 15 | describe('setup', () => { 16 | it('persists cache', async () => { 17 | const operation = gql` 18 | { 19 | hello 20 | } 21 | `; 22 | const result = { data: { hello: 'world' } }; 23 | const storage = new MockStorageSync(); 24 | const cache = new InMemoryCache(); 25 | 26 | const persistOptions: ApolloPersistOptions = { 27 | cache, 28 | storage, 29 | }; 30 | // @ts-ignore 31 | const cachePersistor = new SynchronousCachePersistor(persistOptions); 32 | 33 | const link = new ApolloLink(() => Observable.of(result)); 34 | const client = new ApolloClient({ cache, link }); 35 | expect(cache.extract()).toEqual({}); 36 | 37 | await client.query({ query: operation }); 38 | jest.advanceTimersByTime( 39 | persistOptions.debounce ? persistOptions.debounce + 1 : 1001, 40 | ); 41 | 42 | const cache2 = new InMemoryCache(); 43 | const cachePersistor2 = new SynchronousCachePersistor({ 44 | cache: cache2, 45 | storage, 46 | }); 47 | cachePersistor2.restoreSync(); 48 | const keys = Object.keys(cache2.extract()); 49 | expect(keys.length).toEqual(1); 50 | }); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as CachePersistor } from './CachePersistor'; 2 | export { default as persistCache } from './persistCache'; 3 | export * from './persistCacheSync'; 4 | export * from './storageWrappers/index'; 5 | export { PersistentStorage } from './types'; 6 | -------------------------------------------------------------------------------- /src/onAppBackground.native.ts: -------------------------------------------------------------------------------- 1 | import { AppState } from 'react-native'; 2 | 3 | export default () => (persist: () => void) => { 4 | let wasActive = true; 5 | 6 | const listener = (state: string) => { 7 | if (state === 'active') { 8 | wasActive = true; 9 | } else if (wasActive) { 10 | wasActive = false; 11 | persist(); 12 | } 13 | }; 14 | 15 | const subscription = AppState.addEventListener('change', listener); 16 | return () => subscription.remove(); 17 | }; 18 | -------------------------------------------------------------------------------- /src/onAppBackground.ts: -------------------------------------------------------------------------------- 1 | import { ApolloCache } from '@apollo/client/core'; 2 | 3 | import Log from './Log'; 4 | import onCacheWrite from './onCacheWrite'; 5 | 6 | export interface TriggerFunctionConfig { 7 | log: Log; 8 | cache: ApolloCache; 9 | } 10 | 11 | export default ({ log, cache }: TriggerFunctionConfig) => ( 12 | persist: () => void, 13 | ) => { 14 | log.warn( 15 | 'Trigger option `background` not available on web; using `write` trigger', 16 | ); 17 | return onCacheWrite({ cache })(persist); 18 | }; 19 | -------------------------------------------------------------------------------- /src/onCacheWrite.ts: -------------------------------------------------------------------------------- 1 | import { ApolloCache } from '@apollo/client/core'; 2 | 3 | export interface TriggerFunctionConfig { 4 | cache: ApolloCache; 5 | } 6 | 7 | export default ({ cache }: TriggerFunctionConfig) => ( 8 | persist: () => void, 9 | ) => { 10 | const write = cache.write; 11 | const evict = cache.evict; 12 | const modify = cache.modify; 13 | const gc = cache.gc; 14 | 15 | cache.write = (...args: any[]) => { 16 | const result = write.apply(cache, args); 17 | persist(); 18 | return result; 19 | }; 20 | cache.evict = (...args: any[]) => { 21 | const result = evict.apply(cache, args); 22 | persist(); 23 | return result; 24 | }; 25 | cache.modify = (...args: any[]) => { 26 | const result = modify.apply(cache, args); 27 | persist(); 28 | return result; 29 | }; 30 | cache.gc = (...args: any[]) => { 31 | const result = gc.apply(cache, args); 32 | persist(); 33 | return result; 34 | }; 35 | 36 | 37 | return () => { 38 | cache.write = write; 39 | cache.evict = evict; 40 | cache.modify = modify; 41 | cache.gc = gc; 42 | }; 43 | }; 44 | -------------------------------------------------------------------------------- /src/persistCache.ts: -------------------------------------------------------------------------------- 1 | import CachePersistor from './CachePersistor'; 2 | import { ApolloPersistOptions } from './types'; 3 | 4 | export default (options: ApolloPersistOptions) => { 5 | const persistor = new CachePersistor(options); 6 | return persistor.restore(); 7 | }; 8 | -------------------------------------------------------------------------------- /src/persistCacheSync.ts: -------------------------------------------------------------------------------- 1 | import { ApolloPersistOptions } from './types'; 2 | import CachePersistor from './CachePersistor'; 3 | import Persistor, { PersistorConfig } from './Persistor'; 4 | import Storage from './Storage'; 5 | 6 | /** 7 | * Add cache to persist engine using synchronous API 8 | * 9 | * @see SynchronousCachePersistor for advanced use cases 10 | * @param options options for persist engine 11 | */ 12 | export const persistCacheSync = (options: ApolloPersistOptions) => { 13 | const cachePersistor = new SynchronousCachePersistor(options); 14 | cachePersistor.restoreSync(); 15 | }; 16 | 17 | /** 18 | * Persistor engine that is going to use synchronous api 19 | */ 20 | export class SynchronousCachePersistor extends CachePersistor { 21 | persistor: SynchronousPersistor; 22 | 23 | constructor(options: ApolloPersistOptions) { 24 | super(options); 25 | 26 | this.storage = new SynchronousStorage(options); 27 | this.persistor = new SynchronousPersistor( 28 | { log: this.log, cache: this.cache, storage: this.storage }, 29 | options, 30 | ); 31 | } 32 | 33 | restoreSync() { 34 | this.persistor.restoreSync(); 35 | } 36 | } 37 | 38 | export class SynchronousPersistor extends Persistor { 39 | storage: SynchronousStorage; 40 | 41 | constructor( 42 | { log, cache, storage }: PersistorConfig, 43 | options: ApolloPersistOptions, 44 | ) { 45 | super({ log, cache, storage }, options); 46 | } 47 | 48 | restoreSync() { 49 | this.cache.restore(this.storage.readSync()); 50 | } 51 | } 52 | 53 | export class SynchronousStorage extends Storage { 54 | constructor(options: ApolloPersistOptions) { 55 | super(options); 56 | } 57 | 58 | readSync(): any { 59 | return this.storage.getItem(this.key); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/storageWrappers/AsyncStorageWrapper.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | /** 4 | * Wrapper for react-native's AsyncStorage. 5 | * 6 | * WARNING: AsyncStorage doesn't support values in excess of 2MB on Android. 7 | * 8 | * @example 9 | * const persistor = new CachePersistor({ 10 | * cache, 11 | * storage: new AsyncStorageWrapper(AsyncStorage), 12 | * }); 13 | * 14 | */ 15 | export class AsyncStorageWrapper implements PersistentStorage { 16 | protected storage; 17 | 18 | constructor(storage: AsyncStorageInterface) { 19 | this.storage = storage; 20 | } 21 | 22 | getItem(key: string): Promise { 23 | return this.storage.getItem(key); 24 | } 25 | 26 | removeItem(key: string): Promise { 27 | return this.storage.removeItem(key); 28 | } 29 | 30 | setItem(key: string, value: string | null): Promise { 31 | return this.storage.setItem(key, value); 32 | } 33 | } 34 | 35 | interface AsyncStorageInterface { 36 | // Actual type definition: https://github.com/react-native-async-storage/async-storage/blob/master/types/index.d.ts 37 | getItem(key: string): Promise; 38 | setItem(key: string, value: string | null): Promise; 39 | removeItem(key: string): Promise; 40 | } 41 | -------------------------------------------------------------------------------- /src/storageWrappers/IonicStorageWrapper.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | export class IonicStorageWrapper implements PersistentStorage { 4 | protected storage; 5 | 6 | constructor(storage: IonicStorageInterface) { 7 | this.storage = storage; 8 | } 9 | 10 | getItem(key: string): Promise { 11 | return this.storage.get(key); 12 | } 13 | 14 | removeItem(key: string): Promise { 15 | return this.storage.remove(key); 16 | } 17 | 18 | setItem(key: string, value: string | null): Promise { 19 | return this.storage.set(key, value); 20 | } 21 | } 22 | 23 | interface IonicStorageInterface { 24 | // Actual type definition: https://github.com/ionic-team/ionic-storage/blob/main/lib/src/index.ts 25 | get(key: string): Promise; 26 | set(key: string, value: string | null): Promise; 27 | remove(key: string): Promise; 28 | } 29 | -------------------------------------------------------------------------------- /src/storageWrappers/LocalForageWrapper.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | export class LocalForageWrapper 4 | implements PersistentStorage { 5 | protected storage; 6 | 7 | constructor(storage: LocalForageInterface) { 8 | this.storage = storage; 9 | } 10 | 11 | getItem(key: string): Promise { 12 | return this.storage.getItem(key); 13 | } 14 | 15 | removeItem(key: string): Promise { 16 | return this.storage.removeItem(key); 17 | } 18 | 19 | setItem(key: string, value: string | object | null): Promise { 20 | return new Promise((resolve, reject) => { 21 | this.storage 22 | .setItem(key, value) 23 | .then(() => resolve()) 24 | .catch(() => reject()); 25 | }); 26 | } 27 | } 28 | 29 | interface LocalForageInterface { 30 | // Actual type definition: https://github.com/localForage/localForage/blob/master/typings/localforage.d.ts#L17 31 | getItem(key: string): Promise; 32 | setItem( 33 | key: string, 34 | value: string | object | null, 35 | ): Promise; 36 | removeItem(key: string): Promise; 37 | } 38 | -------------------------------------------------------------------------------- /src/storageWrappers/LocalStorageWrapper.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | export class LocalStorageWrapper implements PersistentStorage { 4 | protected storage; 5 | 6 | constructor(storage: LocalStorageInterface) { 7 | this.storage = storage; 8 | } 9 | 10 | getItem(key: string): string | null { 11 | return this.storage.getItem(key); 12 | } 13 | 14 | removeItem(key: string): void { 15 | return this.storage.removeItem(key); 16 | } 17 | 18 | setItem(key: string, value: string | null): void { 19 | if (value !== null) { 20 | // setting null to localstorage stores "null" as string 21 | return this.storage.setItem(key, value); 22 | } else { 23 | return this.removeItem(key); 24 | } 25 | } 26 | } 27 | 28 | interface LocalStorageInterface { 29 | // Actual type definition: https://github.com/microsoft/TypeScript/blob/main/lib/lib.dom.d.ts#L14276 30 | getItem(key: string): string | null; 31 | setItem(key: string, value: string): void; 32 | removeItem(key: string): void; 33 | } 34 | -------------------------------------------------------------------------------- /src/storageWrappers/MMKVStorageWrapper.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | /** 4 | * Wrapper for react-native-mmkv-storage. 5 | * See [https://rnmmkv.now.sh/#/gettingstarted](https://rnmmkv.now.sh/#/gettingstarted) for installation instructions. 6 | * 7 | * @example 8 | * const persistor = new CachePersistor({ 9 | * cache, 10 | * storage: new MMKVStorageWrapper(new MMKVStorage.Loader().initialize()), 11 | * }); 12 | * 13 | */ 14 | export class MMKVStorageWrapper implements PersistentStorage { 15 | protected storage; 16 | 17 | constructor(storage: MMKVStorageInterface) { 18 | this.storage = storage; 19 | } 20 | 21 | getItem(key: string): Promise { 22 | return this.storage.getItem(key) || null; 23 | } 24 | 25 | removeItem(key: string): Promise { 26 | return new Promise((resolve, reject) => { 27 | // Ensure the removeItem is thenable, even if it's not, by wrapping it to Promise.resolve 28 | // The MMKV storage's removeItem is synchronous since 0.5.7, this Promise wrap allows backward compatibility 29 | // https://stackoverflow.com/a/27746324/2078771 30 | Promise.resolve(this.storage.removeItem(key)) 31 | .then(() => resolve()) 32 | .catch(() => reject()); 33 | }); 34 | } 35 | 36 | setItem(key: string, value: string | null): Promise { 37 | return new Promise((resolve, reject) => { 38 | this.storage 39 | .setItem(key, value) 40 | .then(() => resolve()) 41 | .catch(() => reject()); 42 | }); 43 | } 44 | } 45 | 46 | interface MMKVStorageInterface { 47 | // Actual type definition: https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/index.d.ts#L27 48 | getItem(key: string): Promise; 49 | setItem(key: string, value: string): Promise; 50 | removeItem(key: string): boolean | undefined | Promise; 51 | } 52 | -------------------------------------------------------------------------------- /src/storageWrappers/MMKVWrapper.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | /** 4 | * Wrapper for react-native-mmkv. 5 | * See [https://github.com/mrousavy/react-native-mmkv](https://github.com/mrousavy/react-native-mmkv) for installation instructions. 6 | * 7 | * @example 8 | * const storage = new MMKV(); 9 | * const persistor = new CachePersistor({ 10 | * cache, 11 | * storage: new MMKVWrapper(storage), 12 | * }); 13 | * 14 | */ 15 | export class MMKVWrapper implements PersistentStorage { 16 | protected storage; 17 | 18 | constructor(storage: MMKVInterface) { 19 | this.storage = storage; 20 | } 21 | 22 | getItem(key: string): string | null { 23 | return this.storage.getString(key) || null; 24 | } 25 | 26 | removeItem(key: string): void { 27 | return this.storage.delete(key); 28 | } 29 | 30 | setItem(key: string, value: string | null): void { 31 | if (value !== null) { 32 | return this.storage.set(key, value); 33 | } 34 | return this.removeItem(key); 35 | } 36 | } 37 | 38 | interface MMKVInterface { 39 | set: (key: string, value: boolean | string | number) => void; 40 | getString: (key: string) => string | undefined; 41 | delete: (key: string) => void; 42 | } 43 | -------------------------------------------------------------------------------- /src/storageWrappers/SessionStorageWrapper.ts: -------------------------------------------------------------------------------- 1 | import { PersistentStorage } from '../types'; 2 | 3 | export class SessionStorageWrapper implements PersistentStorage { 4 | protected storage; 5 | 6 | constructor(storage: SessionStorageInterface) { 7 | this.storage = storage; 8 | } 9 | 10 | getItem(key: string): string | null { 11 | return this.storage.getItem(key); 12 | } 13 | 14 | removeItem(key: string): void { 15 | return this.storage.removeItem(key); 16 | } 17 | 18 | setItem(key: string, value: string | null): void { 19 | if (value !== null) { 20 | // setting null to sessionstorage stores "null" as string 21 | return this.storage.setItem(key, value); 22 | } else { 23 | return this.removeItem(key); 24 | } 25 | } 26 | } 27 | 28 | interface SessionStorageInterface { 29 | // Actual type definition: https://github.com/microsoft/TypeScript/blob/main/lib/lib.dom.d.ts#L14276 30 | getItem(key: string): string | null; 31 | setItem(key: string, value: string): void; 32 | removeItem(key: string): void; 33 | } 34 | -------------------------------------------------------------------------------- /src/storageWrappers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AsyncStorageWrapper'; 2 | export * from './IonicStorageWrapper'; 3 | export * from './LocalForageWrapper'; 4 | export * from './LocalStorageWrapper'; 5 | export * from './MMKVStorageWrapper'; 6 | export * from './MMKVWrapper'; 7 | export * from './SessionStorageWrapper'; 8 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | import { ApolloCache } from '@apollo/client/core'; 2 | 3 | export type LogLevel = 'log' | 'warn' | 'error'; 4 | 5 | export type LogLine = [LogLevel, any[]]; 6 | 7 | export type TriggerUninstallFunction = () => void; 8 | 9 | export type TriggerFunction = (persist: () => void) => TriggerUninstallFunction; 10 | 11 | export type PersistenceMapperFunction = (data: any) => Promise; 12 | 13 | export type PersistedData = T | string | null; 14 | 15 | export interface PersistentStorage { 16 | getItem: (key: string) => Promise | T | null; 17 | setItem: (key: string, value: T) => Promise | Promise | void | T; 18 | removeItem: (key: string) => Promise | Promise | void; 19 | } 20 | 21 | type StorageType = TSerialize extends true 22 | ? PersistentStorage 23 | : PersistentStorage; 24 | 25 | export interface ApolloPersistOptions< 26 | TSerialized, 27 | TSerialize extends boolean = true 28 | > { 29 | cache: ApolloCache; 30 | storage: StorageType, TSerialize>; 31 | trigger?: 'write' | 'background' | TriggerFunction | false; 32 | debounce?: number; 33 | key?: string; 34 | serialize?: TSerialize; 35 | maxSize?: number | false; 36 | persistenceMapper?: PersistenceMapperFunction; 37 | debug?: boolean; 38 | } 39 | -------------------------------------------------------------------------------- /tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib/cjs", 5 | "module": "commonjs" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "outDir": "lib", 5 | "pretty": true, 6 | "noImplicitAny": true, 7 | "noUnusedParameters": false, 8 | "noUnusedLocals": true, 9 | "skipLibCheck": true, 10 | "moduleResolution": "node", 11 | "removeComments": true, 12 | "sourceMap": true, 13 | "declaration": true, 14 | "target": "es5", 15 | "module": "es2015", 16 | "lib": ["es2015"] 17 | }, 18 | "include": ["src/**/*.ts"], 19 | "exclude": [ 20 | "src/**/__tests__/*.ts", 21 | "src/**/__mocks__/*.ts", 22 | "node_modules" 23 | ] 24 | } 25 | --------------------------------------------------------------------------------