-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
155 changed files
with
24,365 additions
and
1,434 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*/node_modules | ||
*.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,6 @@ node_modules | |
build | ||
coverage | ||
.DS_Store | ||
website/build | ||
docs/api/**/* | ||
!docs/api/about-api-docs.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"type": "node", | ||
"request": "launch", | ||
"name": "Jest Current File", | ||
"program": "${workspaceFolder}/node_modules/.bin/jest", | ||
"args": ["${fileBasenameNoExtension}", "--config", "jest.config.js"], | ||
"console": "integratedTerminal", | ||
"internalConsoleOptions": "neverOpen", | ||
"disableOptimisticBPs": true, | ||
"windows": { | ||
"program": "${workspaceFolder}/node_modules/jest/bin/jest" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"workbench.colorCustomizations": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
FROM node:8.11.4 | ||
|
||
WORKDIR /app/website | ||
|
||
EXPOSE 3000 35729 | ||
COPY ./docs /app/docs | ||
COPY ./website /app/website | ||
RUN yarn install | ||
|
||
CMD ["yarn", "start"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,37 @@ | ||
# ReSift · [![Build Status](https://travis-ci.org/JustSift/ReSift.svg?branch=master)](https://travis-ci.org/JustSift/ReSift) [![Coverage Status](https://coveralls.io/repos/github/JustSift/ReSift/badge.svg?branch=master)](https://coveralls.io/github/JustSift/ReSift?branch=master) | ||
|
||
A work-in-progress. This will be the home of the open source version of ReSift. | ||
> 👋 **Too many words? Head over to the [Quick glance](./quick-glance.md)** 👉 | ||
Check back soon. There are no released versions yet. | ||
**ReSift is a state management library for fetches** with the goal of giving your team a capable standard for fetching, storing, and reacting to data. | ||
|
||
Initial release roadmap/todo list: https://github.com/JustSift/ReSift/issues/6 | ||
We like to think of ReSift as the [Relay](https://relay.dev/) of REST. ReSift is in the same class of tools as [Relay](https://relay.dev/) and [the Apollo Client](https://www.apollographql.com/docs/react/). However, ReSift does _not_ require GraphQL. | ||
|
||
If you're looking for the internal version [see here](https://github.com/JustSift/ReSift-Internal) | ||
[See this doc for definitions and comparisons of ReSift vs Relay/Apollo](../guides/resift-vs-apollo-relay.md). | ||
|
||
## Motivation | ||
|
||
When developing a React application, you might realize that there is a lot more than meets the eye regarding data fetching. | ||
|
||
With every fetch we need to know: | ||
|
||
- If the data request is inflight (so we can show a loading indicator) | ||
- Where the resulting data will be stored, and how to later retrieve it | ||
- If it's related to other fetches so they update consistently | ||
- If the response was an error so we can try to recover | ||
|
||
These tasks themselves aren't overly complicated, but doing them over and over and over again _will_ take time away from your product. | ||
|
||
To make matters worse, there is an infinite number of ways to accomplish said tasks, and managing these differences while working on a team can be confusing and hard to manage. | ||
|
||
## Introducing ReSift | ||
|
||
ReSift is a capable and versatile library for data fetches. ReSift is opinionated where it matters but also pluggable to suit your different data fetching needs. | ||
|
||
**Features:** | ||
|
||
- 💾 Framework for storing and retrieving responses from data requests | ||
- 📬 Monitoring and updating the status of inflight requests | ||
- 🔌 Pluggable via custom "data services" | ||
- 🌐 Universal — Share code amongst your apps. **Works with React Native!** | ||
- 🎣 Hooks API | ||
- 🤝 Full TypeScript support |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
version: "3" | ||
|
||
services: | ||
docusaurus: | ||
build: . | ||
ports: | ||
- 3000:3000 | ||
- 35729:35729 | ||
volumes: | ||
- ./docs:/app/docs | ||
- ./website/blog:/app/website/blog | ||
- ./website/core:/app/website/core | ||
- ./website/i18n:/app/website/i18n | ||
- ./website/pages:/app/website/pages | ||
- ./website/static:/app/website/static | ||
- ./website/sidebars.json:/app/website/sidebars.json | ||
- ./website/siteConfig.js:/app/website/siteConfig.js | ||
working_dir: /app/website |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
--- | ||
id: about-api-docs | ||
title: About API docs | ||
sidebar_label: About these docs | ||
--- | ||
|
||
These docs are auto-generated by [`generate-api-docs.js`](https://github.com/JustSift/ReSift/blob/master/website/generate-api-doc.js) which generates the docs based on the ambient typings files within the repository (the `*.d.ts` files). [See below for more info.](#how-these-docs-work) | ||
|
||
If you are using an editor that uses the typescript language service (e.g. vs-code, visual studio, webstorm/intelliJ), then you should be able to hover over the definitions within your editor to get the same documentation. | ||
|
||
Please open any issues if you find any within these docs. Open pull requests modifying the `*.d.ts` files. | ||
|
||
## How these docs work | ||
|
||
These docs work by parsing the ambient typings files (`*.d.ts`) files in `/src` and turning them into markdown files (`*.md`). | ||
|
||
This works by using the typescript API (i.e. `const ts = require('typescript');`) to parse the ambient typings for JS doc comments, interfaces, and other code. | ||
|
||
The generator will only pick up code that is commented with a JSDoc comment that contains the `@docs` directive. | ||
|
||
```ts | ||
// this comment must be a JSDoc comment | ||
// 👇 (which is more than a multi-line comment) | ||
/** | ||
* @docs Title of `module` | ||
* | ||
* Description of module. You can also put _markdown_ in **here** | ||
*/ | ||
function myModule(x: number): string; | ||
``` | ||
|
||
This will generate the following document: | ||
|
||
--- | ||
|
||
#### Title of `module` | ||
|
||
Description of module. You can also put _markdown_ in **here** | ||
|
||
```ts | ||
function module(x: number): string; | ||
``` | ||
|
||
--- | ||
|
||
## Generating tables for `interface`s | ||
|
||
When you put the `@docs` directive above an interface, the generator will go through all the property declarations and generate a table. | ||
|
||
```ts | ||
/** | ||
* @docs `ExampleModule` | ||
* | ||
* This is a description of `ExampleModule` | ||
*/ | ||
interface ExampleModule { | ||
/** | ||
* This is the description of foo. | ||
*/ | ||
foo: string; | ||
/** | ||
* This is the description of bar. | ||
*/ | ||
bar?: number; | ||
} | ||
``` | ||
|
||
--- | ||
|
||
#### `ExampleModule` | ||
|
||
This is a description of `ExampleModule` | ||
|
||
| Name | Description | Type | Required | | ||
| ---- | ------------------------------- | ------------------- | -------- | | ||
| foo | This is the description of foo. | <code>string</code> | yes | | ||
| bar | This is the description of bar. | <code>number</code> | no | | ||
|
||
--- | ||
|
||
## Other code behavior | ||
|
||
When the generator sees the `@docs` directive in a JSDoc comment before anything else that isn't an `interface`, it will simply take the declaration and wrap it in a code block with one difference—it will remove the generics from the types (e.g. `<T>`). | ||
|
||
Why? Non-TS users are confused by generics. Simply removing the generics declaration (i.e. the stuff between the `<>`s) fixes the readability issue while also keeping the generics there. | ||
|
||
For example, see the input code block vs the output code block. | ||
|
||
Input: | ||
|
||
```ts | ||
export function myModule<Foo, Bar, Args extends any[], Result>( | ||
...args: Args | ||
): { | ||
foo: Foo; | ||
bar: (bar: Bar) => Result; | ||
}; | ||
``` | ||
|
||
Output (more readable to JS users): | ||
|
||
```ts | ||
function myModule( | ||
...args: Args | ||
): { | ||
foo: Foo; | ||
bar: (bar: Bar) => Result; | ||
}; | ||
``` |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
--- | ||
id: infinite-scroll | ||
title: Infinite scroll | ||
sidebar_label: Infinite scroll | ||
--- | ||
|
||
The following demo is from the [Sharing state between fetches](../main-concepts/sharing-state-between-fetches.md#merges) doc. This example demonstrates how you can use `share.merge` do infinite scrolling. | ||
|
||
<iframe src="https://codesandbox.io/embed/resift-infinite-scroll-df5kt?fontsize=14" | ||
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" | ||
title="ReSift Infinite Scroll" | ||
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb" | ||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin" | ||
></iframe> | ||
<br /> | ||
Don't hesitate to reach out if you've found an issue. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
id: resift-notes | ||
title: ReSift Notes | ||
sidebar_label: ReSift Notes (CRUD) | ||
--- | ||
|
||
The following application is a basic CRUD application made to be a quick reference in how to do CRUD and loading spinner correctly. | ||
|
||
Read the notes and explore the code. | ||
|
||
<iframe src="https://codesandbox.io/embed/resift-notesj-xwp9r?fontsize=14" title="ReSift Notes" allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe> | ||
|
||
<br /> | ||
Don't hesitate to reach out if you've found an issue. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
id: resift-rentals | ||
title: ReSift Rentals | ||
sidebar_label: ReSift Rentals | ||
--- | ||
|
||
This doc will contain the finished demo from the tutorial. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
--- | ||
id: http-proxies | ||
title: HTTP proxies | ||
sidebar_label: HTTP proxies | ||
--- | ||
|
||
HTTP Proxies are a feature of the HTTP [data service](../main-concepts/what-are-data-services.md). | ||
|
||
HTTP proxies allow you to intercept `http` data service calls within fetches and potentially do something else. | ||
|
||
You define an HTTP proxy by calling `createHttpProxy` from ReSift. | ||
|
||
A common use case of HTTP proxies is to use them for mocking an HTTP server. We use HTTP proxies to power the demos in these docs. | ||
|
||
`mockApi.js` | ||
|
||
```js | ||
import { createHttpProxy } from 'resift'; | ||
|
||
export const mockPeopleEndpoint = createHttpProxy( | ||
'/people/:personId', | ||
async ({ match, requestParams, http }) => { | ||
// ... | ||
}, | ||
); | ||
``` | ||
|
||
After you create your proxy, add it to the `proxies` array when you create the HTTP service: | ||
|
||
```js | ||
import { createDataService, createHttpService } from 'resift'; | ||
import { mockPeopleEndpoint } from './mockApi'; | ||
|
||
const http = createHttpService({ | ||
proxies: [mockPeopleEndpoint], | ||
}); | ||
|
||
const dataService = createDataService({ | ||
services: { http }, | ||
onError: e => { | ||
throw e; | ||
}, | ||
}); | ||
|
||
export default dataService; | ||
``` | ||
|
||
When you create an HTTP proxy, you provide a path or path options. The HTTP service will iterate through the proxies until it finds a match. The first match found will be the proxy it uses. | ||
|
||
The matching algorithm is a blatant copy/paste of `react-router`'s [`matchPath`](https://reacttraining.com/react-router/web/api/matchPath) | ||
|
||
## `createHttpProxy` API | ||
|
||
The first argument to `createHttpProxy` is the path you'd like to match. If an `http` call matches this path, the second argument, the handler, will run. | ||
|
||
In the handler, you can destructure: `requestParams`, `http`, `match`, and [more](../api/create-http-proxy.md#httpproxyparams) | ||
|
||
- The `requestParams` are the parameters the caller (in the data service) passes to the `http` call | ||
- `http` is the original `http` service. You can call it to make an actual HTTP request. | ||
- `match` is the result of react-router's [`matchPath`](https://reacttraining.com/react-router/web/api/matchPath) function. It contains the match params in `match.params` | ||
|
||
Here are some example mock endpoints from the [ReSift Notes example](../examples/resift-notes.md). | ||
|
||
```js | ||
import { createHttpProxy } from 'resift'; | ||
import shortId from 'shortid'; | ||
import delay from 'delay'; | ||
import moment from 'moment'; | ||
import { stripIndent } from 'common-tags'; | ||
|
||
const waitTime = 1000; | ||
|
||
let noteData = [ | ||
{ | ||
id: 'sJxbrzBcn', | ||
content: stripIndent` | ||
# This is a note | ||
`, | ||
updatedAt: moment().toISOString(), | ||
}, | ||
]; | ||
|
||
export const notes = createHttpProxy({ path: '/notes', exact: true }, async ({ requestParams }) => { | ||
await delay(waitTime); | ||
|
||
const { method, data } = requestParams; | ||
|
||
if (method === 'GET') { | ||
// send a shallow copy just in case. | ||
// with a real API, the object returned would always be fresh references | ||
return [...noteData]; | ||
} | ||
|
||
if (method === 'POST') { | ||
const newNote = { | ||
...data, | ||
id: shortId(), | ||
}; | ||
noteData.push(newNote); | ||
|
||
return newNote; | ||
} | ||
}); | ||
|
||
export const note = createHttpProxy('/notes/:id', async ({ requestParams, match }) => { | ||
await delay(waitTime); | ||
|
||
const { method, data } = requestParams; | ||
const { id } = match.params; | ||
|
||
if (method === 'GET') { | ||
const note = noteData.find(note => note.id === id); | ||
if (!note) throw new Error('Not Found'); | ||
|
||
return note; | ||
} | ||
|
||
if (method === 'PUT') { | ||
const index = noteData.findIndex(note => note.id === id); | ||
if (index === -1) throw new Error('Not Found'); | ||
|
||
noteData[index] = data; | ||
return data; | ||
} | ||
|
||
if (method === 'DELETE') { | ||
const note = noteData.find(note => note.id === id); | ||
if (!note) throw new Error('Not Found'); | ||
|
||
noteData = noteData.filter(note => note.id !== id); | ||
return undefined; | ||
} | ||
}); | ||
``` |
Oops, something went wrong.