Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Commit

Permalink
feat: add example project for generated hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
tgriesser committed Mar 23, 2021
1 parent dc4acba commit c18a58f
Show file tree
Hide file tree
Showing 42 changed files with 12,426 additions and 0 deletions.
8 changes: 8 additions & 0 deletions example-hooks-gen/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"plugins": [
["relay", { "artifactDirectory": "./ts/__relay_artifacts__" }],
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-class-properties"
],
"presets": ["@babel/preset-typescript", "@babel/preset-react", "@babel/preset-env"]
}
1 change: 1 addition & 0 deletions example-hooks-gen/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
Empty file.
60 changes: 60 additions & 0 deletions example-hooks-gen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Relay TodoMVC

## Prerequisites

```
yarn global add yalc
```

And in the project root folder

```
yarn watch
```

## Installation

```
yarn install
```

## Running

Set up generated files:

```
yarn update-schema
yarn build
```

Start a local server:

```
yarn start
```

## Developing

Any changes you make to files in the `ts/` 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.graphql`, and restart the server:

```
yarn update-schema
yarn build
yarn start
```

## License

This file provided by Facebook is for non-commercial testing and evaluation
purposes only. Facebook reserves all rights not expressly granted.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
110 changes: 110 additions & 0 deletions example-hooks-gen/data/database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

export class Todo {}
export class User {
isAppending = true
}

// Mock authenticated ID
const VIEWER_ID = "me"

// Mock user data
const viewer = new User()
viewer.id = VIEWER_ID
const usersById = {
[VIEWER_ID]: viewer,
}

// Mock todo data
const todosById = {}
const todoIdsByUser = {
[VIEWER_ID]: [],
}
let nextTodoId = 0

for (let i = 0; i < 20; i++) {
addTodo(`Something Todo: ${i}`, false)
}

export function addTodo(text, complete) {
const todo = new Todo()
todo.complete = !!complete
todo.id = `${nextTodoId++}`
todo.text = text
todosById[todo.id] = todo
if (viewer.isAppending) {
todoIdsByUser[VIEWER_ID].push(todo.id)
} else {
todoIdsByUser[VIEWER_ID].unshift(todo.id)
}
return todo.id
}

export function changeTodoStatus(id, complete) {
const todo = getTodo(id)
todo.complete = complete
}

export function getTodo(id) {
return todosById[id]
}

export function getTodos(status = "any") {
const todos = todoIdsByUser[VIEWER_ID].map((id) => todosById[id])
if (status === "any") {
return todos
}
return todos.filter((todo) => todo.complete === (status === "completed"))
}

export function getUser(id) {
return usersById[id]
}

export function getViewer() {
return getUser(VIEWER_ID)
}

export function markAllTodos(complete) {
const changedTodos = []
getTodos().forEach((todo) => {
if (todo.complete !== complete) {
todo.complete = complete
changedTodos.push(todo)
}
})
return changedTodos.map((todo) => todo.id)
}

export function removeTodo(id) {
const todoIndex = todoIdsByUser[VIEWER_ID].indexOf(id)
if (todoIndex !== -1) {
todoIdsByUser[VIEWER_ID].splice(todoIndex, 1)
}
delete todosById[id]
}

export function removeCompletedTodos() {
const todosToRemove = getTodos().filter((todo) => todo.complete)
todosToRemove.forEach((todo) => removeTodo(todo.id))
return todosToRemove.map((todo) => todo.id)
}

export function renameTodo(id, text) {
const todo = getTodo(id)
todo.text = text
}

export function setIsAppending(isAppending) {
viewer.isAppending = isAppending
}
140 changes: 140 additions & 0 deletions example-hooks-gen/data/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
type Query {
viewer: User

"""Fetches an object given its ID"""
node(
"""The ID of an object"""
id: ID!
): Node
}

type User implements Node {
"""The ID of an object"""
id: ID!
todos(status: String = "any", after: String, first: Int, before: String, last: Int): TodoConnection
totalCount: Int
completedCount: Int
isAppending: Boolean!
}

"""An object with an ID"""
interface Node {
"""The id of the object."""
id: ID!
}

"""A connection to a list of items."""
type TodoConnection {
"""Information to aid in pagination."""
pageInfo: PageInfo!

"""A list of edges."""
edges: [TodoEdge]
}

"""Information about pagination in a connection."""
type PageInfo {
"""When paginating forwards, are there more items?"""
hasNextPage: Boolean!

"""When paginating backwards, are there more items?"""
hasPreviousPage: Boolean!

"""When paginating backwards, the cursor to continue."""
startCursor: String

"""When paginating forwards, the cursor to continue."""
endCursor: String
}

"""An edge in a connection."""
type TodoEdge {
"""The item at the end of the edge"""
node: Todo

"""A cursor for use in pagination"""
cursor: String!
}

type Todo implements Node {
"""The ID of an object"""
id: ID!
text: String
complete: Boolean
}

type Mutation {
addTodo(input: AddTodoInput!): AddTodoPayload
changeTodoStatus(input: ChangeTodoStatusInput!): ChangeTodoStatusPayload
markAllTodos(input: MarkAllTodosInput!): MarkAllTodosPayload
removeCompletedTodos(input: RemoveCompletedTodosInput!): RemoveCompletedTodosPayload
removeTodo(input: RemoveTodoInput!): RemoveTodoPayload
renameTodo(input: RenameTodoInput!): RenameTodoPayload
setAppending(appending: Boolean!): User
}

type AddTodoPayload {
todoEdge: TodoEdge
viewer: User
clientMutationId: String
}

input AddTodoInput {
text: String!
clientMutationId: String
}

type ChangeTodoStatusPayload {
todo: Todo
viewer: User
clientMutationId: String
}

input ChangeTodoStatusInput {
complete: Boolean!
id: ID!
clientMutationId: String
}

type MarkAllTodosPayload {
changedTodos: [Todo]
viewer: User
clientMutationId: String
}

input MarkAllTodosInput {
complete: Boolean!
clientMutationId: String
}

type RemoveCompletedTodosPayload {
deletedTodoIds: [String]
viewer: User
clientMutationId: String
}

input RemoveCompletedTodosInput {
clientMutationId: String
}

type RemoveTodoPayload {
deletedTodoId: ID
viewer: User
clientMutationId: String
}

input RemoveTodoInput {
id: ID!
clientMutationId: String
}

type RenameTodoPayload {
todo: Todo
clientMutationId: String
}

input RenameTodoInput {
id: ID!
text: String!
clientMutationId: String
}
Loading

0 comments on commit c18a58f

Please sign in to comment.