shells/dev/relay-app/FriendsList/createInBrowserNetwork.js (127 lines of code) (raw):

/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ /** * This file implements the Relay "network" as a server running in the browser. * This allows the test app to send network requests that can be observed without * running a separate server. */ import { Network } from 'relay-runtime'; import { graphql, buildSchema } from 'graphql'; import Chance from 'chance'; const chance = new Chance(); let nextID = 1000; function guid(prefix) { return `${prefix}-${nextID++}`; } const schema = buildSchema(` type Query { node(id: ID!): Node } interface Node { id: ID! } type User implements Node { id: ID! name: String profilePicture: ProfilePicture, friends( after: ID before: ID first: Int last: Int ): FriendsConnection } type ProfilePicture { url: String } type FriendsConnection { count: Int edges: [FriendsEdge] pageInfo: PageInfo } type FriendsEdge { cursor: String node: User } type PageInfo { hasPreviousPage: Boolean hasNextPage: Boolean endCursor: String startCursor: String } `); function createInBrowserNetwork() { class User { +__typename: 'User'; +id: string; +name: string; _gender: 'male' | 'female'; _profilePicture: {| +url: string, |}; _friends: $ReadOnlyArray<User>; constructor(id) { this.__typename = 'User'; this.id = id == null ? guid('user') : id; this._gender = chance.pick(['male', 'female']); this.name = chance.name({ gender: this._gender, }); } profilePicture() { if (!this._profilePicture) { this._profilePicture = { url: `https://randomuser.me/api/portraits/thumb/${ this._gender === 'female' ? 'women' : 'men' }/${Math.floor(Math.random() * 100)}.jpg`, }; } return this._profilePicture; } friends() { if (!this._friends) { this._friends = []; for (let i = 0; i < 4; i++) { this._friends = this._friends.concat([createUser()]); } } else { this._friends = this._friends.concat([createUser()]); } return createConnection(this._friends); } } function mockPageInfo() { return { hasPreviousPage: true, hasNextPage: true, endCursor: 'todo', startCursor: 'todo', }; } function createConnection(nodes) { return { count: nodes.length + 1, edges: nodes.map((node, index) => ({ cursor: index, node, })), pageInfo: () => mockPageInfo(), }; } const userMap = new Map(); function createUser(id) { const user = new User(id); userMap.set(user.id, user); return user; } const root = { node: ({ id }) => { if (!userMap.has(id)) { return createUser(id); } return userMap.get(id); }, }; function fetchQuery(request, variables) { return new Promise(resolve => { setTimeout(() => { resolve(graphql(schema, request.text, root, null, variables)); }, 1000 + Math.round(Math.random() * 1000)); }); } return Network.create(fetchQuery); } export default createInBrowserNetwork;