contentful-local-schema
v0.1.6
Published
[](https://github.com/watermarkchurch/contentful-local-schema/actions) [;
const spaceId = process.env.CONTENTFUL_SPACEID;
const environmentId = process.env.CONTENTFUL_ENVIRONMENT || 'master';
const contentfulClient = createSimpleClient({
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
space: spaceId,
environmentId,
});
// Enable Syncing
addSync(dataSource, contentfulClient)
// Enable backup/restore to AsyncStorage
addBackup(dataSource, AsyncStorage, `contentful/${spaceId}/${environmentId}`)
/**
* Wraps the `sync` and `backup` functions to execute a resync on demand.
* The react integration handles this for you.
*/
export const resyncContentful = () => {
const syncPromise = dataSource.sync();
// In the background, after the sync finishes, backup to AsyncStorage.
// If this fails, we don't really care because at least the sync succeeded.
syncPromise.then(() => dataSource.backup()).catch((ex) => {
console.error('Post-sync backup failed', ex);
});
return syncPromise;
};
// Cold startup: import the initial state from async storage. This returns
// a promise that can be awaited in your initializers.
// The react integration also takes care of this.
const ensureContentfulLoaded = dataSource.restore();
.then(
() => resyncContentful(),
(ex) => {
console.error('Restore failed, executing full sync', ex);
return resyncContentful();
}
)
.catch((ex) => {
console.error('sync failed', ex);
throw ex;
});Usage with React
The contentful-local-schema/react library provides a set of React hooks to easily query your InMemoryDataSource.
To get started, import and mount the provider:
import { LocalSchemaProvider } from 'contentful-local-schema/react'
import { SplashScreen } from './screens/splashScreen'
// Import your dataSource that you configured above
import { dataSource } from './dataSource';
export function App() {
return <LocalSchemaProvider
dataSource={dataSource}
Loading={SplashScreen}
>
<Router>
...
</Router>
</LocalSchemaProvider>
}Then in your individual screens, query the data source:
export function Home() {
const [announcements, { loading, error, refreshing }, refresh] = useQueryEntries('announcements', { 'date[lt]': Date.now().toISOString() })
return <FlatList
refreshing={loading || refreshing}
onRefresh={refresh}
data={announcements?.items || []}
renderItem={({ item }) => <Item {...item} />}>
</FlatList>
}
export function Announcement({id}: {id: string}) {
const [entry, { loading }] = useFindEntry(id)
// Note: entry is undefined until it finishes loading
return <View>
<H4>{entry?.fields?.title}</H4>
...
</View>
}For more information on the various query methods, see the source files:
Note: useQuery can be used to conveniently make multi-step queries against the dataSource.
Example:
// Load all the `day` entries that this conference links to, and sort them by date
const [days, { loading, error, refreshing}, refresh] = useQuery(async (dataSource) => {
const conference = await dataSource.getEntry(conferenceId)
const dayIds = (conference.fields.days as Link<'Entry'>[]).map((day) => day.sys.id)
const days = await dataSource.getEntries({ content_type: 'day', 'sys.id[in]': dayIds })
return days.items.sort(byDate)
}, [conferenceId])Usage with GraphQL
The contentful-local-schema/graphql package exposes utilities to create a local
GraphQL schema and resolvers that can be queried using the @client directive.
See https://www.apollographql.com/docs/react/local-state/local-resolvers/ for details.
Ensure you have the GraphQL peer dependencies installed
$ npm install graphql graphql-type-jsonNext, download the 'contentful-schema.json' file and commit it to your project repo:
$ npx contentful-local-schema
$ git add ./contentful-schema.json
$ git commitThen, use the utilities to load the schema with resolvers into your Apollo client:
import { createLocalResolvers, createSchema } from "contentful-local-schema/graphql";
import { ApolloClient, gql, InMemoryCache } from "@apollo/client";
// Import your dataSource that you configured above
import { dataSource } from './dataSource';
// Create the schema
const schema: GraphQLSchema = await createSchema()
// Build the local resolvers around the data source
const resolvers = await createLocalResolvers(dataSource);
// Build the Apollo client from the schema and local resolvers
export const apolloClient = new ApolloClient({
cache: new InMemoryCache(),
link: { request: jest.fn() } as any,
typeDefs: schema as any,
resolvers,
});Then you can easily query your apollo client
// Query the apollo client
const result = await apolloClient.query({
query: gql`
query getEvent($id: string!) {
event(id: $id) @client {
sys {
id
}
title
}
}
`,
variables: {
id: "1234",
},
});
expect(result.errors).toBeUndefined();
const { event } = result.data;
expect(event.sys.id).toEqual("1234");
expect(event.title).toEqual("The event title");see src/index.spec.ts for more cool queries
Installation:
npm install contentful-local-schemaOr with yarn
yarn add contentful-local-schemaIf using typescript:
This package relies on types from @apollo/client. If you
don't already have it as a peer dependency, you should install it as
dev dependencies in order to compile with Typescript.
npm install --save-dev @apollo/clientyarn add --dev @apollo/client