A GraphQL client for React using modern context and hooks APIs that is lightweight (< 4 kB) but powerful; the first Relay and Apollo alternative with server side rendering.
MIT License
Bot releases are hidden (Show)
react-waterfall-render
dependency to v5.extract-files
dependency to v13.node:
URL scheme for Node.js builtin module imports in tests.Record
types with index signatures.is-plain-obj
.Published by jaydenseric about 2 years ago
^14.17.0 || ^16.0.0 || >= 18.0.0
.react
peer dependency to 16.14 - 18
.react-dom
peer dependency.@testing-library/react-hooks
dev dependency and rewrote React hook tests using react-test-renderer
, a new test utility function createReactTestRenderer
, and a custom React component ReactHookTest
.fetch-blob
and formdata-node
dev dependencies. Instead, File
and FormData
are imported from node-fetch
.jsconfig.json
:
compilerOptions.maxNodeModuleJsDepth
to 10
.compilerOptions.module
to nodenext
.not IE > 0
from the Browserslist query.react-dom/server
imports in tests to suit React v18.fetchGraphQL
test with the global fetch
API unavailable for new versions of Node.js that have the fetch
global.globalThis
instead of global
in tests.ReactTestRenderer
instead of ReactDOMServer.renderToStaticMarkup
in some React context related tests.graphql-react
examples repo migration from Node.js, Next.js, and Vercel to Deno, Ruck, and Fly.io.Published by jaydenseric over 2 years ago
FetchGraphQLResultErrors
to FetchGraphQLResultError
in fetchGraphQL.mjs
.FetchGraphQLResultErrorLoading
to fetchGraphQL.mjs
containing the GraphQL result error types related to loading that are generated on the client, not the GraphQL server.types.mjs
.Deferred
class used in tests.Published by jaydenseric almost 3 years ago
extract-files
dependency.react-waterfall-render
dependency.files
and exports
fields.jsdoc-md
dev dependency and the package docs-update
and docs-check
scripts, replacing the readme “API” section with a manually written “Exports” section.types
script.formdata-node
dev dependency with formdata-polyfill
and fetch-blob
.license.md
MIT License file, fixing #54.Published by jaydenseric almost 3 years ago
^12.22.0 || ^14.17.0 || >= 16.0.0
.files
and exports
fields../package
from the package exports
field; the full package.json
filename must be used in a require
path./public/
..mjs
files instead of CJS in .js
files, accessible via import
but not require
.React.createElement
instead of the the new React JSX runtime.isobject
dependency.useCacheEntryPrunePrevention
React hook to avoid the React.useCallback
React hook.react
and react-dom
as they’re not proper Node.js ESM.process.env.NODE_ENV
.eslint-plugin-compat
.assertBundleSize
function to assert module bundle size in tests:
singleQuote
to the default, false
.Published by jaydenseric over 3 years ago
extract-files
dependency to v11. This dependency is used by the function fetchOptionsGraphQL
.Published by jaydenseric over 3 years ago
^12.20 || >= 14.13
.package.json
exports
field public subpath folder mapping (deprecated by Node.js) with a subpath pattern. Deep require
paths within graphql-react/public/
must now include the .js
file extension..mjs
files instead of CJS in .js
files.jsdoc-md
v10+ automatically generates a Prettier formatted readme.test:jsdoc
script that checks the readme API docs are up to date with the source JSDoc.esbuild
instead of webpack
and disposable-directory
.esbuild
instead of webpack
.kB
symbol instead of KB
wherever bundle size is mentioned in the package description and readme.require
from react
to slightly improve the esbuild
bundle size..js
file extension in internal require
paths.changelog.md
is no longer published.Published by jaydenseric over 3 years ago
Updated Node.js version support to ^12.0.0 || >= 13.7.0
.
Stopped supporting Internet Explorer.
Updated the react
and react-dom
peer dependencies to 16.14 - 17
.
Use the new JSX runtime.
Reorganized the file structure and replaced the entire API:
GraphQL
GraphQLContext
GraphQLProvider
hashObject
reportCacheErrors
useGraphQL
ssr
graphql-react/public/
.js
CJS modules:
Cache
CacheContext
HYDRATION_TIME_MS
HydrationTimeStampContext
Loading
LoadingCacheValue
LoadingContext
Provider
cacheDelete
cacheEntryDelete
cacheEntryPrune
cacheEntrySet
cacheEntryStale
cachePrune
cacheStale
fetchGraphQL
fetchOptionsGraphQL
useAutoAbortLoad
useAutoLoad
useCache
useCacheEntry
useCacheEntryPrunePrevention
useLoadGraphQL
useLoadOnDelete
useLoadOnMount
useLoadOnStale
useLoading
useLoadingEntry
useWaterfallLoad
waterfallRender
from react-waterfall-render
should now be used for server side rendering, fixing #57.The API for the cache (centered around a Cache
instance provided in the CacheContext
React context) is separated from the API for loading (centered around a Loading
instance provided in the LoadingContext
React context). Although the new loading system should work well for everyone, it could be totally avoided in an app that implements a custom alternative.
Instead of using the old mitt
dependency for events, the Cache
and Loading
classes extend the native EventTarget
global available in modern browsers and Node.js; a powerful and familiar event system with zero bundle size cost.
The new API avoids class methods that add to bundle size regardless if they are used, in favor of focused functions that can be imported to process instances as arguments. For example, one route in your app may only render a cache entry, while another may have a form that makes the global cache stale. If the functionality to make the cache stale was a Cache
instance method, it would increase the bundle size for the entire app, whereas a function imported in the second route will only grow the bundle size for that route. Features can be added to the API over time without growing everyone’s bundles.
There are now functions that can be imported to directly manipulate the cache. The functions cacheEntrySet
and cacheEntryDelete
update a particular entry, and cacheDelete
deletes all cache.
There is a new approach for dealing with stale cache. The function cacheEntryStale
signals a single entry is stale, and cacheStale
does the same for all entries (useful after a mutation). These functions don’t actually update cache entries; they simply dispatch cache entry stale events and it’s up to components to listen for this event and reload the cache entry in response, typically via the useLoadOnStale
React hook.
Cache entries that are not relevant to the current view can now be pruned on demand using the functions cacheEntryPrune
for a single entry, or cachePrune
for all entries, fixing #55. These functions work by dispatching cache entry prune events on the Cache
instance, and for each event not cancelled by a listener with event.preventDefault()
, the cache entry is deleted. The useCacheEntryPrunePrevention
React hook can be used to automatically cancel pruning of a cache entry used in a component.
Cache keys are now manually defined instead of automatically derived from fetch
options hashes, fixing #56. This is easier to understand, is faster to render, and results in a smaller bundle size without the old fnv1a
dependency for hashing.
Instead of one useGraphQL
React hook with complex options that all add to a component’s bundle size regardless if they are used, there are now several more focused React hooks that can be composed to do exactly the work required, fixing #53.
The React hooks can be composed with custom ones to load and cache any type of data, not just GraphQL, using any method, not just fetch
.
The new loading system provides the ability to abort loading at any time, implemented using the native AbortController
global available in modern browsers and Node.js, fixing #24. Many of the new React hooks leverage this for features such as automatically aborting loading a cache entry when the component loading it unmounts. The new API makes it trivially easy to build features as auto-suggest search inputs that abort the last loading on new input, or page queries that abort loading if the user abandons the route.
While the new API may seem to have an intimidating number of public exports, the average Next.js app that queries and renders data from a GraphQL API will only use a few. For inspiration, see the readme “Examples” section.
Published modules now contain JSDoc comments, which might affect TypeScript projects.
actions/checkout
to v2.actions/setup-node
to v2.CI
environment variable as it’s set by default.hard-rejection
to detect unhandled Promise
rejections in tests, as Node.js v15+ does this natively.webpack
v5, and remove size-limit
related dev dependencies, config, and scripts.Published by jaydenseric almost 4 years ago
Published by jaydenseric about 4 years ago
Concurrent GraphQL operations with the same cache key no longer share the first request.
The GraphQL
instance property operations
type has changed:
- object<GraphQLCacheKey, Promise<GraphQLCacheValue>>
+ object<GraphQLCacheKey, Array<Promise<GraphQLCacheValue>>>
promisifyEvent
function.GraphQL
instance method operate
option reloadOnLoad
in isolation.GraphQL
instance method operate
triggered events.GraphQL
instance method operate
to eliminate the GraphQL
private instance method fetch
and reduce the chance of race conditions in consumer code.GraphQL
instance method operate
when the reloadOnLoad
and reloadOnLoad
options are false
.void
.Published by jaydenseric about 4 years ago
cacheKeyCreator
option to the GraphQL
instance method operate
and the useGraphQL
React hook.hashObject
function is now publicly exported.notEqual
assertions with notStrictEqual
in tests.TypeError
class instead of Error
for relevant errors.Published by jaydenseric about 4 years ago
displayName
and propTypes
to be removed in production builds, fixing #51.useGraphQL
React hook to do less work for following renders if the operation
and fetchOptionsOverride
options are defined outside the component or memoized using the React.useMemo
hook.useGraphQL
React hook returns for more efficient hook composition.loadedCacheValue
property to the GraphQL operation status object returned by the useGraphQL
React hook. This allows cache for an earlier operation to be rendered while loading changes to the query, variables, or fetch
options.coverage-node
to enforce 100% code coverage for tests.useGraphQL
React hook examples to use the GitHub GraphQL API.useGraphQL
React hook tests.Published by jaydenseric about 4 years ago
import
and require
the package exports.Published by jaydenseric about 4 years ago
extract-files
dependency to v9.0.0, and used its new deep require
path.@babel/plugin-proposal-class-properties
dev dependency and config, as @babel/preset-env
has handed this via it’s shippedProposals
options since v7.10.0..js
file extensions from require
paths.revertable-globals
to define globals per-test.node-fetch
v3 instead of cross-fetch
.formdata-node
workaround in graphqlFetchOptions
tests.npm-debug.log
from the .gitignore
file as npm v4.2.0+ doesn’t create it in the current working directory.Published by jaydenseric over 4 years ago
npm install-test
command.overrides
to ensure .js
files are parsed as scripts, eliminating Babel interopRequireDefault
helpers from transpilation output.Published by jaydenseric over 4 years ago
^10.17.0 || ^12.0.0 || >= 13.7.0
. This is only a correction; the dependency updates with breaking changes happened in previous versions.reportCacheErrors
JSDoc parameter type.Published by jaydenseric over 4 years ago
exports
field to support native ESM in Node.js..js
(CJS) instead of .mjs
(ESM), so undocumented deep imports may no longer work. This approach avoids the dual package hazard.10 - 12 || >= 13.7
to reflect the package exports
related breaking changes.babel-plugin-transform-runtime-file-extensions
dev dependency to simplify Babel config.prepare:prettier
and test:prettier
scripts.test:eslint
script args for consistency with test:prettier
.semi
to the default, true
.size-limit
:
Published by jaydenseric over 4 years ago
tap
dev dependency with test-director
and hard-rejection
, and refactored tests accordingly. This improves the dev experience and reduced the dev install size by ~75.5 MB.ReactDOM.unstable_batchedUpdates
in the useGraphQL
React hook to reduce the number of renders when loading completes, fixing #38 via #42. Although react-dom
was already a peer dependency, this is the first time it's being used in the client API; potentially a breaking change for atypical projects.object-assign
dependency and several Babel dev dependencies after simplifying the Babel config.babel-plugin-transform-require-extensions
dev dependency and ensured ESM import specifiers in both source and published .mjs
files contain file names with extensions, which are mandatory in the final Node.js ESM implementation. Published CJS .js
files now also have file extensions in require
paths.husky
and lint-staged
.prettier
v2.Published by jaydenseric almost 5 years ago
.github/funding.yml
to display a sponsor button in GitHub.package.json
funding
field to enable npm CLI funding features.Published by jaydenseric almost 5 years ago
eslint
dev dependency now supports. This is unlikely to be a breaking change for the published package.useGraphQL
React hook loadOnMount
, loadOnReload
, and loadOnReset
options now default to false
instead of true
. The loading related options are now all opt-in, which is easier to remember and simpler to configure for situations that previously required manual reversal of certain option defaults. It's also safer when working with mutations you don't want to accidentally load.size-limit
dev dependency with @size-limit/preset-small-lib
.useGraphQL
enabled option loadOnReload
causing a load when the global GraphQL
cache is reloaded even if there was no previously cached data to reload.useGraphQL
option loadOnReset
documentation.package-lock.json
from .gitignore
and .prettierignore
as it’s disabled in .npmrc
anyway.useGraphQL
tests.jsdoc-md
v3.1.0.