├── .gitignore ├── client ├── src │ ├── react-app-env.d.ts │ ├── index.tsx │ ├── App.css │ ├── index.css │ ├── components │ │ ├── style.css │ │ ├── ChatBubble.tsx │ │ ├── UserList.tsx │ │ ├── ImageGallery.tsx │ │ ├── Greeting.tsx │ │ └── Chat.tsx │ ├── App.tsx │ └── proto │ │ ├── RandomServiceClientPb.ts │ │ ├── random_pb.d.ts │ │ └── random_pb.js ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── .gitignore ├── tsconfig.json ├── package.json └── README.md ├── data ├── dump.rdb └── appendonly.aof ├── architecture-diagram.png ├── proto ├── google │ └── protobuf │ │ └── Empty.ts ├── randomPackage │ ├── Status.ts │ ├── StreamRequest.ts │ ├── ChatRequest.ts │ ├── NumberResponse.ts │ ├── PingRequest.ts │ ├── InitiateResponse.ts │ ├── NumberRequest.ts │ ├── PongResponse.ts │ ├── ChatConnectRequest.ts │ ├── TodoRequest.ts │ ├── MessageRequest.ts │ ├── ChatResponse.ts │ ├── InitiateRequest.ts │ ├── UserStreamResponse.ts │ ├── StreamMessage.ts │ ├── TodoResponse.ts │ ├── User.ts │ └── Random.ts ├── random.ts └── random.proto ├── proto-gen.sh ├── docker-compose.yml ├── package.json ├── README.md ├── pubsub.ts ├── data.ts ├── envoy.yaml ├── server.ts └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules -------------------------------------------------------------------------------- /client/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /data/dump.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/floydjones1/grpc-chatApp-react/HEAD/data/dump.rdb -------------------------------------------------------------------------------- /client/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /architecture-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/floydjones1/grpc-chatApp-react/HEAD/architecture-diagram.png -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/floydjones1/grpc-chatApp-react/HEAD/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/floydjones1/grpc-chatApp-react/HEAD/client/public/logo192.png -------------------------------------------------------------------------------- /client/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/floydjones1/grpc-chatApp-react/HEAD/client/public/logo512.png -------------------------------------------------------------------------------- /proto/google/protobuf/Empty.ts: -------------------------------------------------------------------------------- 1 | // Original file: null 2 | 3 | 4 | export interface Empty { 5 | } 6 | 7 | export interface Empty__Output { 8 | } 9 | -------------------------------------------------------------------------------- /proto/randomPackage/Status.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | export enum Status { 4 | UNKOWN = 0, 5 | ONLINE = 1, 6 | OFFLINE = 2, 7 | } 8 | -------------------------------------------------------------------------------- /proto/randomPackage/StreamRequest.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface StreamRequest { 5 | 'id'?: (number); 6 | } 7 | 8 | export interface StreamRequest__Output { 9 | 'id'?: (number); 10 | } 11 | -------------------------------------------------------------------------------- /proto/randomPackage/ChatRequest.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface ChatRequest { 5 | 'message'?: (string); 6 | } 7 | 8 | export interface ChatRequest__Output { 9 | 'message'?: (string); 10 | } 11 | -------------------------------------------------------------------------------- /proto/randomPackage/NumberResponse.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface NumberResponse { 5 | 'num'?: (number); 6 | } 7 | 8 | export interface NumberResponse__Output { 9 | 'num'?: (number); 10 | } 11 | -------------------------------------------------------------------------------- /proto/randomPackage/PingRequest.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface PingRequest { 5 | 'message'?: (string); 6 | } 7 | 8 | export interface PingRequest__Output { 9 | 'message'?: (string); 10 | } 11 | -------------------------------------------------------------------------------- /proto/randomPackage/InitiateResponse.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface InitiateResponse { 5 | 'id'?: (number); 6 | } 7 | 8 | export interface InitiateResponse__Output { 9 | 'id'?: (number); 10 | } 11 | -------------------------------------------------------------------------------- /proto/randomPackage/NumberRequest.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface NumberRequest { 5 | 'maxVal'?: (number); 6 | } 7 | 8 | export interface NumberRequest__Output { 9 | 'maxVal'?: (number); 10 | } 11 | -------------------------------------------------------------------------------- /proto/randomPackage/PongResponse.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface PongResponse { 5 | 'message'?: (string); 6 | } 7 | 8 | export interface PongResponse__Output { 9 | 'message'?: (string); 10 | } 11 | -------------------------------------------------------------------------------- /proto/randomPackage/ChatConnectRequest.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface ChatConnectRequest { 5 | 'id'?: (number); 6 | } 7 | 8 | export interface ChatConnectRequest__Output { 9 | 'id'?: (number); 10 | } 11 | -------------------------------------------------------------------------------- /client/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById("root") 11 | ); 12 | -------------------------------------------------------------------------------- /proto/randomPackage/TodoRequest.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface TodoRequest { 5 | 'todo'?: (string); 6 | 'status'?: (string); 7 | } 8 | 9 | export interface TodoRequest__Output { 10 | 'todo'?: (string); 11 | 'status'?: (string); 12 | } 13 | -------------------------------------------------------------------------------- /proto/randomPackage/MessageRequest.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface MessageRequest { 5 | 'id'?: (number); 6 | 'message'?: (string); 7 | } 8 | 9 | export interface MessageRequest__Output { 10 | 'id'?: (number); 11 | 'message'?: (string); 12 | } 13 | -------------------------------------------------------------------------------- /proto-gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | yarn proto-loader-gen-types --grpcLib=@grpc/grpc-js --outDir=proto/ proto/*.proto 4 | 5 | mkdir -p ./client/src/proto 6 | protoc -I=. ./proto/*.proto \ 7 | --js_out=import_style=commonjs:./client/src \ 8 | --grpc-web_out=import_style=typescript,mode=grpcwebtext:./client/src -------------------------------------------------------------------------------- /proto/randomPackage/ChatResponse.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface ChatResponse { 5 | 'username'?: (string); 6 | 'message'?: (string); 7 | } 8 | 9 | export interface ChatResponse__Output { 10 | 'username'?: (string); 11 | 'message'?: (string); 12 | } 13 | -------------------------------------------------------------------------------- /proto/randomPackage/InitiateRequest.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface InitiateRequest { 5 | 'name'?: (string); 6 | 'avatarUrl'?: (string); 7 | } 8 | 9 | export interface InitiateRequest__Output { 10 | 'name'?: (string); 11 | 'avatarUrl'?: (string); 12 | } 13 | -------------------------------------------------------------------------------- /client/src/App.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | margin: 0; 5 | } 6 | 7 | .App { 8 | display: flex; 9 | justify-content: center; 10 | text-align: center; 11 | flex-direction: column; 12 | height: 100vh; 13 | background-color: aliceblue; 14 | align-items: center; 15 | } 16 | 17 | * { 18 | box-sizing: border-box; 19 | } 20 | -------------------------------------------------------------------------------- /proto/randomPackage/UserStreamResponse.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | import type { User as _randomPackage_User, User__Output as _randomPackage_User__Output } from '../randomPackage/User'; 4 | 5 | export interface UserStreamResponse { 6 | 'users'?: (_randomPackage_User)[]; 7 | } 8 | 9 | export interface UserStreamResponse__Output { 10 | 'users'?: (_randomPackage_User__Output)[]; 11 | } 12 | -------------------------------------------------------------------------------- /proto/randomPackage/StreamMessage.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | 4 | export interface StreamMessage { 5 | 'id'?: (number); 6 | 'senderName'?: (string); 7 | 'senderAvatar'?: (string); 8 | 'message'?: (string); 9 | } 10 | 11 | export interface StreamMessage__Output { 12 | 'id'?: (number); 13 | 'senderName'?: (string); 14 | 'senderAvatar'?: (string); 15 | 'message'?: (string); 16 | } 17 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /proto/randomPackage/TodoResponse.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | import type { TodoRequest as _randomPackage_TodoRequest, TodoRequest__Output as _randomPackage_TodoRequest__Output } from '../randomPackage/TodoRequest'; 4 | 5 | export interface TodoResponse { 6 | 'todos'?: (_randomPackage_TodoRequest)[]; 7 | } 8 | 9 | export interface TodoResponse__Output { 10 | 'todos'?: (_randomPackage_TodoRequest__Output)[]; 11 | } 12 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | envoy: 4 | image: envoyproxy/envoy-dev:e4955aed5694f9935d674419dbb364e744f697b4 5 | volumes: 6 | - ./envoy.yaml:/etc/envoy/envoy.yaml 7 | ports: 8 | - "9901:9901" 9 | - "8080:8080" 10 | redis: 11 | image: bitnami/redis 12 | volumes: 13 | - ./data:/bitnami/redis/data 14 | environment: 15 | - ALLOW_EMPTY_PASSWORD=yes 16 | ports: 17 | - "6379:6379" 18 | -------------------------------------------------------------------------------- /proto/randomPackage/User.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | import type { Status as _randomPackage_Status } from '../randomPackage/Status'; 4 | 5 | export interface User { 6 | 'id'?: (number); 7 | 'name'?: (string); 8 | 'status'?: (_randomPackage_Status | keyof typeof _randomPackage_Status); 9 | 'avatar'?: (string); 10 | } 11 | 12 | export interface User__Output { 13 | 'id'?: (number); 14 | 'name'?: (string); 15 | 'status'?: (_randomPackage_Status); 16 | 'avatar'?: (string); 17 | } 18 | -------------------------------------------------------------------------------- /client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-grpc", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "proto:gen": "./proto-gen.sh", 8 | "start": "ts-node server", 9 | "client": "cd client && yarn start" 10 | }, 11 | "devDependencies": { 12 | "@grpc/grpc-js": "^1.3.2", 13 | "@grpc/proto-loader": "^0.6.2", 14 | "@types/node-redis-pubsub": "^3.0.0", 15 | "@types/redis": "^2.8.30", 16 | "ts-node": "^10.0.0", 17 | "typescript": "^4.3.2" 18 | }, 19 | "dependencies": { 20 | "node-redis-pubsub": "^5.0.0", 21 | "redis": "^3.1.2" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React gRPC Chat Application 2 | 3 | This is an example of a chat application using gRPC, React, Envoy and Redis. Right now this only supports one chat room and implementing direct chat messages is easy but requires some extra work that I am not willing to do right now. If you want to contribute I do not mind! 4 | 5 | There is a youtube video series where I go over making this application if intertested [here](https://youtu.be/NFZbTy_B4H0) 6 | 7 | ## General high level design of this application 8 | 9 | ![alt text](./architecture-diagram.png) 10 | 11 | ## Things you need to run this application 12 | 13 | 1. Node npm/yarn 14 | 2. Docker 15 | 3. protoc 16 | 17 | ## Project setup 18 | 19 | ``` 20 | docker compose up -d 21 | yarn install 22 | yarn proto:gen 23 | yarn start 24 | cd client && yarn install 25 | yarn start 26 | ``` 27 | -------------------------------------------------------------------------------- /client/src/components/style.css: -------------------------------------------------------------------------------- 1 | .speech-bubble { 2 | filter: drop-shadow(-1px -1px 2px rgba(0, 0, 0, 0.1)) 3 | drop-shadow(1px 2px 2px rgba(0, 0, 0, 0.15)); 4 | max-width: 60%; 5 | margin-left: 10px; 6 | padding: 1rem 2rem; 7 | position: relative; 8 | font-family: "Source Sans Pro", sans-serif; 9 | font-size: 1.2rem; 10 | font-weight: 400; 11 | background: #8ca8d8; 12 | color: white; 13 | } 14 | 15 | .speech-bubble p { 16 | text-align: left; 17 | margin-top: 5px; 18 | margin-bottom: 10px; 19 | } 20 | 21 | .speech-bubble cite { 22 | position: absolute; 23 | bottom: 0.5rem; 24 | left: 1rem; 25 | font-size: 0.8rem; 26 | font-style: italic; 27 | font-weight: 600; 28 | letter-spacing: 0.5px; 29 | color: white; 30 | max-width: 100px; 31 | text-overflow: ellipsis; 32 | white-space: nowrap; 33 | overflow: hidden; 34 | } 35 | -------------------------------------------------------------------------------- /pubsub.ts: -------------------------------------------------------------------------------- 1 | import { nrp } from "./data"; 2 | import { StreamMessage } from "./proto/randomPackage/StreamMessage"; 3 | import { User } from "./proto/randomPackage/User"; 4 | 5 | const REDIS_CHANNELS = { 6 | mainRoom: "MAIN_ROOM", 7 | userChange: "USER_CHAHNGE", 8 | }; 9 | 10 | const emitMainRoomChatUpdate = (msg: StreamMessage) => 11 | nrp.emit(REDIS_CHANNELS.mainRoom, JSON.stringify(msg)); 12 | 13 | const listenMainRoomChatUpdate = ( 14 | fn: (data: string, channel: string) => void 15 | ) => nrp.on(REDIS_CHANNELS.mainRoom, fn); 16 | 17 | const emitUserUpdateEvent = (user: User) => 18 | nrp.emit(REDIS_CHANNELS.userChange, JSON.stringify(user)); 19 | 20 | const listenUserUpdateEvent = (fn: (data: string, channel: string) => void) => 21 | nrp.on(REDIS_CHANNELS.userChange, fn); 22 | 23 | export { 24 | emitMainRoomChatUpdate, 25 | listenMainRoomChatUpdate, 26 | emitUserUpdateEvent, 27 | listenUserUpdateEvent, 28 | }; 29 | -------------------------------------------------------------------------------- /client/src/components/ChatBubble.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Grid from "@material-ui/core/Grid"; 3 | import "./style.css"; 4 | import { StreamMessage } from "../proto/random_pb"; 5 | 6 | interface Props { 7 | message: StreamMessage.AsObject; 8 | isCurrentUser: boolean; 9 | } 10 | 11 | const ChatBubble: React.FC = ({ message, isCurrentUser }) => { 12 | const { senderName, message: text } = message; 13 | 14 | return ( 15 | 23 |
27 |

{text}

