diff --git a/.gitignore b/.gitignore index 491fc35..dd79148 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules lib +npm-debug.log* diff --git a/README.md b/README.md index a25edff..568b813 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@ $ npm install --save relay-cache-manager ## Usage -[Until `RelayEnvironment` exposes `injectCacheManager`](https://github.com/facebook/relay/pull/1320) you have to inject it directly from the `RelayStoreData` instance used by your store. You can access that via the `getStoreData()` method on your `RelayEnvironment` instance. If you're using `Relay.Store` you can just do: +Use the `injectCacheManager` method on your `RelayEnvironment` instance to inject the cache manager. If you're using `Relay.Store` you can just do: ```js import CacheManager from 'relay-cache-manager'; const cacheManager = new CacheManager(); -Relay.Store.getStoreData().injectCacheManager(cacheManager); +Relay.Store.injectCacheManager(cacheManager); ``` diff --git a/example/README.md b/example/README.md index 11b485f..855c563 100644 --- a/example/README.md +++ b/example/README.md @@ -2,11 +2,35 @@ A fork of [relay-starter-kit](https://github.com/relayjs/relay-starter-kit) that implements `relay-cache-manager`. -## Try it out +This kit includes an app server, a GraphQL server, and a transpiler that you can use to get started building an app with Relay. For a walkthrough, see the [Relay tutorial](https://facebook.github.io/relay/docs/tutorial.html). -Make sure to run `npm install` in the root folder as well so `relay-cache-manager` builds correctly. +## Installation ``` npm install +``` + +## Running + +Start a local server: + +``` +npm start +``` + +## Developing + +Any changes you make to files in the `js/` directory will cause the server to +automatically rebuild the app and refresh your browser. + +If at any time you make changes to `data/schema.js`, stop the server, +regenerate `data/schema.json`, and restart the server: + +``` +npm run update-schema npm start ``` + +## License + +Relay Starter Kit is [BSD licensed](./LICENSE). We also provide an additional [patent grant](./PATENTS). diff --git a/example/data/schema.json b/example/data/schema.json index 8a0d605..eef2f99 100644 --- a/example/data/schema.json +++ b/example/data/schema.json @@ -1002,7 +1002,7 @@ { "kind": "OBJECT", "name": "__Directive", - "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL’s execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", + "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", "fields": [ { "name": "name", @@ -1315,7 +1315,7 @@ "args": [ { "name": "reason", - "description": "Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formattedin [Markdown](https://daringfireball.net/projects/markdown/).", + "description": "Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in [Markdown](https://daringfireball.net/projects/markdown/).", "type": { "kind": "SCALAR", "name": "String", diff --git a/example/js/app.js b/example/js/app.js index 42f9967..8bc4778 100644 --- a/example/js/app.js +++ b/example/js/app.js @@ -5,12 +5,12 @@ import AppHomeRoute from './routes/AppHomeRoute'; import React from 'react'; import ReactDOM from 'react-dom'; import Relay from 'react-relay'; + import CacheManager from 'relay-cache-manager'; const cacheManager = new CacheManager(); -Relay.Store.getStoreData().injectCacheManager(cacheManager); - +Relay.Store.injectCacheManager(cacheManager) ReactDOM.render( (internal/child_process.js:334:11) -5 verbose stack at emitOne (events.js:96:13) -5 verbose stack at Socket.emit (events.js:188:7) -5 verbose stack at Pipe._handle.close [as _onclose] (net.js:493:12) -6 verbose cwd /Users/brandondail/projects/relay-cache-manager -7 error Darwin 16.0.0 -8 error argv "/Users/brandondail/.nvm/versions/node/v6.5.0/bin/node" "/Users/brandondail/.nvm/versions/node/v6.5.0/bin/npm" "version" "patch" -9 error node v6.5.0 -10 error npm v3.10.3 -11 error Git working directory not clean. -11 error M .npmignore -12 error If you need help, you may report this error at: -12 error -13 verbose exit [ 1, true ] diff --git a/package.json b/package.json index 9f83ffa..88db91a 100644 --- a/package.json +++ b/package.json @@ -31,5 +31,8 @@ "babel-plugin-transform-class-properties": "^6.11.5", "babel-plugin-transform-flow-strip-types": "^6.8.0", "babel-preset-es2015": "^6.9.0" + }, + "dependencies": { + "localforage": "^1.4.3" } } diff --git a/src/CacheWriter.js b/src/CacheWriter.js index 04ef84e..8be8fae 100644 --- a/src/CacheWriter.js +++ b/src/CacheWriter.js @@ -8,10 +8,13 @@ import CacheRecordStore from './CacheRecordStore'; import type { CacheRecord } from './CacheRecordStore'; +import localForage from 'localforage'; + const DEFAULT_CACHE_KEY: string = '__RelayCacheManager__'; type CacheWriterOptions = { cacheKey?: string, + localForage?: mixed, } export default class CacheWriter { @@ -19,22 +22,23 @@ export default class CacheWriter { cacheKey: string; constructor(options: CacheWriterOptions = {}) { this.cacheKey = options.cacheKey || DEFAULT_CACHE_KEY - try { - let localCache = localStorage.getItem(this.cacheKey); - if (localCache) { - localCache = JSON.parse(localCache); - this.cache = CacheRecordStore.fromJSON(localCache); - } else { - this.cache = new CacheRecordStore(); - } - } catch(err) { - this.cache = new CacheRecordStore(); - } + localForage.config(options.localForage || {}); + + localForage.getItem(this.cacheKey) + .then(localCache => { + if (!localCache) { + this.cache = new CacheRecordStore(); + } else { + this.cache = CacheRecordStore.fromJSON(localCache) + } + }) + .catch(err => this.cache = new CacheRecordStore()); } clearStorage() { - localStorage.removeItem(this.cacheKey); - this.cache = new CacheRecordStore(); + localForage.removeItem(this.cacheKey) + .then(() => this.cache = new CacheRecordStore()) + .catch(err => this.cache = new CacheRecordStore()); } writeField( @@ -52,12 +56,7 @@ export default class CacheWriter { } record[field] = value; this.cache.records[dataId] = record; - try { - const serialized = JSON.stringify(this.cache); - localStorage.setItem(this.cacheKey, serialized); - } catch (err) { - /* noop */ - } + localForage.setItem(this.cacheKey, this.cache); } writeNode(dataId: string, record: CacheRecord) { diff --git a/src/RelayCacheManager.js b/src/RelayCacheManager.js index 8503975..571f027 100644 --- a/src/RelayCacheManager.js +++ b/src/RelayCacheManager.js @@ -8,6 +8,7 @@ import CacheWriter from './CacheWriter'; type RelayCacheManagerOptions = { cacheKey?: string, + localForage?: mixed, } export default class RelayCacheManager {