28 | {!isCurrentUser && {senderName}} 29 |
30 |
31 | ); 32 | }; 33 | 34 | export default ChatBubble; 35 | -------------------------------------------------------------------------------- /proto/random.ts: -------------------------------------------------------------------------------- 1 | import type * as grpc from '@grpc/grpc-js'; 2 | import type { ServiceDefinition, EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; 3 | 4 | import type { RandomClient as _randomPackage_RandomClient, RandomDefinition as _randomPackage_RandomDefinition } from './randomPackage/Random'; 5 | 6 | type SubtypeConstructor any, Subtype> = { 7 | new(...args: ConstructorParameters): Subtype; 8 | }; 9 | 10 | export interface ProtoGrpcType { 11 | google: { 12 | protobuf: { 13 | Empty: MessageTypeDefinition 14 | } 15 | } 16 | randomPackage: { 17 | InitiateRequest: MessageTypeDefinition 18 | InitiateResponse: MessageTypeDefinition 19 | MessageRequest: MessageTypeDefinition 20 | Random: SubtypeConstructor & { service: _randomPackage_RandomDefinition } 21 | Status: EnumTypeDefinition 22 | StreamMessage: MessageTypeDefinition 23 | StreamRequest: MessageTypeDefinition 24 | User: MessageTypeDefinition 25 | UserStreamResponse: MessageTypeDefinition 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /proto/random.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | import "google/protobuf/empty.proto"; 3 | 4 | package randomPackage; 5 | 6 | service Random { 7 | rpc ChatInitiate(InitiateRequest) returns (InitiateResponse) {}; 8 | rpc SendMessage(MessageRequest) returns (google.protobuf.Empty) {}; 9 | rpc UserStream(StreamRequest) returns (stream UserStreamResponse) {}; 10 | rpc ChatStream(StreamRequest) returns (stream StreamMessage) {}; 11 | } 12 | 13 | message InitiateRequest { 14 | string name = 1; 15 | string avatar_url = 2; 16 | } 17 | 18 | message InitiateResponse { 19 | int32 id = 1; 20 | } 21 | 22 | message MessageRequest { 23 | int32 id = 1; 24 | string message = 2; 25 | } 26 | 27 | enum Status { 28 | UNKOWN = 0; 29 | ONLINE = 1; 30 | OFFLINE = 2; 31 | } 32 | 33 | message User { 34 | int32 id = 1; 35 | string name = 2; 36 | Status status = 3; 37 | string avatar = 4; 38 | } 39 | 40 | message UserStreamResponse { 41 | repeated User users = 1; 42 | } 43 | 44 | 45 | message StreamRequest { 46 | int32 id = 1; 47 | } 48 | 49 | message StreamMessage { 50 | int32 id = 1; 51 | string sender_name = 2; 52 | string sender_avatar = 3; 53 | string message = 4; 54 | } 55 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^4.11.4", 7 | "@material-ui/icons": "^4.11.2", 8 | "@testing-library/jest-dom": "^5.11.4", 9 | "@testing-library/react": "^11.1.0", 10 | "@testing-library/user-event": "^12.1.10", 11 | "@types/jest": "^26.0.15", 12 | "@types/node": "^12.0.0", 13 | "@types/react": "^17.0.0", 14 | "@types/react-dom": "^17.0.0", 15 | "google-protobuf": "^3.17.3", 16 | "grpc-web": "^1.2.1", 17 | "react": "^17.0.2", 18 | "react-dom": "^17.0.2", 19 | "react-scripts": "4.0.3", 20 | "typescript": "^4.1.2", 21 | "web-vitals": "^1.0.1" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build": "react-scripts build", 26 | "test": "react-scripts test", 27 | "eject": "react-scripts eject" 28 | }, 29 | "eslintConfig": { 30 | "extends": [ 31 | "react-app", 32 | "react-app/jest" 33 | ] 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.2%", 38 | "not dead", 39 | "not op_mini all" 40 | ], 41 | "development": [ 42 | "last 1 chrome version", 43 | "last 1 firefox version", 44 | "last 1 safari version" 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /client/src/components/UserList.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Card from "@material-ui/core/Card"; 3 | import { Avatar, Typography, Chip, Grid } from "@material-ui/core"; 4 | 5 | interface IUser { 6 | id: number; 7 | name: string; 8 | isOnline: boolean; 9 | avatar: string; 10 | } 11 | interface Props { 12 | users: Array; 13 | } 14 | 15 | const style: { [key: string]: React.CSSProperties } = { 16 | card: { 17 | height: "80px", 18 | width: "100%", 19 | backgroundColor: "aliceblue", 20 | display: "flex", 21 | alignItems: "center", 22 | marginBottom: "10px", 23 | }, 24 | avatar: { 25 | margin: "20px", 26 | }, 27 | }; 28 | 29 | const UserList: React.FC = (props) => { 30 | const { users } = props; 31 | 32 | return ( 33 | <> 34 | {users.map((u) => ( 35 | 36 | 37 | 43 | {u.name} 44 | 50 | 51 | 52 | ))} 53 | 54 | ); 55 | }; 56 | 57 | export default UserList; 58 | -------------------------------------------------------------------------------- /data/appendonly.aof: -------------------------------------------------------------------------------- 1 | *2 2 | $6 3 | SELECT 4 | $1 5 | 0 6 | *3 7 | $5 8 | rpush 9 | $5 10 | users 11 | $94 12 | {"id":6586798,"name":"john doe","avatar":"https://picsum.photos/id/1084/4579/3271","status":1} 13 | *4 14 | $4 15 | lset 16 | $5 17 | users 18 | $1 19 | 0 20 | $94 21 | {"id":6586798,"name":"john doe","avatar":"https://picsum.photos/id/1084/4579/3271","status":1} 22 | *4 23 | $4 24 | lset 25 | $5 26 | users 27 | $1 28 | 0 29 | $94 30 | {"id":6586798,"name":"john doe","avatar":"https://picsum.photos/id/1084/4579/3271","status":1} 31 | *3 32 | $5 33 | rpush 34 | $5 35 | users 36 | $93 37 | {"id":8318436,"name":"tdotcode","avatar":"https://picsum.photos/id/114/3264/2448","status":1} 38 | *4 39 | $4 40 | lset 41 | $5 42 | users 43 | $1 44 | 1 45 | $93 46 | {"id":8318436,"name":"tdotcode","avatar":"https://picsum.photos/id/114/3264/2448","status":1} 47 | *4 48 | $4 49 | lset 50 | $5 51 | users 52 | $1 53 | 1 54 | $93 55 | {"id":8318436,"name":"tdotcode","avatar":"https://picsum.photos/id/114/3264/2448","status":1} 56 | *3 57 | $5 58 | rpush 59 | $15 60 | room:0:messages 61 | $126 62 | {"id":6586798,"senderName":"john doe","senderAvatar":"https://picsum.photos/id/1084/4579/3271","message":"Hi my name is john"} 63 | *3 64 | $5 65 | rpush 66 | $15 67 | room:0:messages 68 | $119 69 | {"id":8318436,"senderName":"tdotcode","senderAvatar":"https://picsum.photos/id/114/3264/2448","message":"Hey whatsup?"} 70 | *4 71 | $4 72 | lset 73 | $5 74 | users 75 | $1 76 | 1 77 | $93 78 | {"id":8318436,"name":"tdotcode","avatar":"https://picsum.photos/id/114/3264/2448","status":2} 79 | *4 80 | $4 81 | lset 82 | $5 83 | users 84 | $1 85 | 0 86 | $94 87 | {"id":6586798,"name":"john doe","avatar":"https://picsum.photos/id/1084/4579/3271","status":2} 88 | -------------------------------------------------------------------------------- /client/src/components/ImageGallery.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import Dialog from "@material-ui/core/Dialog"; 3 | import DialogContent from "@material-ui/core/DialogContent"; 4 | import GridList from "@material-ui/core/GridList"; 5 | import GridListTile from "@material-ui/core/GridListTile"; 6 | import DialogTitle from "@material-ui/core/DialogTitle"; 7 | 8 | type Images = { id: string; download_url: string }; 9 | 10 | interface Props { 11 | isOpen: boolean; 12 | onImageSelect: (img: string) => void; 13 | } 14 | 15 | const ImageGalleryDialog: React.FC = (props) => { 16 | const [images, setImages] = useState>([]); 17 | const { isOpen, onImageSelect } = props; 18 | 19 | useEffect(() => { 20 | fetch( 21 | `https://picsum.photos/v2/list?limit=18&page=${Math.floor( 22 | Math.random() * 10 23 | )}` 24 | ) 25 | .then((res) => res.json()) 26 | .then((data) => { 27 | setImages(data); 28 | }); 29 | }, []); 30 | 31 | return ( 32 | 33 | 34 | {"Select your image avatar"} 35 | 36 | 37 | 38 | {images.map((img) => ( 39 | onImageSelect(img.download_url)} 44 | > 45 | Display 46 | 47 | ))} 48 | 49 | 50 | 51 | ); 52 | }; 53 | 54 | export default ImageGalleryDialog; 55 | -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /data.ts: -------------------------------------------------------------------------------- 1 | import redis from "redis"; 2 | import NRP from "node-redis-pubsub"; 3 | import { StreamMessage } from "./proto/randomPackage/StreamMessage"; 4 | import { User } from "./proto/randomPackage/User"; 5 | 6 | const REDIST_KEYS = { 7 | broadcastRoom: "room:0:messages", 8 | users: "users", 9 | }; 10 | 11 | const client = redis.createClient(); 12 | 13 | client.on("error", console.error); 14 | client.on("connect", console.log); 15 | type errCB = (err: Error | null) => void; 16 | type replyCB = (err: Error | null, reply: T) => void; 17 | 18 | 19 | export const listMessagesFromMainRoom = ( 20 | done?: (data: Array) => void 21 | ) => { 22 | client.lrange(REDIST_KEYS.broadcastRoom, 0, -1, (err, reply) => { 23 | const msgs: Array = []; 24 | for (const res of reply) { 25 | msgs.push(JSON.parse(res)); 26 | } 27 | done && done(msgs); 28 | }); 29 | }; 30 | export const addChatToMainRoom = (msg: StreamMessage, fn: errCB) => { 31 | client.rpush(REDIST_KEYS.broadcastRoom, JSON.stringify(msg), fn); 32 | }; 33 | 34 | export const addUser = (user: User, fn: errCB) => { 35 | client.rpush(REDIST_KEYS.users, JSON.stringify(user), fn); 36 | }; 37 | export const listUsers = (fn: replyCB) => { 38 | client.lrange(REDIST_KEYS.users, 0, -1, (err, reply) => { 39 | if (err) return fn(err, []); 40 | const users: Array = []; 41 | for (const r of reply) { 42 | users.push(JSON.parse(r)); 43 | } 44 | fn(null, users); 45 | }); 46 | }; 47 | 48 | export const findUser = (userId: number, fn: replyCB) => { 49 | listUsers((err, users) => { 50 | if(err) return fn(err, {} as User) 51 | const i = users.findIndex((e) => e.id === userId) 52 | fn(null, users[i]) 53 | }) 54 | } 55 | 56 | export const updateUser = (user: User, fn: errCB) => { 57 | listUsers((err, users) => { 58 | if(err) return fn(err) 59 | const i = users.findIndex((e) => e.id === user.id) 60 | if(i === -1) return fn(Error('cannot find user')) 61 | client.lset(REDIST_KEYS.users, i, JSON.stringify(user), fn) 62 | }) 63 | } 64 | 65 | export default client; 66 | export const nrp = NRP({ 67 | emitter: redis.createClient(), 68 | receiver: redis.createClient(), 69 | }); 70 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `yarn start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `yarn test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `yarn build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `yarn eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | -------------------------------------------------------------------------------- /envoy.yaml: -------------------------------------------------------------------------------- 1 | admin: 2 | access_log_path: /tmp/admin_access.log 3 | address: 4 | socket_address: { address: 0.0.0.0, port_value: 9901 } 5 | 6 | static_resources: 7 | listeners: 8 | - name: listener_0 9 | address: 10 | socket_address: { address: 0.0.0.0, port_value: 8080 } 11 | filter_chains: 12 | - filters: 13 | - name: envoy.filters.network.http_connection_manager 14 | typed_config: 15 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager 16 | codec_type: auto 17 | stat_prefix: ingress_http 18 | route_config: 19 | name: local_route 20 | virtual_hosts: 21 | - name: local_service 22 | domains: ["*"] 23 | routes: 24 | - match: { prefix: "/" } 25 | route: 26 | cluster: echo_service 27 | timeout: 0s 28 | max_stream_duration: 29 | grpc_timeout_header_max: 0s 30 | cors: 31 | allow_origin_string_match: 32 | - prefix: "*" 33 | allow_methods: GET, PUT, DELETE, POST, OPTIONS 34 | allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout 35 | max_age: "1728000" 36 | expose_headers: custom-header-1,grpc-status,grpc-message 37 | http_filters: 38 | - name: envoy.filters.http.grpc_web 39 | - name: envoy.filters.http.cors 40 | - name: envoy.filters.http.router 41 | clusters: 42 | - name: echo_service 43 | connect_timeout: 0.25s 44 | type: logical_dns 45 | http2_protocol_options: {} 46 | lb_policy: round_robin 47 | load_assignment: 48 | cluster_name: echo_service 49 | endpoints: 50 | - lb_endpoints: 51 | - endpoint: 52 | address: 53 | socket_address: 54 | address: host.docker.internal 55 | port_value: 9090 56 | -------------------------------------------------------------------------------- /client/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import "./App.css"; 3 | import { RandomClient } from "./proto/RandomServiceClientPb"; 4 | import { 5 | StreamRequest, 6 | InitiateRequest, 7 | StreamMessage, 8 | UserStreamResponse, 9 | User, 10 | MessageRequest, 11 | } from "./proto/random_pb"; 12 | import Greeting from "./components/Greeting"; 13 | import Chat from "./components/Chat"; 14 | 15 | export const client = new RandomClient("http://localhost:8080"); 16 | 17 | export type Session = { id: number; name: string; avatar: string }; 18 | 19 | function App() { 20 | const [user, setUser] = useState(); 21 | const [messages, setMessages] = useState>([]); 22 | const [userList, setUserList] = useState>([]); 23 | 24 | const handleEnterChat = (name: string, avatar: string) => { 25 | const intiateReq = new InitiateRequest(); 26 | intiateReq.setName(name); 27 | intiateReq.setAvatarUrl(avatar); 28 | client.chatInitiate(intiateReq, {}, (err, resp) => { 29 | if (err) throw err; 30 | const id = resp.getId(); 31 | setUser({ id, name, avatar }); 32 | }); 33 | }; 34 | 35 | const handleSendMessage = (msg: string, onSuccess: () => void) => { 36 | console.log(user, !user); 37 | if (!user) return; 38 | const req = new MessageRequest(); 39 | req.setId(user.id); 40 | req.setMessage(msg); 41 | console.log("here we go"); 42 | client.sendMessage(req, {}, (err, resp) => { 43 | if (err) throw err; 44 | onSuccess(); 45 | }); 46 | }; 47 | 48 | useEffect(() => { 49 | if (!user) return; 50 | 51 | const chatReq = new StreamRequest(); 52 | (() => { 53 | chatReq.setId(user.id); 54 | const chatStream = client.chatStream(chatReq); 55 | chatStream.on("data", (chunk) => { 56 | const msg = (chunk as StreamMessage).toObject(); 57 | console.log(msg); 58 | setMessages((prev) => [...prev, msg]); 59 | }); 60 | })(); 61 | 62 | (() => { 63 | const userListStream = client.userStream(chatReq); 64 | userListStream.on("data", (chunk) => { 65 | const { usersList } = (chunk as UserStreamResponse).toObject(); 66 | console.log(usersList); 67 | setUserList(usersList); 68 | }); 69 | })(); 70 | }, [user]); 71 | 72 | return ( 73 |
74 | {user ? ( 75 | 81 | ) : ( 82 | 83 | )} 84 |
85 | ); 86 | } 87 | 88 | export default App; 89 | -------------------------------------------------------------------------------- /client/src/components/Greeting.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import Paper from "@material-ui/core/Paper"; 3 | import Typopgraphy from "@material-ui/core/Typography"; 4 | import TextField from "@material-ui/core/TextField"; 5 | import Avatar from "@material-ui/core/Avatar"; 6 | import { IconButton, Tooltip } from "@material-ui/core"; 7 | import ImageGalleryDialog from "./ImageGallery"; 8 | 9 | const style: { [key: string]: React.CSSProperties } = { 10 | paper: { 11 | height: "30vh", 12 | width: "30%", 13 | backgroundColor: "lightslategrey", 14 | color: "white", 15 | display: "flex", 16 | justifyContent: "center", 17 | alignItems: "center", 18 | padding: "20px", 19 | }, 20 | input: { 21 | marginTop: "50px", 22 | width: "50%", 23 | color: "white", 24 | }, 25 | form: { 26 | display: "flex", 27 | flexDirection: "column", 28 | alignItems: "center", 29 | }, 30 | avatar: { 31 | height: 80, 32 | width: 80, 33 | margin: "2rem 0rem", 34 | }, 35 | }; 36 | 37 | interface Props { 38 | onUsernameEnter: (name: string, avatar: string) => void; 39 | } 40 | 41 | const Greeting: React.FC = (props) => { 42 | const [name, setName] = useState(""); 43 | const [img, setImage] = useState(""); 44 | const [open, setOpen] = useState(false); 45 | const { onUsernameEnter } = props; 46 | 47 | const handleSubmit = (e: React.FormEvent) => { 48 | e.preventDefault(); 49 | if (!name && !img) return; 50 | onUsernameEnter(name, img); 51 | }; 52 | 53 | const handleImageSelect = (imgURL: string) => { 54 | if (!imgURL) return; 55 | setImage(imgURL); 56 | setOpen(false); 57 | }; 58 | 59 | return ( 60 | <> 61 | 62 |
63 | 64 | Please enter your name before joining the chat 65 | 66 | setOpen((prev) => !prev)} 69 | > 70 | 71 | 72 | 73 | 74 | setName(e.target.value)} 79 | InputLabelProps={{ 80 | style: { 81 | color: "white", 82 | }, 83 | }} 84 | InputProps={{ 85 | style: { 86 | color: "white", 87 | }, 88 | }} 89 | /> 90 | 91 |
92 | 93 | 94 | ); 95 | }; 96 | 97 | export default Greeting; 98 | -------------------------------------------------------------------------------- /client/src/components/Chat.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { 3 | Divider, 4 | Grid, 5 | Paper, 6 | Typography, 7 | Avatar, 8 | TextField, 9 | Chip, 10 | } from "@material-ui/core"; 11 | import InputAdornment from "@material-ui/core/InputAdornment"; 12 | import SendIcon from "@material-ui/icons/Send"; 13 | import UserList from "./UserList"; 14 | import ChatBubble from "./ChatBubble"; 15 | import { Status, StreamMessage, User } from "../proto/random_pb"; 16 | import { Session } from "../App"; 17 | 18 | const style: { [key: string]: React.CSSProperties } = { 19 | container: { 20 | height: "80vh", 21 | padding: "2rem", 22 | width: "85vw", 23 | }, 24 | paper: { 25 | padding: "30px", 26 | height: "100%", 27 | display: "flex", 28 | flexDirection: "column", 29 | alignItems: "start", 30 | backgroundColor: "lightslategrey", 31 | }, 32 | avatar: { 33 | margin: "20px", 34 | }, 35 | }; 36 | 37 | interface Props { 38 | user: Session; 39 | userList: Array; 40 | messages: Array; 41 | onMessageSubmit: (msg: string, onSuccess: () => void) => void; 42 | } 43 | 44 | const Chat: React.FC = (props) => { 45 | const [msg, setMsg] = useState(""); 46 | const { userList, messages, onMessageSubmit, user } = props; 47 | 48 | const handleSendMessage = (e: React.FormEvent) => { 49 | console.log("called"); 50 | e.preventDefault(); 51 | if (!msg) return; 52 | console.log("here ", msg); 53 | onMessageSubmit(msg, () => setMsg("")); 54 | }; 55 | 56 | return ( 57 |
58 | 59 | 60 | 61 | ({ 63 | ...x, 64 | isOnline: x.status === Status.ONLINE, 65 | }))} 66 | /> 67 | 68 | 69 | 70 | 71 |
80 | {/* {name banner} */} 81 |
88 | 89 | 95 | {user.name} 96 | 102 | 103 |
104 | 105 |
106 | {messages.map((msg, i) => ( 107 | 112 | ))} 113 |
114 | 115 |
118 | setMsg(e.target.value)} 124 | InputProps={{ 125 | endAdornment: ( 126 | 127 | 128 | 129 | ), 130 | }} 131 | /> 132 |
133 |
134 |
135 |
136 |
137 |
138 | ); 139 | }; 140 | 141 | export default Chat; 142 | -------------------------------------------------------------------------------- /client/src/proto/RandomServiceClientPb.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview gRPC-Web generated client stub for randomPackage 3 | * @enhanceable 4 | * @public 5 | */ 6 | 7 | // GENERATED CODE -- DO NOT EDIT! 8 | 9 | 10 | /* eslint-disable */ 11 | // @ts-nocheck 12 | 13 | 14 | import * as grpcWeb from 'grpc-web'; 15 | 16 | import * as google_protobuf_empty_pb from 'google-protobuf/google/protobuf/empty_pb'; 17 | import * as proto_random_pb from '../proto/random_pb'; 18 | 19 | 20 | export class RandomClient { 21 | client_: grpcWeb.AbstractClientBase; 22 | hostname_: string; 23 | credentials_: null | { [index: string]: string; }; 24 | options_: null | { [index: string]: any; }; 25 | 26 | constructor (hostname: string, 27 | credentials?: null | { [index: string]: string; }, 28 | options?: null | { [index: string]: any; }) { 29 | if (!options) options = {}; 30 | if (!credentials) credentials = {}; 31 | options['format'] = 'text'; 32 | 33 | this.client_ = new grpcWeb.GrpcWebClientBase(options); 34 | this.hostname_ = hostname; 35 | this.credentials_ = credentials; 36 | this.options_ = options; 37 | } 38 | 39 | methodInfoChatInitiate = new grpcWeb.AbstractClientBase.MethodInfo( 40 | proto_random_pb.InitiateResponse, 41 | (request: proto_random_pb.InitiateRequest) => { 42 | return request.serializeBinary(); 43 | }, 44 | proto_random_pb.InitiateResponse.deserializeBinary 45 | ); 46 | 47 | chatInitiate( 48 | request: proto_random_pb.InitiateRequest, 49 | metadata: grpcWeb.Metadata | null): Promise; 50 | 51 | chatInitiate( 52 | request: proto_random_pb.InitiateRequest, 53 | metadata: grpcWeb.Metadata | null, 54 | callback: (err: grpcWeb.Error, 55 | response: proto_random_pb.InitiateResponse) => void): grpcWeb.ClientReadableStream; 56 | 57 | chatInitiate( 58 | request: proto_random_pb.InitiateRequest, 59 | metadata: grpcWeb.Metadata | null, 60 | callback?: (err: grpcWeb.Error, 61 | response: proto_random_pb.InitiateResponse) => void) { 62 | if (callback !== undefined) { 63 | return this.client_.rpcCall( 64 | this.hostname_ + 65 | '/randomPackage.Random/ChatInitiate', 66 | request, 67 | metadata || {}, 68 | this.methodInfoChatInitiate, 69 | callback); 70 | } 71 | return this.client_.unaryCall( 72 | this.hostname_ + 73 | '/randomPackage.Random/ChatInitiate', 74 | request, 75 | metadata || {}, 76 | this.methodInfoChatInitiate); 77 | } 78 | 79 | methodInfoSendMessage = new grpcWeb.AbstractClientBase.MethodInfo( 80 | google_protobuf_empty_pb.Empty, 81 | (request: proto_random_pb.MessageRequest) => { 82 | return request.serializeBinary(); 83 | }, 84 | google_protobuf_empty_pb.Empty.deserializeBinary 85 | ); 86 | 87 | sendMessage( 88 | request: proto_random_pb.MessageRequest, 89 | metadata: grpcWeb.Metadata | null): Promise; 90 | 91 | sendMessage( 92 | request: proto_random_pb.MessageRequest, 93 | metadata: grpcWeb.Metadata | null, 94 | callback: (err: grpcWeb.Error, 95 | response: google_protobuf_empty_pb.Empty) => void): grpcWeb.ClientReadableStream; 96 | 97 | sendMessage( 98 | request: proto_random_pb.MessageRequest, 99 | metadata: grpcWeb.Metadata | null, 100 | callback?: (err: grpcWeb.Error, 101 | response: google_protobuf_empty_pb.Empty) => void) { 102 | if (callback !== undefined) { 103 | return this.client_.rpcCall( 104 | this.hostname_ + 105 | '/randomPackage.Random/SendMessage', 106 | request, 107 | metadata || {}, 108 | this.methodInfoSendMessage, 109 | callback); 110 | } 111 | return this.client_.unaryCall( 112 | this.hostname_ + 113 | '/randomPackage.Random/SendMessage', 114 | request, 115 | metadata || {}, 116 | this.methodInfoSendMessage); 117 | } 118 | 119 | methodInfoUserStream = new grpcWeb.AbstractClientBase.MethodInfo( 120 | proto_random_pb.UserStreamResponse, 121 | (request: proto_random_pb.StreamRequest) => { 122 | return request.serializeBinary(); 123 | }, 124 | proto_random_pb.UserStreamResponse.deserializeBinary 125 | ); 126 | 127 | userStream( 128 | request: proto_random_pb.StreamRequest, 129 | metadata?: grpcWeb.Metadata) { 130 | return this.client_.serverStreaming( 131 | this.hostname_ + 132 | '/randomPackage.Random/UserStream', 133 | request, 134 | metadata || {}, 135 | this.methodInfoUserStream); 136 | } 137 | 138 | methodInfoChatStream = new grpcWeb.AbstractClientBase.MethodInfo( 139 | proto_random_pb.StreamMessage, 140 | (request: proto_random_pb.StreamRequest) => { 141 | return request.serializeBinary(); 142 | }, 143 | proto_random_pb.StreamMessage.deserializeBinary 144 | ); 145 | 146 | chatStream( 147 | request: proto_random_pb.StreamRequest, 148 | metadata?: grpcWeb.Metadata) { 149 | return this.client_.serverStreaming( 150 | this.hostname_ + 151 | '/randomPackage.Random/ChatStream', 152 | request, 153 | metadata || {}, 154 | this.methodInfoChatStream); 155 | } 156 | 157 | } 158 | 159 | -------------------------------------------------------------------------------- /server.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import * as grpc from "@grpc/grpc-js"; 3 | import * as protoLoader from "@grpc/proto-loader"; 4 | import { ProtoGrpcType } from "./proto/random"; 5 | import { RandomHandlers } from "./proto/randomPackage/Random"; 6 | import { StreamMessage } from "./proto/randomPackage/StreamMessage"; 7 | import { ChatConnectRequest } from "./proto/randomPackage/ChatConnectRequest"; 8 | import { UserStreamResponse } from "./proto/randomPackage/UserStreamResponse"; 9 | import { User } from "./proto/randomPackage/User"; 10 | import { 11 | addUser, 12 | listUsers, 13 | listMessagesFromMainRoom, 14 | addChatToMainRoom, 15 | findUser, 16 | updateUser, 17 | } from "./data"; 18 | import { 19 | emitMainRoomChatUpdate, 20 | emitUserUpdateEvent, 21 | listenMainRoomChatUpdate, 22 | listenUserUpdateEvent, 23 | } from "./pubsub"; 24 | import { Status } from "./proto/randomPackage/Status"; 25 | 26 | const PORT = 9090; 27 | const PROTO_FILE = "./proto/random.proto"; 28 | 29 | const packageDef = protoLoader.loadSync(path.resolve(__dirname, PROTO_FILE)); 30 | const grpcObj = grpc.loadPackageDefinition( 31 | packageDef 32 | ) as unknown as ProtoGrpcType; 33 | const randomPackage = grpcObj.randomPackage; 34 | 35 | function main() { 36 | const server = getServer(); 37 | server.bindAsync( 38 | `0.0.0.0:${PORT}`, 39 | grpc.ServerCredentials.createInsecure(), 40 | (err, port) => { 41 | if (err) { 42 | console.error(err); 43 | return; 44 | } 45 | console.log(`Your server as started on port ${port}`); 46 | server.start(); 47 | } 48 | ); 49 | runStreams(); 50 | } 51 | 52 | const userIdToMsgStream = new Map< 53 | number, 54 | grpc.ServerWritableStream 55 | >(); 56 | const userIdToUserListStream = new Map< 57 | number, 58 | grpc.ServerWritableStream 59 | >(); 60 | function getServer() { 61 | const server = new grpc.Server(); 62 | server.addService(randomPackage.Random.service, { 63 | ChatInitiate: (call, callback) => { 64 | const sessionName = (call.request.name || "").trim().toLowerCase(); 65 | const avatar = call.request.avatarUrl || ""; 66 | if (!sessionName || !avatar) 67 | callback(new Error("Name/Avatar is required")); 68 | listUsers((err, users) => { 69 | if (err) return callback(err); 70 | let idx = users.findIndex((u) => u?.name?.toLowerCase() === sessionName); 71 | if (idx !== -1 && users[idx].status === Status.ONLINE) 72 | return callback(new Error("User with name already exist")); 73 | if (idx !== -1) { 74 | const user = users[idx]; 75 | updateUser(user, console.error); 76 | return callback(null, { id: user.id }); 77 | } else { 78 | const user: User = { 79 | id: idx === -1 ? Math.floor(Math.random() * 10000000) : idx, 80 | name: sessionName, 81 | avatar, 82 | status: Status.ONLINE, 83 | }; 84 | addUser(user, console.error); 85 | return callback(null, { id: user.id }); 86 | } 87 | }); 88 | }, 89 | ChatStream: (call) => { 90 | const { id = 0 } = call.request; 91 | findUser(id, (err, user) => { 92 | if (err) return call.end(); 93 | const {id: userId = 0} = user 94 | user.status = Status.ONLINE; 95 | updateUser(user, console.error); 96 | listMessagesFromMainRoom((msgs) => { 97 | userIdToMsgStream.set(userId, call); 98 | for (const msg of msgs) { 99 | call.write(msg); 100 | } 101 | }); 102 | 103 | call.on("cancelled", () => { 104 | userIdToMsgStream.delete(id); 105 | }); 106 | }); 107 | }, 108 | SendMessage: (call, callback) => { 109 | const { id = 0, message = "" } = call.request; 110 | if (!id) return callback(new Error("not valid id")); 111 | if (!message) return callback(new Error("no message")); 112 | 113 | findUser(id, (err, user) => { 114 | if (err) return callback(null, err); 115 | const msg: StreamMessage = { 116 | id, 117 | senderName: user.name, 118 | senderAvatar: user.avatar, 119 | message, 120 | }; 121 | addChatToMainRoom(msg, (err) => { 122 | if (err) callback(null, err); 123 | emitMainRoomChatUpdate(msg); 124 | callback(null); 125 | }); 126 | }); 127 | }, 128 | UserStream: (call) => { 129 | const { id = 0 } = call.request; 130 | if (!id) return call.end(); 131 | findUser(id, (err, user) => { 132 | const {id: userId = 0} = user 133 | if (err) return call.end(); 134 | user.status = Status.ONLINE; 135 | updateUser(user, () => { 136 | if(err) throw err 137 | listUsers((err, users) => { 138 | if (err) throw err; 139 | userIdToUserListStream.set(userId, call); 140 | for (const [, stream] of userIdToUserListStream) { 141 | stream.write({ users }); 142 | } 143 | }); 144 | }); 145 | 146 | call.on("cancelled", () => { 147 | userIdToUserListStream.delete(id) 148 | user.status = Status.OFFLINE; 149 | updateUser(user, (err) => { 150 | if(err) throw err 151 | emitUserUpdateEvent(user) 152 | }); 153 | 154 | }); 155 | }); 156 | }, 157 | } as RandomHandlers); 158 | 159 | return server; 160 | } 161 | 162 | function runStreams() { 163 | listenMainRoomChatUpdate((data, channel) => { 164 | const msg = JSON.parse(data) as StreamMessage; 165 | for (const [, stream] of userIdToMsgStream) { 166 | stream.write(msg); 167 | } 168 | }); 169 | listenUserUpdateEvent(() => 170 | listUsers((err, users) => { 171 | if (err) throw err; 172 | for (const [, stream] of userIdToUserListStream) { 173 | stream.write({ users }); 174 | } 175 | }) 176 | ); 177 | } 178 | 179 | main(); 180 | -------------------------------------------------------------------------------- /client/src/proto/random_pb.d.ts: -------------------------------------------------------------------------------- 1 | import * as jspb from 'google-protobuf' 2 | 3 | import * as google_protobuf_empty_pb from 'google-protobuf/google/protobuf/empty_pb'; 4 | 5 | 6 | export class InitiateRequest extends jspb.Message { 7 | getName(): string; 8 | setName(value: string): InitiateRequest; 9 | 10 | getAvatarUrl(): string; 11 | setAvatarUrl(value: string): InitiateRequest; 12 | 13 | serializeBinary(): Uint8Array; 14 | toObject(includeInstance?: boolean): InitiateRequest.AsObject; 15 | static toObject(includeInstance: boolean, msg: InitiateRequest): InitiateRequest.AsObject; 16 | static serializeBinaryToWriter(message: InitiateRequest, writer: jspb.BinaryWriter): void; 17 | static deserializeBinary(bytes: Uint8Array): InitiateRequest; 18 | static deserializeBinaryFromReader(message: InitiateRequest, reader: jspb.BinaryReader): InitiateRequest; 19 | } 20 | 21 | export namespace InitiateRequest { 22 | export type AsObject = { 23 | name: string, 24 | avatarUrl: string, 25 | } 26 | } 27 | 28 | export class InitiateResponse extends jspb.Message { 29 | getId(): number; 30 | setId(value: number): InitiateResponse; 31 | 32 | serializeBinary(): Uint8Array; 33 | toObject(includeInstance?: boolean): InitiateResponse.AsObject; 34 | static toObject(includeInstance: boolean, msg: InitiateResponse): InitiateResponse.AsObject; 35 | static serializeBinaryToWriter(message: InitiateResponse, writer: jspb.BinaryWriter): void; 36 | static deserializeBinary(bytes: Uint8Array): InitiateResponse; 37 | static deserializeBinaryFromReader(message: InitiateResponse, reader: jspb.BinaryReader): InitiateResponse; 38 | } 39 | 40 | export namespace InitiateResponse { 41 | export type AsObject = { 42 | id: number, 43 | } 44 | } 45 | 46 | export class MessageRequest extends jspb.Message { 47 | getId(): number; 48 | setId(value: number): MessageRequest; 49 | 50 | getMessage(): string; 51 | setMessage(value: string): MessageRequest; 52 | 53 | serializeBinary(): Uint8Array; 54 | toObject(includeInstance?: boolean): MessageRequest.AsObject; 55 | static toObject(includeInstance: boolean, msg: MessageRequest): MessageRequest.AsObject; 56 | static serializeBinaryToWriter(message: MessageRequest, writer: jspb.BinaryWriter): void; 57 | static deserializeBinary(bytes: Uint8Array): MessageRequest; 58 | static deserializeBinaryFromReader(message: MessageRequest, reader: jspb.BinaryReader): MessageRequest; 59 | } 60 | 61 | export namespace MessageRequest { 62 | export type AsObject = { 63 | id: number, 64 | message: string, 65 | } 66 | } 67 | 68 | export class User extends jspb.Message { 69 | getId(): number; 70 | setId(value: number): User; 71 | 72 | getName(): string; 73 | setName(value: string): User; 74 | 75 | getStatus(): Status; 76 | setStatus(value: Status): User; 77 | 78 | getAvatar(): string; 79 | setAvatar(value: string): User; 80 | 81 | serializeBinary(): Uint8Array; 82 | toObject(includeInstance?: boolean): User.AsObject; 83 | static toObject(includeInstance: boolean, msg: User): User.AsObject; 84 | static serializeBinaryToWriter(message: User, writer: jspb.BinaryWriter): void; 85 | static deserializeBinary(bytes: Uint8Array): User; 86 | static deserializeBinaryFromReader(message: User, reader: jspb.BinaryReader): User; 87 | } 88 | 89 | export namespace User { 90 | export type AsObject = { 91 | id: number, 92 | name: string, 93 | status: Status, 94 | avatar: string, 95 | } 96 | } 97 | 98 | export class UserStreamResponse extends jspb.Message { 99 | getUsersList(): Array; 100 | setUsersList(value: Array): UserStreamResponse; 101 | clearUsersList(): UserStreamResponse; 102 | addUsers(value?: User, index?: number): User; 103 | 104 | serializeBinary(): Uint8Array; 105 | toObject(includeInstance?: boolean): UserStreamResponse.AsObject; 106 | static toObject(includeInstance: boolean, msg: UserStreamResponse): UserStreamResponse.AsObject; 107 | static serializeBinaryToWriter(message: UserStreamResponse, writer: jspb.BinaryWriter): void; 108 | static deserializeBinary(bytes: Uint8Array): UserStreamResponse; 109 | static deserializeBinaryFromReader(message: UserStreamResponse, reader: jspb.BinaryReader): UserStreamResponse; 110 | } 111 | 112 | export namespace UserStreamResponse { 113 | export type AsObject = { 114 | usersList: Array, 115 | } 116 | } 117 | 118 | export class StreamRequest extends jspb.Message { 119 | getId(): number; 120 | setId(value: number): StreamRequest; 121 | 122 | serializeBinary(): Uint8Array; 123 | toObject(includeInstance?: boolean): StreamRequest.AsObject; 124 | static toObject(includeInstance: boolean, msg: StreamRequest): StreamRequest.AsObject; 125 | static serializeBinaryToWriter(message: StreamRequest, writer: jspb.BinaryWriter): void; 126 | static deserializeBinary(bytes: Uint8Array): StreamRequest; 127 | static deserializeBinaryFromReader(message: StreamRequest, reader: jspb.BinaryReader): StreamRequest; 128 | } 129 | 130 | export namespace StreamRequest { 131 | export type AsObject = { 132 | id: number, 133 | } 134 | } 135 | 136 | export class StreamMessage extends jspb.Message { 137 | getId(): number; 138 | setId(value: number): StreamMessage; 139 | 140 | getSenderName(): string; 141 | setSenderName(value: string): StreamMessage; 142 | 143 | getSenderAvatar(): string; 144 | setSenderAvatar(value: string): StreamMessage; 145 | 146 | getMessage(): string; 147 | setMessage(value: string): StreamMessage; 148 | 149 | serializeBinary(): Uint8Array; 150 | toObject(includeInstance?: boolean): StreamMessage.AsObject; 151 | static toObject(includeInstance: boolean, msg: StreamMessage): StreamMessage.AsObject; 152 | static serializeBinaryToWriter(message: StreamMessage, writer: jspb.BinaryWriter): void; 153 | static deserializeBinary(bytes: Uint8Array): StreamMessage; 154 | static deserializeBinaryFromReader(message: StreamMessage, reader: jspb.BinaryReader): StreamMessage; 155 | } 156 | 157 | export namespace StreamMessage { 158 | export type AsObject = { 159 | id: number, 160 | senderName: string, 161 | senderAvatar: string, 162 | message: string, 163 | } 164 | } 165 | 166 | export enum Status { 167 | UNKOWN = 0, 168 | ONLINE = 1, 169 | OFFLINE = 2, 170 | } 171 | -------------------------------------------------------------------------------- /proto/randomPackage/Random.ts: -------------------------------------------------------------------------------- 1 | // Original file: proto/random.proto 2 | 3 | import type * as grpc from '@grpc/grpc-js' 4 | import type { MethodDefinition } from '@grpc/proto-loader' 5 | import type { Empty as _google_protobuf_Empty, Empty__Output as _google_protobuf_Empty__Output } from '../google/protobuf/Empty'; 6 | import type { InitiateRequest as _randomPackage_InitiateRequest, InitiateRequest__Output as _randomPackage_InitiateRequest__Output } from '../randomPackage/InitiateRequest'; 7 | import type { InitiateResponse as _randomPackage_InitiateResponse, InitiateResponse__Output as _randomPackage_InitiateResponse__Output } from '../randomPackage/InitiateResponse'; 8 | import type { MessageRequest as _randomPackage_MessageRequest, MessageRequest__Output as _randomPackage_MessageRequest__Output } from '../randomPackage/MessageRequest'; 9 | import type { StreamMessage as _randomPackage_StreamMessage, StreamMessage__Output as _randomPackage_StreamMessage__Output } from '../randomPackage/StreamMessage'; 10 | import type { StreamRequest as _randomPackage_StreamRequest, StreamRequest__Output as _randomPackage_StreamRequest__Output } from '../randomPackage/StreamRequest'; 11 | import type { UserStreamResponse as _randomPackage_UserStreamResponse, UserStreamResponse__Output as _randomPackage_UserStreamResponse__Output } from '../randomPackage/UserStreamResponse'; 12 | 13 | export interface RandomClient extends grpc.Client { 14 | ChatInitiate(argument: _randomPackage_InitiateRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _randomPackage_InitiateResponse__Output) => void): grpc.ClientUnaryCall; 15 | ChatInitiate(argument: _randomPackage_InitiateRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _randomPackage_InitiateResponse__Output) => void): grpc.ClientUnaryCall; 16 | ChatInitiate(argument: _randomPackage_InitiateRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _randomPackage_InitiateResponse__Output) => void): grpc.ClientUnaryCall; 17 | ChatInitiate(argument: _randomPackage_InitiateRequest, callback: (error?: grpc.ServiceError, result?: _randomPackage_InitiateResponse__Output) => void): grpc.ClientUnaryCall; 18 | chatInitiate(argument: _randomPackage_InitiateRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _randomPackage_InitiateResponse__Output) => void): grpc.ClientUnaryCall; 19 | chatInitiate(argument: _randomPackage_InitiateRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _randomPackage_InitiateResponse__Output) => void): grpc.ClientUnaryCall; 20 | chatInitiate(argument: _randomPackage_InitiateRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _randomPackage_InitiateResponse__Output) => void): grpc.ClientUnaryCall; 21 | chatInitiate(argument: _randomPackage_InitiateRequest, callback: (error?: grpc.ServiceError, result?: _randomPackage_InitiateResponse__Output) => void): grpc.ClientUnaryCall; 22 | 23 | ChatStream(argument: _randomPackage_StreamRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_randomPackage_StreamMessage__Output>; 24 | ChatStream(argument: _randomPackage_StreamRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_randomPackage_StreamMessage__Output>; 25 | chatStream(argument: _randomPackage_StreamRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_randomPackage_StreamMessage__Output>; 26 | chatStream(argument: _randomPackage_StreamRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_randomPackage_StreamMessage__Output>; 27 | 28 | SendMessage(argument: _randomPackage_MessageRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; 29 | SendMessage(argument: _randomPackage_MessageRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; 30 | SendMessage(argument: _randomPackage_MessageRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; 31 | SendMessage(argument: _randomPackage_MessageRequest, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; 32 | sendMessage(argument: _randomPackage_MessageRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; 33 | sendMessage(argument: _randomPackage_MessageRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; 34 | sendMessage(argument: _randomPackage_MessageRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; 35 | sendMessage(argument: _randomPackage_MessageRequest, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; 36 | 37 | UserStream(argument: _randomPackage_StreamRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_randomPackage_UserStreamResponse__Output>; 38 | UserStream(argument: _randomPackage_StreamRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_randomPackage_UserStreamResponse__Output>; 39 | userStream(argument: _randomPackage_StreamRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_randomPackage_UserStreamResponse__Output>; 40 | userStream(argument: _randomPackage_StreamRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_randomPackage_UserStreamResponse__Output>; 41 | 42 | } 43 | 44 | export interface RandomHandlers extends grpc.UntypedServiceImplementation { 45 | ChatInitiate: grpc.handleUnaryCall<_randomPackage_InitiateRequest__Output, _randomPackage_InitiateResponse>; 46 | 47 | ChatStream: grpc.handleServerStreamingCall<_randomPackage_StreamRequest__Output, _randomPackage_StreamMessage>; 48 | 49 | SendMessage: grpc.handleUnaryCall<_randomPackage_MessageRequest__Output, _google_protobuf_Empty>; 50 | 51 | UserStream: grpc.handleServerStreamingCall<_randomPackage_StreamRequest__Output, _randomPackage_UserStreamResponse>; 52 | 53 | } 54 | 55 | export interface RandomDefinition extends grpc.ServiceDefinition { 56 | ChatInitiate: MethodDefinition<_randomPackage_InitiateRequest, _randomPackage_InitiateResponse, _randomPackage_InitiateRequest__Output, _randomPackage_InitiateResponse__Output> 57 | ChatStream: MethodDefinition<_randomPackage_StreamRequest, _randomPackage_StreamMessage, _randomPackage_StreamRequest__Output, _randomPackage_StreamMessage__Output> 58 | SendMessage: MethodDefinition<_randomPackage_MessageRequest, _google_protobuf_Empty, _randomPackage_MessageRequest__Output, _google_protobuf_Empty__Output> 59 | UserStream: MethodDefinition<_randomPackage_StreamRequest, _randomPackage_UserStreamResponse, _randomPackage_StreamRequest__Output, _randomPackage_UserStreamResponse__Output> 60 | } 61 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@grpc/grpc-js@^1.3.2": 6 | version "1.3.2" 7 | resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.3.2.tgz#eae97e6daf5abd49a7818aadeca0744dfb1ebca1" 8 | integrity sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA== 9 | dependencies: 10 | "@types/node" ">=12.12.47" 11 | 12 | "@grpc/proto-loader@^0.6.2": 13 | version "0.6.2" 14 | resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.2.tgz#412575f3ff5ef0a9b79d4ea12c08cba5601041cb" 15 | integrity sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg== 16 | dependencies: 17 | "@types/long" "^4.0.1" 18 | lodash.camelcase "^4.3.0" 19 | long "^4.0.0" 20 | protobufjs "^6.10.0" 21 | yargs "^16.1.1" 22 | 23 | "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": 24 | version "1.1.2" 25 | resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" 26 | integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= 27 | 28 | "@protobufjs/base64@^1.1.2": 29 | version "1.1.2" 30 | resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" 31 | integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== 32 | 33 | "@protobufjs/codegen@^2.0.4": 34 | version "2.0.4" 35 | resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" 36 | integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== 37 | 38 | "@protobufjs/eventemitter@^1.1.0": 39 | version "1.1.0" 40 | resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" 41 | integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= 42 | 43 | "@protobufjs/fetch@^1.1.0": 44 | version "1.1.0" 45 | resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" 46 | integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= 47 | dependencies: 48 | "@protobufjs/aspromise" "^1.1.1" 49 | "@protobufjs/inquire" "^1.1.0" 50 | 51 | "@protobufjs/float@^1.0.2": 52 | version "1.0.2" 53 | resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" 54 | integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= 55 | 56 | "@protobufjs/inquire@^1.1.0": 57 | version "1.1.0" 58 | resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" 59 | integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= 60 | 61 | "@protobufjs/path@^1.1.2": 62 | version "1.1.2" 63 | resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" 64 | integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= 65 | 66 | "@protobufjs/pool@^1.1.0": 67 | version "1.1.0" 68 | resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" 69 | integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= 70 | 71 | "@protobufjs/utf8@^1.1.0": 72 | version "1.1.0" 73 | resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" 74 | integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= 75 | 76 | "@tsconfig/node10@^1.0.7": 77 | version "1.0.7" 78 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.7.tgz#1eb1de36c73478a2479cc661ef5af1c16d86d606" 79 | integrity sha512-aBvUmXLQbayM4w3A8TrjwrXs4DZ8iduJnuJLLRGdkWlyakCf1q6uHZJBzXoRA/huAEknG5tcUyQxN3A+In5euQ== 80 | 81 | "@tsconfig/node12@^1.0.7": 82 | version "1.0.7" 83 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.7.tgz#677bd9117e8164dc319987dd6ff5fc1ba6fbf18b" 84 | integrity sha512-dgasobK/Y0wVMswcipr3k0HpevxFJLijN03A8mYfEPvWvOs14v0ZlYTR4kIgMx8g4+fTyTFv8/jLCIfRqLDJ4A== 85 | 86 | "@tsconfig/node14@^1.0.0": 87 | version "1.0.0" 88 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.0.tgz#5bd046e508b1ee90bc091766758838741fdefd6e" 89 | integrity sha512-RKkL8eTdPv6t5EHgFKIVQgsDapugbuOptNd9OOunN/HAkzmmTnZELx1kNCK0rSdUYGmiFMM3rRQMAWiyp023LQ== 90 | 91 | "@tsconfig/node16@^1.0.1": 92 | version "1.0.1" 93 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.1.tgz#a6ca6a9a0ff366af433f42f5f0e124794ff6b8f1" 94 | integrity sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA== 95 | 96 | "@types/long@^4.0.1": 97 | version "4.0.1" 98 | resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" 99 | integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== 100 | 101 | "@types/node-redis-pubsub@^3.0.0": 102 | version "3.0.0" 103 | resolved "https://registry.yarnpkg.com/@types/node-redis-pubsub/-/node-redis-pubsub-3.0.0.tgz#c809c060c3cdbce208a084dfaa6d31d64ec8934e" 104 | integrity sha512-ZZKhK3UT91tvneUSxGYxYXkyQzbxNBvesq/fMsMLpBT1dwPd3DxKtXpT5hHzXOmN7X3GH3tflfr8EFkwICQ8hw== 105 | dependencies: 106 | "@types/redis" "*" 107 | 108 | "@types/node@*": 109 | version "15.12.5" 110 | resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.5.tgz#9a78318a45d75c9523d2396131bd3cca54b2d185" 111 | integrity sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg== 112 | 113 | "@types/node@>=12.12.47", "@types/node@>=13.7.0": 114 | version "15.6.1" 115 | resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08" 116 | integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA== 117 | 118 | "@types/redis@*", "@types/redis@^2.8.30": 119 | version "2.8.30" 120 | resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.30.tgz#2b63ce9ff93959355d8a1f6d7a45e483b5fe0299" 121 | integrity sha512-4D3XwfIc671FSNXNruE/wmf6jWL7QYtyAhiWXJDkY41F4atMnOol4584oP4WqnW3uHe8d+Jn+wDLuQaxbfMgXQ== 122 | dependencies: 123 | "@types/node" "*" 124 | 125 | ansi-regex@^5.0.0: 126 | version "5.0.0" 127 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" 128 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== 129 | 130 | ansi-styles@^4.0.0: 131 | version "4.3.0" 132 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 133 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 134 | dependencies: 135 | color-convert "^2.0.1" 136 | 137 | arg@^4.1.0: 138 | version "4.1.3" 139 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 140 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 141 | 142 | buffer-from@^1.0.0: 143 | version "1.1.1" 144 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 145 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 146 | 147 | cliui@^7.0.2: 148 | version "7.0.4" 149 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 150 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 151 | dependencies: 152 | string-width "^4.2.0" 153 | strip-ansi "^6.0.0" 154 | wrap-ansi "^7.0.0" 155 | 156 | color-convert@^2.0.1: 157 | version "2.0.1" 158 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 159 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 160 | dependencies: 161 | color-name "~1.1.4" 162 | 163 | color-name@~1.1.4: 164 | version "1.1.4" 165 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 166 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 167 | 168 | create-require@^1.1.0: 169 | version "1.1.1" 170 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" 171 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 172 | 173 | denque@^1.5.0: 174 | version "1.5.0" 175 | resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de" 176 | integrity sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ== 177 | 178 | diff@^4.0.1: 179 | version "4.0.2" 180 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 181 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 182 | 183 | emoji-regex@^8.0.0: 184 | version "8.0.0" 185 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 186 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 187 | 188 | escalade@^3.1.1: 189 | version "3.1.1" 190 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 191 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 192 | 193 | get-caller-file@^2.0.5: 194 | version "2.0.5" 195 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 196 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 197 | 198 | is-fullwidth-code-point@^3.0.0: 199 | version "3.0.0" 200 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 201 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 202 | 203 | lodash.camelcase@^4.3.0: 204 | version "4.3.0" 205 | resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" 206 | integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= 207 | 208 | long@^4.0.0: 209 | version "4.0.0" 210 | resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" 211 | integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== 212 | 213 | make-error@^1.1.1: 214 | version "1.3.6" 215 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 216 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 217 | 218 | node-redis-pubsub@^5.0.0: 219 | version "5.0.0" 220 | resolved "https://registry.yarnpkg.com/node-redis-pubsub/-/node-redis-pubsub-5.0.0.tgz#565510a23230f4deec95f5c67eaecceb08d0d6e6" 221 | integrity sha512-SBDgfC2QwKLDYbUYNE/jDQxOU1Vg0NDf4fVNQZWnd/tXEhn/N1wY3SxaEXmHWPXhB2nqwZD5fH08SE2g07oMIA== 222 | dependencies: 223 | redis "^3.0.0" 224 | 225 | protobufjs@^6.10.0: 226 | version "6.11.2" 227 | resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b" 228 | integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw== 229 | dependencies: 230 | "@protobufjs/aspromise" "^1.1.2" 231 | "@protobufjs/base64" "^1.1.2" 232 | "@protobufjs/codegen" "^2.0.4" 233 | "@protobufjs/eventemitter" "^1.1.0" 234 | "@protobufjs/fetch" "^1.1.0" 235 | "@protobufjs/float" "^1.0.2" 236 | "@protobufjs/inquire" "^1.1.0" 237 | "@protobufjs/path" "^1.1.2" 238 | "@protobufjs/pool" "^1.1.0" 239 | "@protobufjs/utf8" "^1.1.0" 240 | "@types/long" "^4.0.1" 241 | "@types/node" ">=13.7.0" 242 | long "^4.0.0" 243 | 244 | redis-commands@^1.7.0: 245 | version "1.7.0" 246 | resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89" 247 | integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ== 248 | 249 | redis-errors@^1.0.0, redis-errors@^1.2.0: 250 | version "1.2.0" 251 | resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" 252 | integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= 253 | 254 | redis-parser@^3.0.0: 255 | version "3.0.0" 256 | resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" 257 | integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ= 258 | dependencies: 259 | redis-errors "^1.0.0" 260 | 261 | redis@^3.0.0, redis@^3.1.2: 262 | version "3.1.2" 263 | resolved "https://registry.yarnpkg.com/redis/-/redis-3.1.2.tgz#766851117e80653d23e0ed536254677ab647638c" 264 | integrity sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw== 265 | dependencies: 266 | denque "^1.5.0" 267 | redis-commands "^1.7.0" 268 | redis-errors "^1.2.0" 269 | redis-parser "^3.0.0" 270 | 271 | require-directory@^2.1.1: 272 | version "2.1.1" 273 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 274 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 275 | 276 | source-map-support@^0.5.17: 277 | version "0.5.19" 278 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" 279 | integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== 280 | dependencies: 281 | buffer-from "^1.0.0" 282 | source-map "^0.6.0" 283 | 284 | source-map@^0.6.0: 285 | version "0.6.1" 286 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 287 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 288 | 289 | string-width@^4.1.0, string-width@^4.2.0: 290 | version "4.2.2" 291 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" 292 | integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== 293 | dependencies: 294 | emoji-regex "^8.0.0" 295 | is-fullwidth-code-point "^3.0.0" 296 | strip-ansi "^6.0.0" 297 | 298 | strip-ansi@^6.0.0: 299 | version "6.0.0" 300 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" 301 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== 302 | dependencies: 303 | ansi-regex "^5.0.0" 304 | 305 | ts-node@^10.0.0: 306 | version "10.0.0" 307 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.0.0.tgz#05f10b9a716b0b624129ad44f0ea05dac84ba3be" 308 | integrity sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg== 309 | dependencies: 310 | "@tsconfig/node10" "^1.0.7" 311 | "@tsconfig/node12" "^1.0.7" 312 | "@tsconfig/node14" "^1.0.0" 313 | "@tsconfig/node16" "^1.0.1" 314 | arg "^4.1.0" 315 | create-require "^1.1.0" 316 | diff "^4.0.1" 317 | make-error "^1.1.1" 318 | source-map-support "^0.5.17" 319 | yn "3.1.1" 320 | 321 | typescript@^4.3.2: 322 | version "4.3.2" 323 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" 324 | integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== 325 | 326 | wrap-ansi@^7.0.0: 327 | version "7.0.0" 328 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 329 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 330 | dependencies: 331 | ansi-styles "^4.0.0" 332 | string-width "^4.1.0" 333 | strip-ansi "^6.0.0" 334 | 335 | y18n@^5.0.5: 336 | version "5.0.8" 337 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 338 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 339 | 340 | yargs-parser@^20.2.2: 341 | version "20.2.7" 342 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" 343 | integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== 344 | 345 | yargs@^16.1.1: 346 | version "16.2.0" 347 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 348 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 349 | dependencies: 350 | cliui "^7.0.2" 351 | escalade "^3.1.1" 352 | get-caller-file "^2.0.5" 353 | require-directory "^2.1.1" 354 | string-width "^4.2.0" 355 | y18n "^5.0.5" 356 | yargs-parser "^20.2.2" 357 | 358 | yn@3.1.1: 359 | version "3.1.1" 360 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 361 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 362 | -------------------------------------------------------------------------------- /client/src/proto/random_pb.js: -------------------------------------------------------------------------------- 1 | // source: proto/random.proto 2 | /** 3 | * @fileoverview 4 | * @enhanceable 5 | * @suppress {missingRequire} reports error on implicit type usages. 6 | * @suppress {messageConventions} JS Compiler reports an error if a variable or 7 | * field starts with 'MSG_' and isn't a translatable message. 8 | * @public 9 | */ 10 | // GENERATED CODE -- DO NOT EDIT! 11 | /* eslint-disable */ 12 | // @ts-nocheck 13 | 14 | var jspb = require('google-protobuf'); 15 | var goog = jspb; 16 | var global = Function('return this')(); 17 | 18 | var google_protobuf_empty_pb = require('google-protobuf/google/protobuf/empty_pb.js'); 19 | goog.object.extend(proto, google_protobuf_empty_pb); 20 | goog.exportSymbol('proto.randomPackage.InitiateRequest', null, global); 21 | goog.exportSymbol('proto.randomPackage.InitiateResponse', null, global); 22 | goog.exportSymbol('proto.randomPackage.MessageRequest', null, global); 23 | goog.exportSymbol('proto.randomPackage.Status', null, global); 24 | goog.exportSymbol('proto.randomPackage.StreamMessage', null, global); 25 | goog.exportSymbol('proto.randomPackage.StreamRequest', null, global); 26 | goog.exportSymbol('proto.randomPackage.User', null, global); 27 | goog.exportSymbol('proto.randomPackage.UserStreamResponse', null, global); 28 | /** 29 | * Generated by JsPbCodeGenerator. 30 | * @param {Array=} opt_data Optional initial data array, typically from a 31 | * server response, or constructed directly in Javascript. The array is used 32 | * in place and becomes part of the constructed object. It is not cloned. 33 | * If no data is provided, the constructed object will be empty, but still 34 | * valid. 35 | * @extends {jspb.Message} 36 | * @constructor 37 | */ 38 | proto.randomPackage.InitiateRequest = function(opt_data) { 39 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 40 | }; 41 | goog.inherits(proto.randomPackage.InitiateRequest, jspb.Message); 42 | if (goog.DEBUG && !COMPILED) { 43 | /** 44 | * @public 45 | * @override 46 | */ 47 | proto.randomPackage.InitiateRequest.displayName = 'proto.randomPackage.InitiateRequest'; 48 | } 49 | /** 50 | * Generated by JsPbCodeGenerator. 51 | * @param {Array=} opt_data Optional initial data array, typically from a 52 | * server response, or constructed directly in Javascript. The array is used 53 | * in place and becomes part of the constructed object. It is not cloned. 54 | * If no data is provided, the constructed object will be empty, but still 55 | * valid. 56 | * @extends {jspb.Message} 57 | * @constructor 58 | */ 59 | proto.randomPackage.InitiateResponse = function(opt_data) { 60 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 61 | }; 62 | goog.inherits(proto.randomPackage.InitiateResponse, jspb.Message); 63 | if (goog.DEBUG && !COMPILED) { 64 | /** 65 | * @public 66 | * @override 67 | */ 68 | proto.randomPackage.InitiateResponse.displayName = 'proto.randomPackage.InitiateResponse'; 69 | } 70 | /** 71 | * Generated by JsPbCodeGenerator. 72 | * @param {Array=} opt_data Optional initial data array, typically from a 73 | * server response, or constructed directly in Javascript. The array is used 74 | * in place and becomes part of the constructed object. It is not cloned. 75 | * If no data is provided, the constructed object will be empty, but still 76 | * valid. 77 | * @extends {jspb.Message} 78 | * @constructor 79 | */ 80 | proto.randomPackage.MessageRequest = function(opt_data) { 81 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 82 | }; 83 | goog.inherits(proto.randomPackage.MessageRequest, jspb.Message); 84 | if (goog.DEBUG && !COMPILED) { 85 | /** 86 | * @public 87 | * @override 88 | */ 89 | proto.randomPackage.MessageRequest.displayName = 'proto.randomPackage.MessageRequest'; 90 | } 91 | /** 92 | * Generated by JsPbCodeGenerator. 93 | * @param {Array=} opt_data Optional initial data array, typically from a 94 | * server response, or constructed directly in Javascript. The array is used 95 | * in place and becomes part of the constructed object. It is not cloned. 96 | * If no data is provided, the constructed object will be empty, but still 97 | * valid. 98 | * @extends {jspb.Message} 99 | * @constructor 100 | */ 101 | proto.randomPackage.User = function(opt_data) { 102 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 103 | }; 104 | goog.inherits(proto.randomPackage.User, jspb.Message); 105 | if (goog.DEBUG && !COMPILED) { 106 | /** 107 | * @public 108 | * @override 109 | */ 110 | proto.randomPackage.User.displayName = 'proto.randomPackage.User'; 111 | } 112 | /** 113 | * Generated by JsPbCodeGenerator. 114 | * @param {Array=} opt_data Optional initial data array, typically from a 115 | * server response, or constructed directly in Javascript. The array is used 116 | * in place and becomes part of the constructed object. It is not cloned. 117 | * If no data is provided, the constructed object will be empty, but still 118 | * valid. 119 | * @extends {jspb.Message} 120 | * @constructor 121 | */ 122 | proto.randomPackage.UserStreamResponse = function(opt_data) { 123 | jspb.Message.initialize(this, opt_data, 0, -1, proto.randomPackage.UserStreamResponse.repeatedFields_, null); 124 | }; 125 | goog.inherits(proto.randomPackage.UserStreamResponse, jspb.Message); 126 | if (goog.DEBUG && !COMPILED) { 127 | /** 128 | * @public 129 | * @override 130 | */ 131 | proto.randomPackage.UserStreamResponse.displayName = 'proto.randomPackage.UserStreamResponse'; 132 | } 133 | /** 134 | * Generated by JsPbCodeGenerator. 135 | * @param {Array=} opt_data Optional initial data array, typically from a 136 | * server response, or constructed directly in Javascript. The array is used 137 | * in place and becomes part of the constructed object. It is not cloned. 138 | * If no data is provided, the constructed object will be empty, but still 139 | * valid. 140 | * @extends {jspb.Message} 141 | * @constructor 142 | */ 143 | proto.randomPackage.StreamRequest = function(opt_data) { 144 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 145 | }; 146 | goog.inherits(proto.randomPackage.StreamRequest, jspb.Message); 147 | if (goog.DEBUG && !COMPILED) { 148 | /** 149 | * @public 150 | * @override 151 | */ 152 | proto.randomPackage.StreamRequest.displayName = 'proto.randomPackage.StreamRequest'; 153 | } 154 | /** 155 | * Generated by JsPbCodeGenerator. 156 | * @param {Array=} opt_data Optional initial data array, typically from a 157 | * server response, or constructed directly in Javascript. The array is used 158 | * in place and becomes part of the constructed object. It is not cloned. 159 | * If no data is provided, the constructed object will be empty, but still 160 | * valid. 161 | * @extends {jspb.Message} 162 | * @constructor 163 | */ 164 | proto.randomPackage.StreamMessage = function(opt_data) { 165 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 166 | }; 167 | goog.inherits(proto.randomPackage.StreamMessage, jspb.Message); 168 | if (goog.DEBUG && !COMPILED) { 169 | /** 170 | * @public 171 | * @override 172 | */ 173 | proto.randomPackage.StreamMessage.displayName = 'proto.randomPackage.StreamMessage'; 174 | } 175 | 176 | 177 | 178 | if (jspb.Message.GENERATE_TO_OBJECT) { 179 | /** 180 | * Creates an object representation of this proto. 181 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 182 | * Optional fields that are not set will be set to undefined. 183 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 184 | * For the list of reserved names please see: 185 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 186 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 187 | * JSPB instance for transitional soy proto support: 188 | * http://goto/soy-param-migration 189 | * @return {!Object} 190 | */ 191 | proto.randomPackage.InitiateRequest.prototype.toObject = function(opt_includeInstance) { 192 | return proto.randomPackage.InitiateRequest.toObject(opt_includeInstance, this); 193 | }; 194 | 195 | 196 | /** 197 | * Static version of the {@see toObject} method. 198 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 199 | * the JSPB instance for transitional soy proto support: 200 | * http://goto/soy-param-migration 201 | * @param {!proto.randomPackage.InitiateRequest} msg The msg instance to transform. 202 | * @return {!Object} 203 | * @suppress {unusedLocalVariables} f is only used for nested messages 204 | */ 205 | proto.randomPackage.InitiateRequest.toObject = function(includeInstance, msg) { 206 | var f, obj = { 207 | name: jspb.Message.getFieldWithDefault(msg, 1, ""), 208 | avatarUrl: jspb.Message.getFieldWithDefault(msg, 2, "") 209 | }; 210 | 211 | if (includeInstance) { 212 | obj.$jspbMessageInstance = msg; 213 | } 214 | return obj; 215 | }; 216 | } 217 | 218 | 219 | /** 220 | * Deserializes binary data (in protobuf wire format). 221 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 222 | * @return {!proto.randomPackage.InitiateRequest} 223 | */ 224 | proto.randomPackage.InitiateRequest.deserializeBinary = function(bytes) { 225 | var reader = new jspb.BinaryReader(bytes); 226 | var msg = new proto.randomPackage.InitiateRequest; 227 | return proto.randomPackage.InitiateRequest.deserializeBinaryFromReader(msg, reader); 228 | }; 229 | 230 | 231 | /** 232 | * Deserializes binary data (in protobuf wire format) from the 233 | * given reader into the given message object. 234 | * @param {!proto.randomPackage.InitiateRequest} msg The message object to deserialize into. 235 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 236 | * @return {!proto.randomPackage.InitiateRequest} 237 | */ 238 | proto.randomPackage.InitiateRequest.deserializeBinaryFromReader = function(msg, reader) { 239 | while (reader.nextField()) { 240 | if (reader.isEndGroup()) { 241 | break; 242 | } 243 | var field = reader.getFieldNumber(); 244 | switch (field) { 245 | case 1: 246 | var value = /** @type {string} */ (reader.readString()); 247 | msg.setName(value); 248 | break; 249 | case 2: 250 | var value = /** @type {string} */ (reader.readString()); 251 | msg.setAvatarUrl(value); 252 | break; 253 | default: 254 | reader.skipField(); 255 | break; 256 | } 257 | } 258 | return msg; 259 | }; 260 | 261 | 262 | /** 263 | * Serializes the message to binary data (in protobuf wire format). 264 | * @return {!Uint8Array} 265 | */ 266 | proto.randomPackage.InitiateRequest.prototype.serializeBinary = function() { 267 | var writer = new jspb.BinaryWriter(); 268 | proto.randomPackage.InitiateRequest.serializeBinaryToWriter(this, writer); 269 | return writer.getResultBuffer(); 270 | }; 271 | 272 | 273 | /** 274 | * Serializes the given message to binary data (in protobuf wire 275 | * format), writing to the given BinaryWriter. 276 | * @param {!proto.randomPackage.InitiateRequest} message 277 | * @param {!jspb.BinaryWriter} writer 278 | * @suppress {unusedLocalVariables} f is only used for nested messages 279 | */ 280 | proto.randomPackage.InitiateRequest.serializeBinaryToWriter = function(message, writer) { 281 | var f = undefined; 282 | f = message.getName(); 283 | if (f.length > 0) { 284 | writer.writeString( 285 | 1, 286 | f 287 | ); 288 | } 289 | f = message.getAvatarUrl(); 290 | if (f.length > 0) { 291 | writer.writeString( 292 | 2, 293 | f 294 | ); 295 | } 296 | }; 297 | 298 | 299 | /** 300 | * optional string name = 1; 301 | * @return {string} 302 | */ 303 | proto.randomPackage.InitiateRequest.prototype.getName = function() { 304 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 305 | }; 306 | 307 | 308 | /** 309 | * @param {string} value 310 | * @return {!proto.randomPackage.InitiateRequest} returns this 311 | */ 312 | proto.randomPackage.InitiateRequest.prototype.setName = function(value) { 313 | return jspb.Message.setProto3StringField(this, 1, value); 314 | }; 315 | 316 | 317 | /** 318 | * optional string avatar_url = 2; 319 | * @return {string} 320 | */ 321 | proto.randomPackage.InitiateRequest.prototype.getAvatarUrl = function() { 322 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); 323 | }; 324 | 325 | 326 | /** 327 | * @param {string} value 328 | * @return {!proto.randomPackage.InitiateRequest} returns this 329 | */ 330 | proto.randomPackage.InitiateRequest.prototype.setAvatarUrl = function(value) { 331 | return jspb.Message.setProto3StringField(this, 2, value); 332 | }; 333 | 334 | 335 | 336 | 337 | 338 | if (jspb.Message.GENERATE_TO_OBJECT) { 339 | /** 340 | * Creates an object representation of this proto. 341 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 342 | * Optional fields that are not set will be set to undefined. 343 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 344 | * For the list of reserved names please see: 345 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 346 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 347 | * JSPB instance for transitional soy proto support: 348 | * http://goto/soy-param-migration 349 | * @return {!Object} 350 | */ 351 | proto.randomPackage.InitiateResponse.prototype.toObject = function(opt_includeInstance) { 352 | return proto.randomPackage.InitiateResponse.toObject(opt_includeInstance, this); 353 | }; 354 | 355 | 356 | /** 357 | * Static version of the {@see toObject} method. 358 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 359 | * the JSPB instance for transitional soy proto support: 360 | * http://goto/soy-param-migration 361 | * @param {!proto.randomPackage.InitiateResponse} msg The msg instance to transform. 362 | * @return {!Object} 363 | * @suppress {unusedLocalVariables} f is only used for nested messages 364 | */ 365 | proto.randomPackage.InitiateResponse.toObject = function(includeInstance, msg) { 366 | var f, obj = { 367 | id: jspb.Message.getFieldWithDefault(msg, 1, 0) 368 | }; 369 | 370 | if (includeInstance) { 371 | obj.$jspbMessageInstance = msg; 372 | } 373 | return obj; 374 | }; 375 | } 376 | 377 | 378 | /** 379 | * Deserializes binary data (in protobuf wire format). 380 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 381 | * @return {!proto.randomPackage.InitiateResponse} 382 | */ 383 | proto.randomPackage.InitiateResponse.deserializeBinary = function(bytes) { 384 | var reader = new jspb.BinaryReader(bytes); 385 | var msg = new proto.randomPackage.InitiateResponse; 386 | return proto.randomPackage.InitiateResponse.deserializeBinaryFromReader(msg, reader); 387 | }; 388 | 389 | 390 | /** 391 | * Deserializes binary data (in protobuf wire format) from the 392 | * given reader into the given message object. 393 | * @param {!proto.randomPackage.InitiateResponse} msg The message object to deserialize into. 394 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 395 | * @return {!proto.randomPackage.InitiateResponse} 396 | */ 397 | proto.randomPackage.InitiateResponse.deserializeBinaryFromReader = function(msg, reader) { 398 | while (reader.nextField()) { 399 | if (reader.isEndGroup()) { 400 | break; 401 | } 402 | var field = reader.getFieldNumber(); 403 | switch (field) { 404 | case 1: 405 | var value = /** @type {number} */ (reader.readInt32()); 406 | msg.setId(value); 407 | break; 408 | default: 409 | reader.skipField(); 410 | break; 411 | } 412 | } 413 | return msg; 414 | }; 415 | 416 | 417 | /** 418 | * Serializes the message to binary data (in protobuf wire format). 419 | * @return {!Uint8Array} 420 | */ 421 | proto.randomPackage.InitiateResponse.prototype.serializeBinary = function() { 422 | var writer = new jspb.BinaryWriter(); 423 | proto.randomPackage.InitiateResponse.serializeBinaryToWriter(this, writer); 424 | return writer.getResultBuffer(); 425 | }; 426 | 427 | 428 | /** 429 | * Serializes the given message to binary data (in protobuf wire 430 | * format), writing to the given BinaryWriter. 431 | * @param {!proto.randomPackage.InitiateResponse} message 432 | * @param {!jspb.BinaryWriter} writer 433 | * @suppress {unusedLocalVariables} f is only used for nested messages 434 | */ 435 | proto.randomPackage.InitiateResponse.serializeBinaryToWriter = function(message, writer) { 436 | var f = undefined; 437 | f = message.getId(); 438 | if (f !== 0) { 439 | writer.writeInt32( 440 | 1, 441 | f 442 | ); 443 | } 444 | }; 445 | 446 | 447 | /** 448 | * optional int32 id = 1; 449 | * @return {number} 450 | */ 451 | proto.randomPackage.InitiateResponse.prototype.getId = function() { 452 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); 453 | }; 454 | 455 | 456 | /** 457 | * @param {number} value 458 | * @return {!proto.randomPackage.InitiateResponse} returns this 459 | */ 460 | proto.randomPackage.InitiateResponse.prototype.setId = function(value) { 461 | return jspb.Message.setProto3IntField(this, 1, value); 462 | }; 463 | 464 | 465 | 466 | 467 | 468 | if (jspb.Message.GENERATE_TO_OBJECT) { 469 | /** 470 | * Creates an object representation of this proto. 471 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 472 | * Optional fields that are not set will be set to undefined. 473 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 474 | * For the list of reserved names please see: 475 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 476 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 477 | * JSPB instance for transitional soy proto support: 478 | * http://goto/soy-param-migration 479 | * @return {!Object} 480 | */ 481 | proto.randomPackage.MessageRequest.prototype.toObject = function(opt_includeInstance) { 482 | return proto.randomPackage.MessageRequest.toObject(opt_includeInstance, this); 483 | }; 484 | 485 | 486 | /** 487 | * Static version of the {@see toObject} method. 488 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 489 | * the JSPB instance for transitional soy proto support: 490 | * http://goto/soy-param-migration 491 | * @param {!proto.randomPackage.MessageRequest} msg The msg instance to transform. 492 | * @return {!Object} 493 | * @suppress {unusedLocalVariables} f is only used for nested messages 494 | */ 495 | proto.randomPackage.MessageRequest.toObject = function(includeInstance, msg) { 496 | var f, obj = { 497 | id: jspb.Message.getFieldWithDefault(msg, 1, 0), 498 | message: jspb.Message.getFieldWithDefault(msg, 2, "") 499 | }; 500 | 501 | if (includeInstance) { 502 | obj.$jspbMessageInstance = msg; 503 | } 504 | return obj; 505 | }; 506 | } 507 | 508 | 509 | /** 510 | * Deserializes binary data (in protobuf wire format). 511 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 512 | * @return {!proto.randomPackage.MessageRequest} 513 | */ 514 | proto.randomPackage.MessageRequest.deserializeBinary = function(bytes) { 515 | var reader = new jspb.BinaryReader(bytes); 516 | var msg = new proto.randomPackage.MessageRequest; 517 | return proto.randomPackage.MessageRequest.deserializeBinaryFromReader(msg, reader); 518 | }; 519 | 520 | 521 | /** 522 | * Deserializes binary data (in protobuf wire format) from the 523 | * given reader into the given message object. 524 | * @param {!proto.randomPackage.MessageRequest} msg The message object to deserialize into. 525 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 526 | * @return {!proto.randomPackage.MessageRequest} 527 | */ 528 | proto.randomPackage.MessageRequest.deserializeBinaryFromReader = function(msg, reader) { 529 | while (reader.nextField()) { 530 | if (reader.isEndGroup()) { 531 | break; 532 | } 533 | var field = reader.getFieldNumber(); 534 | switch (field) { 535 | case 1: 536 | var value = /** @type {number} */ (reader.readInt32()); 537 | msg.setId(value); 538 | break; 539 | case 2: 540 | var value = /** @type {string} */ (reader.readString()); 541 | msg.setMessage(value); 542 | break; 543 | default: 544 | reader.skipField(); 545 | break; 546 | } 547 | } 548 | return msg; 549 | }; 550 | 551 | 552 | /** 553 | * Serializes the message to binary data (in protobuf wire format). 554 | * @return {!Uint8Array} 555 | */ 556 | proto.randomPackage.MessageRequest.prototype.serializeBinary = function() { 557 | var writer = new jspb.BinaryWriter(); 558 | proto.randomPackage.MessageRequest.serializeBinaryToWriter(this, writer); 559 | return writer.getResultBuffer(); 560 | }; 561 | 562 | 563 | /** 564 | * Serializes the given message to binary data (in protobuf wire 565 | * format), writing to the given BinaryWriter. 566 | * @param {!proto.randomPackage.MessageRequest} message 567 | * @param {!jspb.BinaryWriter} writer 568 | * @suppress {unusedLocalVariables} f is only used for nested messages 569 | */ 570 | proto.randomPackage.MessageRequest.serializeBinaryToWriter = function(message, writer) { 571 | var f = undefined; 572 | f = message.getId(); 573 | if (f !== 0) { 574 | writer.writeInt32( 575 | 1, 576 | f 577 | ); 578 | } 579 | f = message.getMessage(); 580 | if (f.length > 0) { 581 | writer.writeString( 582 | 2, 583 | f 584 | ); 585 | } 586 | }; 587 | 588 | 589 | /** 590 | * optional int32 id = 1; 591 | * @return {number} 592 | */ 593 | proto.randomPackage.MessageRequest.prototype.getId = function() { 594 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); 595 | }; 596 | 597 | 598 | /** 599 | * @param {number} value 600 | * @return {!proto.randomPackage.MessageRequest} returns this 601 | */ 602 | proto.randomPackage.MessageRequest.prototype.setId = function(value) { 603 | return jspb.Message.setProto3IntField(this, 1, value); 604 | }; 605 | 606 | 607 | /** 608 | * optional string message = 2; 609 | * @return {string} 610 | */ 611 | proto.randomPackage.MessageRequest.prototype.getMessage = function() { 612 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); 613 | }; 614 | 615 | 616 | /** 617 | * @param {string} value 618 | * @return {!proto.randomPackage.MessageRequest} returns this 619 | */ 620 | proto.randomPackage.MessageRequest.prototype.setMessage = function(value) { 621 | return jspb.Message.setProto3StringField(this, 2, value); 622 | }; 623 | 624 | 625 | 626 | 627 | 628 | if (jspb.Message.GENERATE_TO_OBJECT) { 629 | /** 630 | * Creates an object representation of this proto. 631 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 632 | * Optional fields that are not set will be set to undefined. 633 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 634 | * For the list of reserved names please see: 635 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 636 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 637 | * JSPB instance for transitional soy proto support: 638 | * http://goto/soy-param-migration 639 | * @return {!Object} 640 | */ 641 | proto.randomPackage.User.prototype.toObject = function(opt_includeInstance) { 642 | return proto.randomPackage.User.toObject(opt_includeInstance, this); 643 | }; 644 | 645 | 646 | /** 647 | * Static version of the {@see toObject} method. 648 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 649 | * the JSPB instance for transitional soy proto support: 650 | * http://goto/soy-param-migration 651 | * @param {!proto.randomPackage.User} msg The msg instance to transform. 652 | * @return {!Object} 653 | * @suppress {unusedLocalVariables} f is only used for nested messages 654 | */ 655 | proto.randomPackage.User.toObject = function(includeInstance, msg) { 656 | var f, obj = { 657 | id: jspb.Message.getFieldWithDefault(msg, 1, 0), 658 | name: jspb.Message.getFieldWithDefault(msg, 2, ""), 659 | status: jspb.Message.getFieldWithDefault(msg, 3, 0), 660 | avatar: jspb.Message.getFieldWithDefault(msg, 4, "") 661 | }; 662 | 663 | if (includeInstance) { 664 | obj.$jspbMessageInstance = msg; 665 | } 666 | return obj; 667 | }; 668 | } 669 | 670 | 671 | /** 672 | * Deserializes binary data (in protobuf wire format). 673 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 674 | * @return {!proto.randomPackage.User} 675 | */ 676 | proto.randomPackage.User.deserializeBinary = function(bytes) { 677 | var reader = new jspb.BinaryReader(bytes); 678 | var msg = new proto.randomPackage.User; 679 | return proto.randomPackage.User.deserializeBinaryFromReader(msg, reader); 680 | }; 681 | 682 | 683 | /** 684 | * Deserializes binary data (in protobuf wire format) from the 685 | * given reader into the given message object. 686 | * @param {!proto.randomPackage.User} msg The message object to deserialize into. 687 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 688 | * @return {!proto.randomPackage.User} 689 | */ 690 | proto.randomPackage.User.deserializeBinaryFromReader = function(msg, reader) { 691 | while (reader.nextField()) { 692 | if (reader.isEndGroup()) { 693 | break; 694 | } 695 | var field = reader.getFieldNumber(); 696 | switch (field) { 697 | case 1: 698 | var value = /** @type {number} */ (reader.readInt32()); 699 | msg.setId(value); 700 | break; 701 | case 2: 702 | var value = /** @type {string} */ (reader.readString()); 703 | msg.setName(value); 704 | break; 705 | case 3: 706 | var value = /** @type {!proto.randomPackage.Status} */ (reader.readEnum()); 707 | msg.setStatus(value); 708 | break; 709 | case 4: 710 | var value = /** @type {string} */ (reader.readString()); 711 | msg.setAvatar(value); 712 | break; 713 | default: 714 | reader.skipField(); 715 | break; 716 | } 717 | } 718 | return msg; 719 | }; 720 | 721 | 722 | /** 723 | * Serializes the message to binary data (in protobuf wire format). 724 | * @return {!Uint8Array} 725 | */ 726 | proto.randomPackage.User.prototype.serializeBinary = function() { 727 | var writer = new jspb.BinaryWriter(); 728 | proto.randomPackage.User.serializeBinaryToWriter(this, writer); 729 | return writer.getResultBuffer(); 730 | }; 731 | 732 | 733 | /** 734 | * Serializes the given message to binary data (in protobuf wire 735 | * format), writing to the given BinaryWriter. 736 | * @param {!proto.randomPackage.User} message 737 | * @param {!jspb.BinaryWriter} writer 738 | * @suppress {unusedLocalVariables} f is only used for nested messages 739 | */ 740 | proto.randomPackage.User.serializeBinaryToWriter = function(message, writer) { 741 | var f = undefined; 742 | f = message.getId(); 743 | if (f !== 0) { 744 | writer.writeInt32( 745 | 1, 746 | f 747 | ); 748 | } 749 | f = message.getName(); 750 | if (f.length > 0) { 751 | writer.writeString( 752 | 2, 753 | f 754 | ); 755 | } 756 | f = message.getStatus(); 757 | if (f !== 0.0) { 758 | writer.writeEnum( 759 | 3, 760 | f 761 | ); 762 | } 763 | f = message.getAvatar(); 764 | if (f.length > 0) { 765 | writer.writeString( 766 | 4, 767 | f 768 | ); 769 | } 770 | }; 771 | 772 | 773 | /** 774 | * optional int32 id = 1; 775 | * @return {number} 776 | */ 777 | proto.randomPackage.User.prototype.getId = function() { 778 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); 779 | }; 780 | 781 | 782 | /** 783 | * @param {number} value 784 | * @return {!proto.randomPackage.User} returns this 785 | */ 786 | proto.randomPackage.User.prototype.setId = function(value) { 787 | return jspb.Message.setProto3IntField(this, 1, value); 788 | }; 789 | 790 | 791 | /** 792 | * optional string name = 2; 793 | * @return {string} 794 | */ 795 | proto.randomPackage.User.prototype.getName = function() { 796 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); 797 | }; 798 | 799 | 800 | /** 801 | * @param {string} value 802 | * @return {!proto.randomPackage.User} returns this 803 | */ 804 | proto.randomPackage.User.prototype.setName = function(value) { 805 | return jspb.Message.setProto3StringField(this, 2, value); 806 | }; 807 | 808 | 809 | /** 810 | * optional Status status = 3; 811 | * @return {!proto.randomPackage.Status} 812 | */ 813 | proto.randomPackage.User.prototype.getStatus = function() { 814 | return /** @type {!proto.randomPackage.Status} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); 815 | }; 816 | 817 | 818 | /** 819 | * @param {!proto.randomPackage.Status} value 820 | * @return {!proto.randomPackage.User} returns this 821 | */ 822 | proto.randomPackage.User.prototype.setStatus = function(value) { 823 | return jspb.Message.setProto3EnumField(this, 3, value); 824 | }; 825 | 826 | 827 | /** 828 | * optional string avatar = 4; 829 | * @return {string} 830 | */ 831 | proto.randomPackage.User.prototype.getAvatar = function() { 832 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); 833 | }; 834 | 835 | 836 | /** 837 | * @param {string} value 838 | * @return {!proto.randomPackage.User} returns this 839 | */ 840 | proto.randomPackage.User.prototype.setAvatar = function(value) { 841 | return jspb.Message.setProto3StringField(this, 4, value); 842 | }; 843 | 844 | 845 | 846 | /** 847 | * List of repeated fields within this message type. 848 | * @private {!Array} 849 | * @const 850 | */ 851 | proto.randomPackage.UserStreamResponse.repeatedFields_ = [1]; 852 | 853 | 854 | 855 | if (jspb.Message.GENERATE_TO_OBJECT) { 856 | /** 857 | * Creates an object representation of this proto. 858 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 859 | * Optional fields that are not set will be set to undefined. 860 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 861 | * For the list of reserved names please see: 862 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 863 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 864 | * JSPB instance for transitional soy proto support: 865 | * http://goto/soy-param-migration 866 | * @return {!Object} 867 | */ 868 | proto.randomPackage.UserStreamResponse.prototype.toObject = function(opt_includeInstance) { 869 | return proto.randomPackage.UserStreamResponse.toObject(opt_includeInstance, this); 870 | }; 871 | 872 | 873 | /** 874 | * Static version of the {@see toObject} method. 875 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 876 | * the JSPB instance for transitional soy proto support: 877 | * http://goto/soy-param-migration 878 | * @param {!proto.randomPackage.UserStreamResponse} msg The msg instance to transform. 879 | * @return {!Object} 880 | * @suppress {unusedLocalVariables} f is only used for nested messages 881 | */ 882 | proto.randomPackage.UserStreamResponse.toObject = function(includeInstance, msg) { 883 | var f, obj = { 884 | usersList: jspb.Message.toObjectList(msg.getUsersList(), 885 | proto.randomPackage.User.toObject, includeInstance) 886 | }; 887 | 888 | if (includeInstance) { 889 | obj.$jspbMessageInstance = msg; 890 | } 891 | return obj; 892 | }; 893 | } 894 | 895 | 896 | /** 897 | * Deserializes binary data (in protobuf wire format). 898 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 899 | * @return {!proto.randomPackage.UserStreamResponse} 900 | */ 901 | proto.randomPackage.UserStreamResponse.deserializeBinary = function(bytes) { 902 | var reader = new jspb.BinaryReader(bytes); 903 | var msg = new proto.randomPackage.UserStreamResponse; 904 | return proto.randomPackage.UserStreamResponse.deserializeBinaryFromReader(msg, reader); 905 | }; 906 | 907 | 908 | /** 909 | * Deserializes binary data (in protobuf wire format) from the 910 | * given reader into the given message object. 911 | * @param {!proto.randomPackage.UserStreamResponse} msg The message object to deserialize into. 912 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 913 | * @return {!proto.randomPackage.UserStreamResponse} 914 | */ 915 | proto.randomPackage.UserStreamResponse.deserializeBinaryFromReader = function(msg, reader) { 916 | while (reader.nextField()) { 917 | if (reader.isEndGroup()) { 918 | break; 919 | } 920 | var field = reader.getFieldNumber(); 921 | switch (field) { 922 | case 1: 923 | var value = new proto.randomPackage.User; 924 | reader.readMessage(value,proto.randomPackage.User.deserializeBinaryFromReader); 925 | msg.addUsers(value); 926 | break; 927 | default: 928 | reader.skipField(); 929 | break; 930 | } 931 | } 932 | return msg; 933 | }; 934 | 935 | 936 | /** 937 | * Serializes the message to binary data (in protobuf wire format). 938 | * @return {!Uint8Array} 939 | */ 940 | proto.randomPackage.UserStreamResponse.prototype.serializeBinary = function() { 941 | var writer = new jspb.BinaryWriter(); 942 | proto.randomPackage.UserStreamResponse.serializeBinaryToWriter(this, writer); 943 | return writer.getResultBuffer(); 944 | }; 945 | 946 | 947 | /** 948 | * Serializes the given message to binary data (in protobuf wire 949 | * format), writing to the given BinaryWriter. 950 | * @param {!proto.randomPackage.UserStreamResponse} message 951 | * @param {!jspb.BinaryWriter} writer 952 | * @suppress {unusedLocalVariables} f is only used for nested messages 953 | */ 954 | proto.randomPackage.UserStreamResponse.serializeBinaryToWriter = function(message, writer) { 955 | var f = undefined; 956 | f = message.getUsersList(); 957 | if (f.length > 0) { 958 | writer.writeRepeatedMessage( 959 | 1, 960 | f, 961 | proto.randomPackage.User.serializeBinaryToWriter 962 | ); 963 | } 964 | }; 965 | 966 | 967 | /** 968 | * repeated User users = 1; 969 | * @return {!Array} 970 | */ 971 | proto.randomPackage.UserStreamResponse.prototype.getUsersList = function() { 972 | return /** @type{!Array} */ ( 973 | jspb.Message.getRepeatedWrapperField(this, proto.randomPackage.User, 1)); 974 | }; 975 | 976 | 977 | /** 978 | * @param {!Array} value 979 | * @return {!proto.randomPackage.UserStreamResponse} returns this 980 | */ 981 | proto.randomPackage.UserStreamResponse.prototype.setUsersList = function(value) { 982 | return jspb.Message.setRepeatedWrapperField(this, 1, value); 983 | }; 984 | 985 | 986 | /** 987 | * @param {!proto.randomPackage.User=} opt_value 988 | * @param {number=} opt_index 989 | * @return {!proto.randomPackage.User} 990 | */ 991 | proto.randomPackage.UserStreamResponse.prototype.addUsers = function(opt_value, opt_index) { 992 | return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.randomPackage.User, opt_index); 993 | }; 994 | 995 | 996 | /** 997 | * Clears the list making it empty but non-null. 998 | * @return {!proto.randomPackage.UserStreamResponse} returns this 999 | */ 1000 | proto.randomPackage.UserStreamResponse.prototype.clearUsersList = function() { 1001 | return this.setUsersList([]); 1002 | }; 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | if (jspb.Message.GENERATE_TO_OBJECT) { 1009 | /** 1010 | * Creates an object representation of this proto. 1011 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 1012 | * Optional fields that are not set will be set to undefined. 1013 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 1014 | * For the list of reserved names please see: 1015 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 1016 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 1017 | * JSPB instance for transitional soy proto support: 1018 | * http://goto/soy-param-migration 1019 | * @return {!Object} 1020 | */ 1021 | proto.randomPackage.StreamRequest.prototype.toObject = function(opt_includeInstance) { 1022 | return proto.randomPackage.StreamRequest.toObject(opt_includeInstance, this); 1023 | }; 1024 | 1025 | 1026 | /** 1027 | * Static version of the {@see toObject} method. 1028 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 1029 | * the JSPB instance for transitional soy proto support: 1030 | * http://goto/soy-param-migration 1031 | * @param {!proto.randomPackage.StreamRequest} msg The msg instance to transform. 1032 | * @return {!Object} 1033 | * @suppress {unusedLocalVariables} f is only used for nested messages 1034 | */ 1035 | proto.randomPackage.StreamRequest.toObject = function(includeInstance, msg) { 1036 | var f, obj = { 1037 | id: jspb.Message.getFieldWithDefault(msg, 1, 0) 1038 | }; 1039 | 1040 | if (includeInstance) { 1041 | obj.$jspbMessageInstance = msg; 1042 | } 1043 | return obj; 1044 | }; 1045 | } 1046 | 1047 | 1048 | /** 1049 | * Deserializes binary data (in protobuf wire format). 1050 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 1051 | * @return {!proto.randomPackage.StreamRequest} 1052 | */ 1053 | proto.randomPackage.StreamRequest.deserializeBinary = function(bytes) { 1054 | var reader = new jspb.BinaryReader(bytes); 1055 | var msg = new proto.randomPackage.StreamRequest; 1056 | return proto.randomPackage.StreamRequest.deserializeBinaryFromReader(msg, reader); 1057 | }; 1058 | 1059 | 1060 | /** 1061 | * Deserializes binary data (in protobuf wire format) from the 1062 | * given reader into the given message object. 1063 | * @param {!proto.randomPackage.StreamRequest} msg The message object to deserialize into. 1064 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 1065 | * @return {!proto.randomPackage.StreamRequest} 1066 | */ 1067 | proto.randomPackage.StreamRequest.deserializeBinaryFromReader = function(msg, reader) { 1068 | while (reader.nextField()) { 1069 | if (reader.isEndGroup()) { 1070 | break; 1071 | } 1072 | var field = reader.getFieldNumber(); 1073 | switch (field) { 1074 | case 1: 1075 | var value = /** @type {number} */ (reader.readInt32()); 1076 | msg.setId(value); 1077 | break; 1078 | default: 1079 | reader.skipField(); 1080 | break; 1081 | } 1082 | } 1083 | return msg; 1084 | }; 1085 | 1086 | 1087 | /** 1088 | * Serializes the message to binary data (in protobuf wire format). 1089 | * @return {!Uint8Array} 1090 | */ 1091 | proto.randomPackage.StreamRequest.prototype.serializeBinary = function() { 1092 | var writer = new jspb.BinaryWriter(); 1093 | proto.randomPackage.StreamRequest.serializeBinaryToWriter(this, writer); 1094 | return writer.getResultBuffer(); 1095 | }; 1096 | 1097 | 1098 | /** 1099 | * Serializes the given message to binary data (in protobuf wire 1100 | * format), writing to the given BinaryWriter. 1101 | * @param {!proto.randomPackage.StreamRequest} message 1102 | * @param {!jspb.BinaryWriter} writer 1103 | * @suppress {unusedLocalVariables} f is only used for nested messages 1104 | */ 1105 | proto.randomPackage.StreamRequest.serializeBinaryToWriter = function(message, writer) { 1106 | var f = undefined; 1107 | f = message.getId(); 1108 | if (f !== 0) { 1109 | writer.writeInt32( 1110 | 1, 1111 | f 1112 | ); 1113 | } 1114 | }; 1115 | 1116 | 1117 | /** 1118 | * optional int32 id = 1; 1119 | * @return {number} 1120 | */ 1121 | proto.randomPackage.StreamRequest.prototype.getId = function() { 1122 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); 1123 | }; 1124 | 1125 | 1126 | /** 1127 | * @param {number} value 1128 | * @return {!proto.randomPackage.StreamRequest} returns this 1129 | */ 1130 | proto.randomPackage.StreamRequest.prototype.setId = function(value) { 1131 | return jspb.Message.setProto3IntField(this, 1, value); 1132 | }; 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | if (jspb.Message.GENERATE_TO_OBJECT) { 1139 | /** 1140 | * Creates an object representation of this proto. 1141 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 1142 | * Optional fields that are not set will be set to undefined. 1143 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 1144 | * For the list of reserved names please see: 1145 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 1146 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 1147 | * JSPB instance for transitional soy proto support: 1148 | * http://goto/soy-param-migration 1149 | * @return {!Object} 1150 | */ 1151 | proto.randomPackage.StreamMessage.prototype.toObject = function(opt_includeInstance) { 1152 | return proto.randomPackage.StreamMessage.toObject(opt_includeInstance, this); 1153 | }; 1154 | 1155 | 1156 | /** 1157 | * Static version of the {@see toObject} method. 1158 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 1159 | * the JSPB instance for transitional soy proto support: 1160 | * http://goto/soy-param-migration 1161 | * @param {!proto.randomPackage.StreamMessage} msg The msg instance to transform. 1162 | * @return {!Object} 1163 | * @suppress {unusedLocalVariables} f is only used for nested messages 1164 | */ 1165 | proto.randomPackage.StreamMessage.toObject = function(includeInstance, msg) { 1166 | var f, obj = { 1167 | id: jspb.Message.getFieldWithDefault(msg, 1, 0), 1168 | senderName: jspb.Message.getFieldWithDefault(msg, 2, ""), 1169 | senderAvatar: jspb.Message.getFieldWithDefault(msg, 3, ""), 1170 | message: jspb.Message.getFieldWithDefault(msg, 4, "") 1171 | }; 1172 | 1173 | if (includeInstance) { 1174 | obj.$jspbMessageInstance = msg; 1175 | } 1176 | return obj; 1177 | }; 1178 | } 1179 | 1180 | 1181 | /** 1182 | * Deserializes binary data (in protobuf wire format). 1183 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 1184 | * @return {!proto.randomPackage.StreamMessage} 1185 | */ 1186 | proto.randomPackage.StreamMessage.deserializeBinary = function(bytes) { 1187 | var reader = new jspb.BinaryReader(bytes); 1188 | var msg = new proto.randomPackage.StreamMessage; 1189 | return proto.randomPackage.StreamMessage.deserializeBinaryFromReader(msg, reader); 1190 | }; 1191 | 1192 | 1193 | /** 1194 | * Deserializes binary data (in protobuf wire format) from the 1195 | * given reader into the given message object. 1196 | * @param {!proto.randomPackage.StreamMessage} msg The message object to deserialize into. 1197 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 1198 | * @return {!proto.randomPackage.StreamMessage} 1199 | */ 1200 | proto.randomPackage.StreamMessage.deserializeBinaryFromReader = function(msg, reader) { 1201 | while (reader.nextField()) { 1202 | if (reader.isEndGroup()) { 1203 | break; 1204 | } 1205 | var field = reader.getFieldNumber(); 1206 | switch (field) { 1207 | case 1: 1208 | var value = /** @type {number} */ (reader.readInt32()); 1209 | msg.setId(value); 1210 | break; 1211 | case 2: 1212 | var value = /** @type {string} */ (reader.readString()); 1213 | msg.setSenderName(value); 1214 | break; 1215 | case 3: 1216 | var value = /** @type {string} */ (reader.readString()); 1217 | msg.setSenderAvatar(value); 1218 | break; 1219 | case 4: 1220 | var value = /** @type {string} */ (reader.readString()); 1221 | msg.setMessage(value); 1222 | break; 1223 | default: 1224 | reader.skipField(); 1225 | break; 1226 | } 1227 | } 1228 | return msg; 1229 | }; 1230 | 1231 | 1232 | /** 1233 | * Serializes the message to binary data (in protobuf wire format). 1234 | * @return {!Uint8Array} 1235 | */ 1236 | proto.randomPackage.StreamMessage.prototype.serializeBinary = function() { 1237 | var writer = new jspb.BinaryWriter(); 1238 | proto.randomPackage.StreamMessage.serializeBinaryToWriter(this, writer); 1239 | return writer.getResultBuffer(); 1240 | }; 1241 | 1242 | 1243 | /** 1244 | * Serializes the given message to binary data (in protobuf wire 1245 | * format), writing to the given BinaryWriter. 1246 | * @param {!proto.randomPackage.StreamMessage} message 1247 | * @param {!jspb.BinaryWriter} writer 1248 | * @suppress {unusedLocalVariables} f is only used for nested messages 1249 | */ 1250 | proto.randomPackage.StreamMessage.serializeBinaryToWriter = function(message, writer) { 1251 | var f = undefined; 1252 | f = message.getId(); 1253 | if (f !== 0) { 1254 | writer.writeInt32( 1255 | 1, 1256 | f 1257 | ); 1258 | } 1259 | f = message.getSenderName(); 1260 | if (f.length > 0) { 1261 | writer.writeString( 1262 | 2, 1263 | f 1264 | ); 1265 | } 1266 | f = message.getSenderAvatar(); 1267 | if (f.length > 0) { 1268 | writer.writeString( 1269 | 3, 1270 | f 1271 | ); 1272 | } 1273 | f = message.getMessage(); 1274 | if (f.length > 0) { 1275 | writer.writeString( 1276 | 4, 1277 | f 1278 | ); 1279 | } 1280 | }; 1281 | 1282 | 1283 | /** 1284 | * optional int32 id = 1; 1285 | * @return {number} 1286 | */ 1287 | proto.randomPackage.StreamMessage.prototype.getId = function() { 1288 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); 1289 | }; 1290 | 1291 | 1292 | /** 1293 | * @param {number} value 1294 | * @return {!proto.randomPackage.StreamMessage} returns this 1295 | */ 1296 | proto.randomPackage.StreamMessage.prototype.setId = function(value) { 1297 | return jspb.Message.setProto3IntField(this, 1, value); 1298 | }; 1299 | 1300 | 1301 | /** 1302 | * optional string sender_name = 2; 1303 | * @return {string} 1304 | */ 1305 | proto.randomPackage.StreamMessage.prototype.getSenderName = function() { 1306 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); 1307 | }; 1308 | 1309 | 1310 | /** 1311 | * @param {string} value 1312 | * @return {!proto.randomPackage.StreamMessage} returns this 1313 | */ 1314 | proto.randomPackage.StreamMessage.prototype.setSenderName = function(value) { 1315 | return jspb.Message.setProto3StringField(this, 2, value); 1316 | }; 1317 | 1318 | 1319 | /** 1320 | * optional string sender_avatar = 3; 1321 | * @return {string} 1322 | */ 1323 | proto.randomPackage.StreamMessage.prototype.getSenderAvatar = function() { 1324 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); 1325 | }; 1326 | 1327 | 1328 | /** 1329 | * @param {string} value 1330 | * @return {!proto.randomPackage.StreamMessage} returns this 1331 | */ 1332 | proto.randomPackage.StreamMessage.prototype.setSenderAvatar = function(value) { 1333 | return jspb.Message.setProto3StringField(this, 3, value); 1334 | }; 1335 | 1336 | 1337 | /** 1338 | * optional string message = 4; 1339 | * @return {string} 1340 | */ 1341 | proto.randomPackage.StreamMessage.prototype.getMessage = function() { 1342 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); 1343 | }; 1344 | 1345 | 1346 | /** 1347 | * @param {string} value 1348 | * @return {!proto.randomPackage.StreamMessage} returns this 1349 | */ 1350 | proto.randomPackage.StreamMessage.prototype.setMessage = function(value) { 1351 | return jspb.Message.setProto3StringField(this, 4, value); 1352 | }; 1353 | 1354 | 1355 | /** 1356 | * @enum {number} 1357 | */ 1358 | proto.randomPackage.Status = { 1359 | UNKOWN: 0, 1360 | ONLINE: 1, 1361 | OFFLINE: 2 1362 | }; 1363 | 1364 | goog.object.extend(exports, proto.randomPackage); 1365 | --------------------------------------------------------------------------------