├── .gitignore
├── README.md
├── bin
├── client
│ ├── dist
│ │ └── index.html
│ ├── get-data.js
│ ├── index.html
│ └── src
│ │ ├── PageInterface.ts
│ │ ├── components
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── Data.tsx
│ │ ├── Header.css
│ │ ├── Header.tsx
│ │ ├── Main.css
│ │ ├── Main.tsx
│ │ ├── Mutations.css
│ │ ├── Mutations.tsx
│ │ ├── Overview.css
│ │ ├── Overview.tsx
│ │ ├── Queries.css
│ │ ├── Queries.tsx
│ │ ├── Resolvers.css
│ │ └── Resolvers.tsx
│ │ ├── index.css
│ │ ├── index.html
│ │ └── index.tsx
├── db
│ ├── data.json
│ ├── err.json
│ └── fileController.js
├── exec.js
├── goblin.js
└── server
│ ├── express.js
│ └── wsServer.js
├── package-lock.json
├── package.json
├── src
├── enableTracking.js
├── grabFields.js
├── main.js
└── mapResolvers.js
├── test
├── enableMonitoring.test.js
└── enableTracking.test.js
├── testResolvers
└── mockResolvers.js
├── tsconfig.json
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # goblinsharks
2 | la30-goblinsharks production project repository
3 |
--------------------------------------------------------------------------------
/bin/client/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/bin/client/get-data.js:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | // connection.addEventListener('open',()=>{
7 | // console.log('websocket connection established to port 9000');
8 | // })
9 |
10 | // connection.addEventListener('message',(e) => {
11 | // console.log('message received through socket connection')
12 | // console.log(e)
13 | // })
14 |
15 | const connection = new WebSocket('ws://localhost:9000');
16 | connection.onopen = () => {
17 | console.log("socket is open on port 9000")
18 | connection.onmessage = (message) => {
19 | console.log(message);
20 | console.log('socket server message: ' + (message.data));
21 |
22 | fetch('./db/data.json')
23 | .then((data)=>data.json())
24 | .then((res)=>{
25 | console.log(res);
26 | })
27 | }
28 | }
29 |
30 |
31 | window.onload = () => {
32 | console.log(data)
33 | fetch('../db/data.json')
34 | .then((data)=>data.json())
35 | .then((res)=>{
36 | const vals = Object.values(res);
37 | vals.forEach((value)=>{
38 | document.querySelector('#data').append(`${JSON.stringify(value)}`);
39 | })
40 | })
41 | }
42 |
43 |
44 |
--------------------------------------------------------------------------------
/bin/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/bin/client/src/PageInterface.ts:
--------------------------------------------------------------------------------
1 | export default interface Page {
2 | color: string;
3 | }
4 |
--------------------------------------------------------------------------------
/bin/client/src/components/App.css:
--------------------------------------------------------------------------------
1 | #modeWrapper {
2 | display: flex;
3 | justify-content: center;
4 | };
--------------------------------------------------------------------------------
/bin/client/src/components/App.tsx:
--------------------------------------------------------------------------------
1 | // src/components/App.tsx
2 | import * as React from 'react';
3 | import { useState, useEffect } from 'react';
4 |
5 | // Components.
6 | import Header from './Header';
7 | import Overview from './Overview';
8 | import Queries from './Queries';
9 | import Mutations from './Mutations';
10 | import Resolvers from './Resolvers';
11 |
12 | // Style.
13 | import "./App.css";
14 |
15 | // TODO: Make this responsive to changes.
16 | import { processedData, getOverviewData, getResolversData } from './Data';
17 |
18 | // Renders App.
19 | const App = () => {
20 | // An array of Modes.
21 | const [ data, updateData ] = useState(processedData);
22 |
23 | // This establishes socket connection. Invokes once.
24 | useEffect(() => {
25 | // Connection.
26 | const connection = new WebSocket('ws://localhost:9000');
27 |
28 | // On open connection, update data.
29 | connection.onopen = () => {
30 | console.log("socket is open on port 9000")
31 | fetch('./db/data.json')
32 | .then(data => data.json())
33 | .then(res => updateData({ overview: getOverviewData(res), resolvers: getResolversData(res) }))
34 | .catch(e => console.log('error fetching from json', e))
35 |
36 | // On message listener. Updates data according to message body.
37 | connection.onmessage = (message) => {
38 | console.log('socket server message: ' + (message.data));
39 |
40 | fetch('./db/data.json')
41 | .then(data => data.json())
42 | .then(res => updateData({ overview: getOverviewData(res), resolvers: getResolversData(res) }))
43 | .catch(e => console.log('error fetching from json', e))
44 | }
45 | }
46 | }, [])
47 |
48 | // Hook to update the current mode.
49 | const [currentMode, updateMode] = useState('overview');
50 |
51 | // useEffect hook to change the css styling of the active mode.
52 | useEffect(() => {
53 | // Remove 'active' from class names.
54 | Array.from(document.getElementsByClassName("header-navigation-item"))
55 | .forEach(el => el.classList.remove('active'));
56 | // Add 'active' to the current Mode css.
57 | document.getElementById("header-navigation-item-" + currentMode)!
58 | .classList.toggle('active');
59 | });
60 |
61 | // Initialize the current view.
62 | let currentView = ;
63 |
64 | // Conditionally render the following based on current mode.
65 | switch (currentMode) {
66 | case 'overview':
67 | currentView = ;
68 | break;
69 | case 'queries':
70 | currentView = ;
71 | break;
72 | case 'mutations':
73 | currentView = ;
74 | break;
75 | case 'resolvers':
76 | currentView = ;
77 | break;
78 | }
79 |
80 | // Render App with the following DOM.
81 | const modes = ['Overview', 'Resolvers'];
82 |
83 | // Render the following:
84 | return (
85 |
86 |
87 |
88 | {currentView}
89 |
90 |
91 | )
92 | }
93 |
94 | export default App
95 |
--------------------------------------------------------------------------------
/bin/client/src/components/Data.tsx:
--------------------------------------------------------------------------------
1 | // src/components/Data.tsx
2 |
3 | // TS types.
4 | type RequestObject = {
5 | speed: number,
6 | time: number,
7 | frequency: number,
8 | id: string
9 | }
10 |
11 | // Output object.
12 | const testingData = {
13 | Query:{ state: [] }
14 | }
15 | const processedData = {
16 | overview: getOverviewData(testingData),
17 | resolvers: getResolversData(testingData),
18 | };
19 |
20 | /**
21 | * For Preparing Overview data.
22 | * @param data
23 | */
24 | function getOverviewData (data: object) {
25 | // Init data to return.
26 | let minTS = Infinity;
27 | let maxTS = -Infinity;
28 |
29 | // Gets min and max TS.
30 | for (var entrypoint in data['Query']) {
31 | data['Query'][entrypoint].forEach((request: RequestObject) => {
32 | minTS = request.time < minTS ? request.time : minTS;
33 | maxTS = request.time > maxTS ? request.time : maxTS;
34 | }
35 | )};
36 |
37 | // Init object of processed data to return.
38 | const returnData = {
39 | summary: getOverviewSummaryData(data),
40 | requests: getOverviewRequestsData(data),
41 | response: getOverviewResponseData(data),
42 | resolvers: getOverviewResolversData(data)
43 | };
44 |
45 | // Gets summary data from 'data'.
46 | function getOverviewSummaryData (data: object) {
47 | // Init data to return.
48 | const rtnObj = {
49 | 'numTotalRequests': 0
50 | };
51 |
52 | // Count total requests.
53 | for (var entrypoint in data['Query']) {
54 | rtnObj.numTotalRequests += data['Query'][entrypoint].length;
55 | }
56 |
57 | // Return the data.
58 | return rtnObj;
59 | }
60 |
61 | /**
62 | * Gets Requests data from 'data'.
63 | * @params
64 | * @todo: account for empty bins.
65 | */
66 | function getOverviewRequestsData (data: object) {
67 | // Init data to return.
68 | const rtnObj = {
69 | 'times': [''],
70 | 'rpm': [null],
71 | 'ave': 0,
72 | 'count': 0
73 | };
74 |
75 | // Counts total requests.
76 | const tempData = { "count": {} };
77 | for (var entrypoint in data['Query']) {
78 | data['Query'][entrypoint].forEach((request: RequestObject) => {
79 | // Get the bin of the data.
80 | let bin = Number(Math.floor((request.time - minTS)/1000)*1000 + minTS);
81 | tempData["count"][bin] = bin in tempData["count"] ? tempData["count"][bin] + 1 : 1;
82 | })
83 | }
84 | // Cast the counts obj to array and sort.
85 | const tempDataAsSortedArray = Object.keys(tempData["count"])
86 | .map(key => [Number(key), tempData['count'][key]])
87 | .sort((a, b)=> a[0] - b[0]);
88 |
89 | rtnObj["times"] = tempDataAsSortedArray.map(el => new Date(el[0]).toTimeString().split(' ')[0]);
90 | rtnObj["rpm"] = tempDataAsSortedArray.map(el => el[1]);
91 |
92 | return rtnObj;
93 | };
94 |
95 | // Gets Response data from 'data'.
96 | function getOverviewResponseData (data: object) {
97 | // Init data to return.
98 | const rtnObj = {
99 | 'times': [''],
100 | '90': [null],
101 | 'ave': 0.0,
102 | 'count': 0
103 | };
104 |
105 | // Counts total requests.
106 | const tempData = { "speed": {} , "counts": {} };
107 | for (var entrypoint in data['Query']) {
108 | data['Query'][entrypoint].forEach((request: RequestObject) => {
109 | // Bin the results.
110 | let bin = Number(Math.floor((request.time - minTS)/1000)*1000 + minTS);
111 | tempData["counts"][bin] = bin in tempData["counts"] ? tempData["counts"][bin] + 1 : 1;
112 | tempData["speed"][bin] = bin in tempData["speed"] ?
113 | ((tempData["counts"][bin] - 1) * tempData["speed"][bin] / tempData["counts"][bin])
114 | + (request.speed / tempData["counts"][bin]) : request.speed;
115 |
116 | // Set the average.
117 | rtnObj['count']++;
118 | rtnObj['ave'] = ( rtnObj['ave'] * (rtnObj['count']-1) / rtnObj['count'] )
119 | + ( request.speed / rtnObj['count'] );
120 | })
121 | }
122 |
123 | // Cast the counts obj to array and sort.
124 | const tempDataAsSortedArray = Object.keys(tempData["speed"])
125 | .map(key => [Number(key), tempData['speed'][key]])
126 | .sort((a, b)=> a[0] - b[0]);
127 |
128 | rtnObj["times"] = tempDataAsSortedArray.map(el => new Date(el[0]).toTimeString().split(' ')[0]);
129 | rtnObj["90"] = tempDataAsSortedArray.map(el => el[1]);
130 |
131 | return rtnObj;
132 | };
133 |
134 | // Execution Times data.
135 | function getOverviewResolversData(data: object) {
136 | // Init an object to hold our analysis.
137 | const rtnObj = {
138 | 'times': [''],
139 | 'aveSpeed': [null]
140 | };
141 |
142 | const tempData = { "speed": {} , "counts": {} };
143 | // Init a recursive funtion to count nested resolvers.
144 | const recurseSpeed = (key: any, element: any) => {
145 | if (Array.isArray(element)) {
146 |
147 | element.forEach(request => {
148 | let bin = Number(Math.floor((request.time - minTS)/1000)*1000 + minTS);
149 | tempData["counts"][bin] = bin in tempData["counts"] ? tempData["counts"][bin] + 1 : 1;
150 | tempData["speed"][bin] = bin in tempData["speed"] ?
151 | ((tempData["counts"][bin] - 1) * tempData["speed"][bin] / tempData["counts"][bin])
152 | + (request.speed / tempData["counts"][bin]) : request.speed;
153 | });
154 |
155 | } else for (let el in element) recurseSpeed(key + ":" + el, element[el]);
156 | }
157 |
158 | // Iterate through top level Resolvers.
159 | for (let key in data) if (key !== "Query") recurseSpeed(key, data[key]);
160 |
161 | // Cast the counts obj to array and sort.
162 | const tempDataAsSortedArray = Object.keys(tempData["speed"])
163 | .map(key => [Number(key), tempData['speed'][key]])
164 | .sort((a, b)=> a[0] - b[0]);
165 |
166 | rtnObj["times"] = tempDataAsSortedArray.map(el => new Date(el[0]).toTimeString().split(' ')[0]);
167 | rtnObj["aveSpeed"] = tempDataAsSortedArray.map(el => el[1]);
168 |
169 | // Return
170 | return rtnObj;
171 | }
172 |
173 | // Return.
174 | return returnData;
175 | }
176 |
177 | /**
178 | * For Preparing Resolvers data.
179 | * @param data
180 | */
181 | function getResolversData(data: object) {
182 | const returnData = {
183 | invocationCounts: getInvocationCountsData(data),
184 | executionTimes: getExecutionTimesData(data),
185 | averageTime: 0.0,
186 | };
187 |
188 | // Invocation Counts data.
189 | function getInvocationCountsData(data: object) {
190 | // Init an object to hold our analysis.
191 | const rtnObj = {};
192 |
193 | // Init a recursive funtion to count nested resolvers.
194 | const recurseCount = (key: any, element: any) => {
195 | if (Array.isArray(element)) rtnObj[key] = element.length;
196 | else for (let el in element) recurseCount(key + ":" + el, element[el]);
197 | }
198 |
199 | // Fill out the top level Resolvers.
200 | for (let key in data) if (key !== "Query") recurseCount(key, data[key]);
201 |
202 | // Return
203 | return rtnObj;
204 | }
205 |
206 | // Execution Times data.
207 | function getExecutionTimesData(data: object) {
208 | // Init an object to hold our analysis.
209 | const rtnObj = {};
210 |
211 | // Init a recursive funtion to count nested resolvers.
212 | const recurseSpeed = (key: any, element: any) => {
213 | if (Array.isArray(element)) {
214 | let speedArr = element.map(request => request["speed"]);
215 | rtnObj[key]={
216 | ave: speedArr.reduce((a,c) => a+c) / speedArr.length,
217 | count: speedArr.length,
218 | };
219 | } else for (let el in element) recurseSpeed(key + ":" + el, element[el]);
220 | }
221 |
222 | // Iterate through top level Resolvers.
223 | for (let key in data) if (key !== "Query") recurseSpeed(key, data[key]);
224 |
225 | // Return
226 | return rtnObj;
227 | }
228 |
229 |
230 | // Get Average Times data.
231 | let sumAve = 0.0;
232 | let count = 0;
233 |
234 | for (let key in returnData.executionTimes) {
235 | count += returnData.executionTimes[key]['count']
236 | sumAve += returnData.executionTimes[key]['ave'] * returnData.executionTimes[key]['count'];
237 | }
238 |
239 | returnData['averageTime'] = sumAve / count;
240 |
241 | // Return.
242 | return returnData;
243 | }
244 |
245 | // Export.
246 | export { processedData, getOverviewData, getResolversData };
247 |
--------------------------------------------------------------------------------
/bin/client/src/components/Header.css:
--------------------------------------------------------------------------------
1 | .header {
2 | width: 100%;
3 | top: 0px;
4 | left: 0px;
5 | background-color: #000;
6 | color: #fff;
7 | display: flex;
8 | justify-content: space-between;
9 | align-items: center;
10 | font-family: 'Open Sans', sans-serif;
11 | padding: .5em;
12 | }
13 |
14 | .active {
15 | color: #fff !important;
16 | font-weight: 600;
17 | }
18 |
19 | .header .header-logo {
20 | display: flex;
21 | font-size: 2em;
22 | color: #fff;
23 | margin-left: 50px;
24 | }
25 |
26 | .header .header-navigation {
27 | justify-content: space-between;
28 | display: flex;
29 | }
30 |
31 | .header-navigation-item {
32 | margin: 0em 1em 0em 1em;
33 | text-transform: uppercase;
34 | cursor: pointer;
35 | color: #a0a0a0;
36 | }
37 |
38 | .header .header-moreinformation {
39 | justify-content: space-between;
40 | display: flex;
41 | margin-right: 50px;
42 | }
43 |
44 | .svg_icons{
45 | transform: scale(1.8);
46 | padding: 0em .5em 0em .5em;
47 | }
48 |
--------------------------------------------------------------------------------
/bin/client/src/components/Header.tsx:
--------------------------------------------------------------------------------
1 | // src/components/Header.tsx
2 |
3 | import * as React from 'react';
4 | import { HelpOutline, SettingsApplications, Refresh } from '@material-ui/icons';
5 |
6 | import './Header.css'
7 |
8 | // Header Props TS typedef.
9 | type HeaderProps = { modes: Array, updateMode: Function }
10 |
11 | // Header functional component def.
12 | function Header({ modes, updateMode }: HeaderProps) {
13 | // An array of mode buttons for the header.
14 | const modeNavigationItems = modes.map(modeName => {
15 | return (
16 |
22 | )
23 | });
24 |
25 | // Header FC renders the following DOM:
26 | return (
27 |
28 |
Goblin Monitor
29 |
{modeNavigationItems}
30 |
31 |
32 |
33 |
34 |
35 |
36 | );
37 | }
38 |
39 | export default Header;
40 |
--------------------------------------------------------------------------------
/bin/client/src/components/Main.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/goblinsharks/d573085a9e1d2cdd6d944025ee8686da1f140afa/bin/client/src/components/Main.css
--------------------------------------------------------------------------------
/bin/client/src/components/Main.tsx:
--------------------------------------------------------------------------------
1 | // src/components/Hello.tsx
2 |
3 | import * as React from 'react';
4 |
5 | import './Main.css'
6 |
7 | function Main({}) {
8 | return (
9 |
10 |
11 | );
12 | }
13 |
14 | export default Main;
15 |
--------------------------------------------------------------------------------
/bin/client/src/components/Mutations.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/goblinsharks/d573085a9e1d2cdd6d944025ee8686da1f140afa/bin/client/src/components/Mutations.css
--------------------------------------------------------------------------------
/bin/client/src/components/Mutations.tsx:
--------------------------------------------------------------------------------
1 | // src/components/Overview.tsx
2 |
3 | import * as React from 'react';
4 |
5 | import './Mutations.css'
6 |
7 | // Header Props TS typedef.
8 | // type OverviewProps = {
9 | // modes: Array,
10 | // updateMode: Function
11 | // }
12 |
13 | type MutationsProps = {
14 | data: Object
15 | }
16 |
17 | function Mutations({ data }: MutationsProps) {
18 | return (
19 |
20 |
21 | )
22 | }
23 |
24 | export default Mutations;
25 |
--------------------------------------------------------------------------------
/bin/client/src/components/Overview.css:
--------------------------------------------------------------------------------
1 | #modeOverview {
2 | position: absolute;
3 | background: #f3f3f3;
4 | width: 1000px;
5 | bottom: 0px;
6 | top: 100px;
7 | padding: 10px;
8 | }
9 |
10 | .overview-content {
11 | padding: 5px;
12 | margin-bottom: 15px;
13 | }
14 |
15 | .overview-content-whitebg {
16 | background: #fff;
17 | padding: 5px;
18 | }
19 |
20 | .content-title {
21 | font-size: 1.5em;
22 | margin-bottom: 10px;
23 | }
24 |
25 | .bold {
26 | font-weight: 600;
27 | }
28 |
29 | #overview-summary-statistics-wrapper {
30 | justify-content: space-around;
31 | display: flex;
32 | }
33 |
34 | .overview-summary-statistic-stat {
35 | font-size: 1.5em;
36 | font-weight: 600;
37 | }
38 |
39 | .overview-summary-statistic-val {
40 | color: orange;
41 | font-size: 3em;
42 | }
43 |
44 | .overview-summary-statistic-statval {
45 | text-align: center;
46 | }
47 |
48 | .chart-wrapper {
49 | height: 200px;
50 | width: 100%;
51 | padding: 5px 0px 5px 0px;
52 | }
53 |
54 |
55 |
56 | .modeOverview .overview-summary {
57 |
58 | }
59 |
60 | .modeOverview .overview-requests {
61 |
62 | }
63 |
64 | .modeOverview .overview-response {
65 |
66 | }
67 |
68 | .modeOverview .overview-errors {
69 |
70 | }
--------------------------------------------------------------------------------
/bin/client/src/components/Overview.tsx:
--------------------------------------------------------------------------------
1 | // src/components/Overview.tsx
2 |
3 | import * as React from 'react';
4 | import { Line } from 'react-chartjs-2';
5 | // let = require("react-chartjs-2").Line;
6 |
7 |
8 | import './Overview.css'
9 |
10 | // Header Props TS typedef.
11 | // type OverviewProps = {
12 | // modes: Array,
13 | // updateMode: Function
14 | // }
15 |
16 | interface OverviewProps {
17 | overviewData: OverviewData,
18 | resolversData: ResolversData
19 | }
20 |
21 | type OverviewData = {
22 | summary: Object,
23 | requests: Object,
24 | response: Object,
25 | resolvers: Object
26 | }
27 |
28 | type ResolversData = {
29 | invocationCounts: Object,
30 | executionTimes: Object,
31 | averageTime: Number
32 | }
33 |
34 | // type OverviewSummaryProps = {
35 | // summary: OverviewSummaryData
36 | // }
37 |
38 | // type OverviewSummaryData = {
39 | // numRequests: number
40 | // }
41 |
42 |
43 | // type OverviewRequestsProps = {
44 | // requests: Object
45 | // }
46 |
47 |
48 | /**
49 | * Overview-Summary functional component.
50 | * @param props
51 | */
52 | function OverviewSummary(props: any) {
53 | // Render the summary statistics according to the following.
54 | return (
55 |
56 |
57 | Summary
58 |
59 |
60 |
61 |
62 |
64 |
Total Requests
65 |
{props.summary.numTotalRequests}
66 |
67 |
68 |
70 |
Average Response Time (ms)
71 |
{props.averageTime.toFixed(2)}
72 |
73 |
74 |
75 |
76 |
77 | )
78 | }
79 |
80 | /**
81 | * Overview-Requests functional component.
82 | *
83 | * @param props
84 | */
85 | function OverviewRequests(props: any) {
86 | // Chart.js data.
87 | const chartData = {
88 | labels: props.requests.times.slice(-100),
89 | datasets: [
90 | {
91 | label: 'Requests Per Second',
92 | fill: false,
93 | lineTension: 0.1,
94 | backgroundColor: 'rgba(75,192,192,0.4)',
95 | borderColor: 'rgba(75,192,192,1)',
96 | // borderCapStyle: 'butt',
97 | borderDash: [],
98 | borderDashOffset: 0.0,
99 | // borderJoinStyle: 'miter',
100 | pointBorderColor: 'rgba(75,192,192,1)',
101 | pointBackgroundColor: '#fff',
102 | pointBorderWidth: 1,
103 | pointHoverRadius: 5,
104 | pointHoverBackgroundColor: 'rgba(75,192,192,1)',
105 | pointHoverBorderColor: 'rgba(220,220,220,1)',
106 | pointHoverBorderWidth: 2,
107 | pointRadius: 1,
108 | pointHitRadius: 10,
109 | data: props.requests.rpm.slice(-100)
110 | }
111 | ]
112 | };
113 |
114 | // Chart.js options.
115 | const chartOptions = {
116 | maintainAspectRatio: false,
117 | legend: { display: false }
118 | }
119 |
120 | // Render the following:
121 | return (
122 |
123 |
125 | Requests Per Second this session:
126 |
127 |
129 |
130 |
131 |
132 | )
133 | }
134 |
135 | /**
136 | * Overview-Response functional component.
137 | *
138 | * @param props
139 | */
140 | function OverviewResponse(props: any) {
141 | // Chart.js data.
142 | const chartData = {
143 | labels: props.resolvers['times'].slice(-100),
144 | datasets: [
145 | {
146 | label: 'Response Time',
147 | fill: false,
148 | lineTension: 0.1,
149 | backgroundColor: 'rgba(75,192,192,0.4)',
150 | borderColor: 'rgba(75,192,192,1)',
151 | // borderCapStyle: 'butt',
152 | borderDash: [],
153 | borderDashOffset: 0.0,
154 | // borderJoinStyle: 'miter',
155 | pointBorderColor: 'rgba(75,192,192,1)',
156 | pointBackgroundColor: '#fff',
157 | pointBorderWidth: 1,
158 | pointHoverRadius: 5,
159 | pointHoverBackgroundColor: 'rgba(75,192,192,1)',
160 | pointHoverBorderColor: 'rgba(220,220,220,1)',
161 | pointHoverBorderWidth: 2,
162 | pointRadius: 1,
163 | pointHitRadius: 10,
164 | data: props.resolvers["aveSpeed"].slice(-100)
165 | }
166 | ]
167 | };
168 |
169 | // Chart.js options.
170 | const chartOptions = {
171 | maintainAspectRatio: false,
172 | legend: { display: false }
173 | }
174 |
175 | // Render the following:
176 | return (
177 |
178 |
179 | Response Time 90 (ms) this session:
180 |
181 |
182 |
183 |
184 |
185 | )
186 | }
187 |
188 | /**
189 | * Overview-Errors functional component.
190 | */
191 | function OverviewErrors() {
192 | return (
193 |
195 |
196 | )
197 | }
198 |
199 | /**
200 | * Overview parent functional component. Renders 'Summary', 'Requests',
201 | * 'Response', and 'Errors' containers.
202 | *
203 | * @param props
204 | */
205 | function Overview(props: OverviewProps) {
206 | return (
207 |
208 |
209 |
210 |
211 |
212 |
213 | )
214 | }
215 |
216 | // Export.
217 | export default Overview;
218 |
--------------------------------------------------------------------------------
/bin/client/src/components/Queries.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/goblinsharks/d573085a9e1d2cdd6d944025ee8686da1f140afa/bin/client/src/components/Queries.css
--------------------------------------------------------------------------------
/bin/client/src/components/Queries.tsx:
--------------------------------------------------------------------------------
1 | // src/components/Overview.tsx
2 |
3 | import * as React from 'react';
4 |
5 | import './Queries.css'
6 |
7 | // Header Props TS typedef.
8 | // type OverviewProps = {
9 | // modes: Array,
10 | // updateMode: Function
11 | // }
12 |
13 | type QueriesProps = {
14 | data: Object
15 | }
16 | function Queries({ data }: QueriesProps) {
17 | return (
18 |
19 |
20 | )
21 | }
22 |
23 | export default Queries;
24 |
--------------------------------------------------------------------------------
/bin/client/src/components/Resolvers.css:
--------------------------------------------------------------------------------
1 | #modeResolvers {
2 | position: absolute;
3 | background: #f3f3f3;
4 | width: 1000px;
5 | bottom: 0px;
6 | top: 100px;
7 | padding: 10px;
8 | }
9 |
10 |
11 | .resolverListItem {
12 | display: flex;
13 | justify-content: space-between;
14 | padding: 10px;
15 | font-size: 1.2em;
16 | }
17 |
18 | .resolvers-content {
19 | padding: 5px;
20 | margin-bottom: 15px;
21 | }
22 |
23 |
24 | #resolvers-popularity{
25 |
26 | }
27 |
28 | #resolvers-title{
29 |
30 | }
31 |
32 |
33 |
34 | #resolvers-popularitylist-wrapper {
35 | height: 200px;
36 | overflow: scroll;
37 | }
38 |
39 | .content-title {
40 | font-size: 1.5em;
41 | margin-bottom: 10px;
42 | }
43 |
44 | .resolvers-content-whitebg {
45 | background: #fff;
46 | padding: 5px;
47 | }
--------------------------------------------------------------------------------
/bin/client/src/components/Resolvers.tsx:
--------------------------------------------------------------------------------
1 | // src/components/Overview.tsx
2 |
3 | import * as React from 'react';
4 |
5 | import './Resolvers.css'
6 |
7 |
8 | // ResolversProps type.
9 | type ResolversProps = {
10 | resolversData: ResolversData,
11 | }
12 |
13 | // ResolversData type.
14 | type ResolversData = {
15 | invocationCounts: Object,
16 | executionTimes: Object,
17 | }
18 |
19 | /**
20 | * Renders the list of resolvers sorted by invocation count, descending.
21 | * @param props
22 | */
23 | function ResolversInvocationCount(props: any) {
24 | // Sort the object of objects by count popularity descending.
25 | const resolverListSortedByPopularity =
26 | Object.keys(props.invocationCounts).map(path => {
27 | return [path, props.invocationCounts[path]];
28 | }).sort((a, b) => b[1] - a[1]);
29 |
30 | // Create array of DOM elements for the resolvers.
31 | const resolverListItems = resolverListSortedByPopularity.map((item, idx) => {
32 | return (
33 |
34 |
{item[0]}
35 |
{item[1]}
36 |
37 | )
38 | });
39 |
40 | // Render the following:
41 | return (
42 |
43 |
44 |
45 | Resolver Operations by invocation count:
46 |
47 |
48 |
49 | {resolverListItems}
50 |
51 |
52 | )
53 | }
54 |
55 |
56 | /**
57 | * Renders the list of resolvers sorted by average execution time, descending.
58 | * @param props
59 | */
60 | function ResolversExecutionTime(props: any) {
61 | // Sort the object of objects by count popularity descending.
62 | const resolverListSortedByExecutionTime =
63 | Object.keys(props.executionTimes).map(path => {
64 | return [path, props.executionTimes[path]['ave']];
65 | }).sort((a, b) => b[1] - a[1]);
66 |
67 | // Create array of DOM elements for the resolvers.
68 | const resolverListItems = resolverListSortedByExecutionTime.map((item, idx) => {
69 | return (
70 |
71 |
{item[0]}
72 |
{item[1].toFixed(2)}
73 |
74 | )
75 | });
76 |
77 | // Render the following:
78 | return (
79 |
80 |
81 |
82 | Resolver Operations by average execution time (ms):
83 |
84 |
85 |
86 | {resolverListItems}
87 |
88 |
89 | )
90 | }
91 |
92 |
93 | /**
94 | * Resolvers FC renders the following.
95 | * @param props
96 | */
97 | function Resolvers(props: ResolversProps) {
98 | return (
99 |
100 |
101 |
102 |
103 | )
104 | }
105 |
106 | export default Resolvers;
107 |
--------------------------------------------------------------------------------
/bin/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/bin/client/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/bin/client/src/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import * as ReactDOM from 'react-dom';
3 | import App from './components/App';
4 | import './index.css';
5 | // import registerServiceWorker from './registerServiceWorker';
6 |
7 |
8 |
9 | ReactDOM.render(
10 | ,
11 | document.getElementById('root') as HTMLElement
12 | );
13 | // registerServiceWorker();
14 |
--------------------------------------------------------------------------------
/bin/db/err.json:
--------------------------------------------------------------------------------
1 | {
2 | "errors": [
3 | {
4 | "message": "function dsum(bigint) does not exist",
5 | "path": [
6 | "state",
7 | "total_dosage"
8 | ],
9 | "time": 1566949016121,
10 | "stacktrace": [
11 | "error: function dsum(bigint) does not exist",
12 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
13 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
14 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
15 | " at Socket.emit (events.js:198:13)",
16 | " at addChunk (_stream_readable.js:288:12)",
17 | " at readableAddChunk (_stream_readable.js:269:11)",
18 | " at Socket.Readable.push (_stream_readable.js:224:10)",
19 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
20 | ]
21 | },
22 | {
23 | "message": "function dsum(bigint) does not exist",
24 | "path": [
25 | "state",
26 | "total_dosage"
27 | ],
28 | "time": 1566952368434,
29 | "stacktrace": [
30 | "error: function dsum(bigint) does not exist",
31 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
32 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
33 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
34 | " at Socket.emit (events.js:198:13)",
35 | " at addChunk (_stream_readable.js:288:12)",
36 | " at readableAddChunk (_stream_readable.js:269:11)",
37 | " at Socket.Readable.push (_stream_readable.js:224:10)",
38 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
39 | ]
40 | },
41 | {
42 | "message": "function dsum(bigint) does not exist",
43 | "path": [
44 | "state",
45 | "total_dosage"
46 | ],
47 | "time": 1566952452448,
48 | "stacktrace": [
49 | "error: function dsum(bigint) does not exist",
50 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
51 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
52 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
53 | " at Socket.emit (events.js:198:13)",
54 | " at addChunk (_stream_readable.js:288:12)",
55 | " at readableAddChunk (_stream_readable.js:269:11)",
56 | " at Socket.Readable.push (_stream_readable.js:224:10)",
57 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
58 | ]
59 | },
60 | {
61 | "message": "function dsum(bigint) does not exist",
62 | "path": [
63 | "state",
64 | "total_dosage"
65 | ],
66 | "time": 1566952533598,
67 | "stacktrace": [
68 | "error: function dsum(bigint) does not exist",
69 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
70 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
71 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
72 | " at Socket.emit (events.js:198:13)",
73 | " at addChunk (_stream_readable.js:288:12)",
74 | " at readableAddChunk (_stream_readable.js:269:11)",
75 | " at Socket.Readable.push (_stream_readable.js:224:10)",
76 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
77 | ]
78 | },
79 | {
80 | "message": "function dsum(bigint) does not exist",
81 | "path": [
82 | "state",
83 | "total_dosage"
84 | ],
85 | "time": 1566952594895,
86 | "stacktrace": [
87 | "error: function dsum(bigint) does not exist",
88 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
89 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
90 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
91 | " at Socket.emit (events.js:198:13)",
92 | " at addChunk (_stream_readable.js:288:12)",
93 | " at readableAddChunk (_stream_readable.js:269:11)",
94 | " at Socket.Readable.push (_stream_readable.js:224:10)",
95 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
96 | ]
97 | },
98 | {
99 | "message": "function dsum(bigint) does not exist",
100 | "path": [
101 | "state",
102 | "total_dosage"
103 | ],
104 | "time": 1566952897304,
105 | "stacktrace": [
106 | "error: function dsum(bigint) does not exist",
107 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
108 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
109 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
110 | " at Socket.emit (events.js:198:13)",
111 | " at addChunk (_stream_readable.js:288:12)",
112 | " at readableAddChunk (_stream_readable.js:269:11)",
113 | " at Socket.Readable.push (_stream_readable.js:224:10)",
114 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
115 | ]
116 | },
117 | {
118 | "message": "function dsum(bigint) does not exist",
119 | "path": [
120 | "state",
121 | "total_dosage"
122 | ],
123 | "time": 1566952898799,
124 | "stacktrace": [
125 | "error: function dsum(bigint) does not exist",
126 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
127 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
128 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
129 | " at Socket.emit (events.js:198:13)",
130 | " at addChunk (_stream_readable.js:288:12)",
131 | " at readableAddChunk (_stream_readable.js:269:11)",
132 | " at Socket.Readable.push (_stream_readable.js:224:10)",
133 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
134 | ]
135 | },
136 | {
137 | "message": "function dsum(bigint) does not exist",
138 | "path": [
139 | "state",
140 | "total_dosage"
141 | ],
142 | "time": 1566952899705,
143 | "stacktrace": [
144 | "error: function dsum(bigint) does not exist",
145 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
146 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
147 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
148 | " at Socket.emit (events.js:198:13)",
149 | " at addChunk (_stream_readable.js:288:12)",
150 | " at readableAddChunk (_stream_readable.js:269:11)",
151 | " at Socket.Readable.push (_stream_readable.js:224:10)",
152 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
153 | ]
154 | },
155 | {
156 | "message": "function dsum(bigint) does not exist",
157 | "path": [
158 | "state",
159 | "total_dosage"
160 | ],
161 | "time": 1566952900146,
162 | "stacktrace": [
163 | "error: function dsum(bigint) does not exist",
164 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
165 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
166 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
167 | " at Socket.emit (events.js:198:13)",
168 | " at addChunk (_stream_readable.js:288:12)",
169 | " at readableAddChunk (_stream_readable.js:269:11)",
170 | " at Socket.Readable.push (_stream_readable.js:224:10)",
171 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
172 | ]
173 | },
174 | {
175 | "message": "function dsum(bigint) does not exist",
176 | "path": [
177 | "state",
178 | "total_dosage"
179 | ],
180 | "time": 1566952900571,
181 | "stacktrace": [
182 | "error: function dsum(bigint) does not exist",
183 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
184 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
185 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
186 | " at Socket.emit (events.js:198:13)",
187 | " at addChunk (_stream_readable.js:288:12)",
188 | " at readableAddChunk (_stream_readable.js:269:11)",
189 | " at Socket.Readable.push (_stream_readable.js:224:10)",
190 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
191 | ]
192 | },
193 | {
194 | "message": "function dsum(bigint) does not exist",
195 | "path": [
196 | "state",
197 | "total_dosage"
198 | ],
199 | "time": 1566952931366,
200 | "stacktrace": [
201 | "error: function dsum(bigint) does not exist",
202 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
203 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
204 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
205 | " at Socket.emit (events.js:198:13)",
206 | " at addChunk (_stream_readable.js:288:12)",
207 | " at readableAddChunk (_stream_readable.js:269:11)",
208 | " at Socket.Readable.push (_stream_readable.js:224:10)",
209 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
210 | ]
211 | },
212 | {
213 | "message": "function dsum(bigint) does not exist",
214 | "path": [
215 | "state",
216 | "total_dosage"
217 | ],
218 | "time": 1566952934292,
219 | "stacktrace": [
220 | "error: function dsum(bigint) does not exist",
221 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
222 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
223 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
224 | " at Socket.emit (events.js:198:13)",
225 | " at addChunk (_stream_readable.js:288:12)",
226 | " at readableAddChunk (_stream_readable.js:269:11)",
227 | " at Socket.Readable.push (_stream_readable.js:224:10)",
228 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
229 | ]
230 | },
231 | {
232 | "message": "function dsum(bigint) does not exist",
233 | "path": [
234 | "state",
235 | "total_dosage"
236 | ],
237 | "time": 1566952937298,
238 | "stacktrace": [
239 | "error: function dsum(bigint) does not exist",
240 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
241 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
242 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
243 | " at Socket.emit (events.js:198:13)",
244 | " at addChunk (_stream_readable.js:288:12)",
245 | " at readableAddChunk (_stream_readable.js:269:11)",
246 | " at Socket.Readable.push (_stream_readable.js:224:10)",
247 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
248 | ]
249 | },
250 | {
251 | "message": "function dsum(bigint) does not exist",
252 | "path": [
253 | "state",
254 | "total_dosage"
255 | ],
256 | "time": 1566952937891,
257 | "stacktrace": [
258 | "error: function dsum(bigint) does not exist",
259 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
260 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
261 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
262 | " at Socket.emit (events.js:198:13)",
263 | " at addChunk (_stream_readable.js:288:12)",
264 | " at readableAddChunk (_stream_readable.js:269:11)",
265 | " at Socket.Readable.push (_stream_readable.js:224:10)",
266 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
267 | ]
268 | },
269 | {
270 | "message": "function dsum(bigint) does not exist",
271 | "path": [
272 | "state",
273 | "total_dosage"
274 | ],
275 | "time": 1566952964594,
276 | "stacktrace": [
277 | "error: function dsum(bigint) does not exist",
278 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
279 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
280 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
281 | " at Socket.emit (events.js:198:13)",
282 | " at addChunk (_stream_readable.js:288:12)",
283 | " at readableAddChunk (_stream_readable.js:269:11)",
284 | " at Socket.Readable.push (_stream_readable.js:224:10)",
285 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
286 | ]
287 | },
288 | {
289 | "message": "function dsum(bigint) does not exist",
290 | "path": [
291 | "state",
292 | "total_dosage"
293 | ],
294 | "time": 1566952967243,
295 | "stacktrace": [
296 | "error: function dsum(bigint) does not exist",
297 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
298 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
299 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
300 | " at Socket.emit (events.js:198:13)",
301 | " at addChunk (_stream_readable.js:288:12)",
302 | " at readableAddChunk (_stream_readable.js:269:11)",
303 | " at Socket.Readable.push (_stream_readable.js:224:10)",
304 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
305 | ]
306 | },
307 | {
308 | "message": "function dsum(bigint) does not exist",
309 | "path": [
310 | "state",
311 | "total_dosage"
312 | ],
313 | "time": 1566952976226,
314 | "stacktrace": [
315 | "error: function dsum(bigint) does not exist",
316 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
317 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
318 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
319 | " at Socket.emit (events.js:198:13)",
320 | " at addChunk (_stream_readable.js:288:12)",
321 | " at readableAddChunk (_stream_readable.js:269:11)",
322 | " at Socket.Readable.push (_stream_readable.js:224:10)",
323 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
324 | ]
325 | },
326 | {
327 | "message": "function dsum(bigint) does not exist",
328 | "path": [
329 | "state",
330 | "total_dosage"
331 | ],
332 | "time": 1566952978091,
333 | "stacktrace": [
334 | "error: function dsum(bigint) does not exist",
335 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
336 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
337 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
338 | " at Socket.emit (events.js:198:13)",
339 | " at addChunk (_stream_readable.js:288:12)",
340 | " at readableAddChunk (_stream_readable.js:269:11)",
341 | " at Socket.Readable.push (_stream_readable.js:224:10)",
342 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
343 | ]
344 | },
345 | {
346 | "message": "function dsum(bigint) does not exist",
347 | "path": [
348 | "state",
349 | "total_dosage"
350 | ],
351 | "time": 1566952978553,
352 | "stacktrace": [
353 | "error: function dsum(bigint) does not exist",
354 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
355 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
356 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
357 | " at Socket.emit (events.js:198:13)",
358 | " at addChunk (_stream_readable.js:288:12)",
359 | " at readableAddChunk (_stream_readable.js:269:11)",
360 | " at Socket.Readable.push (_stream_readable.js:224:10)",
361 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
362 | ]
363 | },
364 | {
365 | "message": "function dsum(bigint) does not exist",
366 | "path": [
367 | "state",
368 | "total_dosage"
369 | ],
370 | "time": 1566953006365,
371 | "stacktrace": [
372 | "error: function dsum(bigint) does not exist",
373 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
374 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
375 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
376 | " at Socket.emit (events.js:198:13)",
377 | " at addChunk (_stream_readable.js:288:12)",
378 | " at readableAddChunk (_stream_readable.js:269:11)",
379 | " at Socket.Readable.push (_stream_readable.js:224:10)",
380 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
381 | ]
382 | },
383 | {
384 | "message": "function dsum(bigint) does not exist",
385 | "path": [
386 | "state",
387 | "total_dosage"
388 | ],
389 | "time": 1566953012198,
390 | "stacktrace": [
391 | "error: function dsum(bigint) does not exist",
392 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
393 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
394 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
395 | " at Socket.emit (events.js:198:13)",
396 | " at addChunk (_stream_readable.js:288:12)",
397 | " at readableAddChunk (_stream_readable.js:269:11)",
398 | " at Socket.Readable.push (_stream_readable.js:224:10)",
399 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
400 | ]
401 | },
402 | {
403 | "message": "function dsum(bigint) does not exist",
404 | "path": [
405 | "state",
406 | "total_dosage"
407 | ],
408 | "time": 1566953016411,
409 | "stacktrace": [
410 | "error: function dsum(bigint) does not exist",
411 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
412 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
413 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
414 | " at Socket.emit (events.js:198:13)",
415 | " at addChunk (_stream_readable.js:288:12)",
416 | " at readableAddChunk (_stream_readable.js:269:11)",
417 | " at Socket.Readable.push (_stream_readable.js:224:10)",
418 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
419 | ]
420 | },
421 | {
422 | "message": "function dsum(bigint) does not exist",
423 | "path": [
424 | "state",
425 | "total_dosage"
426 | ],
427 | "time": 1566953021769,
428 | "stacktrace": [
429 | "error: function dsum(bigint) does not exist",
430 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
431 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
432 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
433 | " at Socket.emit (events.js:198:13)",
434 | " at addChunk (_stream_readable.js:288:12)",
435 | " at readableAddChunk (_stream_readable.js:269:11)",
436 | " at Socket.Readable.push (_stream_readable.js:224:10)",
437 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
438 | ]
439 | },
440 | {
441 | "message": "syntax error at or near \"SELECT\"",
442 | "path": [
443 | "state",
444 | "name"
445 | ],
446 | "time": 1566953097526,
447 | "stacktrace": [
448 | "error: syntax error at or near \"SELECT\"",
449 | " at Connection.parseE (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:604:11)",
450 | " at Connection.parseMessage (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:401:19)",
451 | " at Socket. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/pg/lib/connection.js:121:22)",
452 | " at Socket.emit (events.js:198:13)",
453 | " at addChunk (_stream_readable.js:288:12)",
454 | " at readableAddChunk (_stream_readable.js:269:11)",
455 | " at Socket.Readable.push (_stream_readable.js:224:10)",
456 | " at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)"
457 | ]
458 | },
459 | {
460 | "message": "Cannot query field \"named\" on type \"State\". Did you mean \"name\"?",
461 | "time": 1566964064529,
462 | "stacktrace": [
463 | "GraphQLError: Cannot query field \"named\" on type \"State\". Did you mean \"name\"?",
464 | " at Object.Field (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/rules/FieldsOnCorrectType.js:53:31)",
465 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:324:29)",
466 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:375:25)",
467 | " at visit (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:242:26)",
468 | " at Object.validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/validate.js:73:24)",
469 | " at validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:211:32)",
470 | " at Object. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:124:42)",
471 | " at Generator.next ()",
472 | " at fulfilled (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:4:58)",
473 | " at process._tickCallback (internal/process/next_tick.js:68:7)"
474 | ]
475 | },
476 | {
477 | "message": "Cannot query field \"named\" on type \"State\". Did you mean \"name\"?",
478 | "time": 1566964067105,
479 | "stacktrace": [
480 | "GraphQLError: Cannot query field \"named\" on type \"State\". Did you mean \"name\"?",
481 | " at Object.Field (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/rules/FieldsOnCorrectType.js:53:31)",
482 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:324:29)",
483 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:375:25)",
484 | " at visit (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:242:26)",
485 | " at Object.validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/validate.js:73:24)",
486 | " at validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:211:32)",
487 | " at Object. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:124:42)",
488 | " at Generator.next ()",
489 | " at fulfilled (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:4:58)",
490 | " at process._tickCallback (internal/process/next_tick.js:68:7)"
491 | ]
492 | },
493 | {
494 | "message": "Cannot query field \"named\" on type \"State\". Did you mean \"name\"?",
495 | "time": 1566964067266,
496 | "stacktrace": [
497 | "GraphQLError: Cannot query field \"named\" on type \"State\". Did you mean \"name\"?",
498 | " at Object.Field (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/rules/FieldsOnCorrectType.js:53:31)",
499 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:324:29)",
500 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:375:25)",
501 | " at visit (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:242:26)",
502 | " at Object.validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/validate.js:73:24)",
503 | " at validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:211:32)",
504 | " at Object. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:124:42)",
505 | " at Generator.next ()",
506 | " at fulfilled (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:4:58)",
507 | " at process._tickCallback (internal/process/next_tick.js:68:7)"
508 | ]
509 | },
510 | {
511 | "message": "Cannot query field \"nameadsada\" on type \"State\".",
512 | "time": 1566964076503,
513 | "stacktrace": [
514 | "GraphQLError: Cannot query field \"nameadsada\" on type \"State\".",
515 | " at Object.Field (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/rules/FieldsOnCorrectType.js:53:31)",
516 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:324:29)",
517 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:375:25)",
518 | " at visit (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:242:26)",
519 | " at Object.validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/validate.js:73:24)",
520 | " at validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:211:32)",
521 | " at Object. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:124:42)",
522 | " at Generator.next ()",
523 | " at fulfilled (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:4:58)",
524 | " at process._tickCallback (internal/process/next_tick.js:68:7)"
525 | ]
526 | },
527 | {
528 | "message": "Cannot query field \"nameadsada\" on type \"State\".",
529 | "time": 1566964076888,
530 | "stacktrace": [
531 | "GraphQLError: Cannot query field \"nameadsada\" on type \"State\".",
532 | " at Object.Field (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/rules/FieldsOnCorrectType.js:53:31)",
533 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:324:29)",
534 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:375:25)",
535 | " at visit (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:242:26)",
536 | " at Object.validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/validate.js:73:24)",
537 | " at validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:211:32)",
538 | " at Object. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:124:42)",
539 | " at Generator.next ()",
540 | " at fulfilled (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:4:58)",
541 | " at process._tickCallback (internal/process/next_tick.js:68:7)"
542 | ]
543 | },
544 | {
545 | "message": "Cannot query field \"nameadsada\" on type \"State\".",
546 | "time": 1566964076991,
547 | "stacktrace": [
548 | "GraphQLError: Cannot query field \"nameadsada\" on type \"State\".",
549 | " at Object.Field (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/rules/FieldsOnCorrectType.js:53:31)",
550 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:324:29)",
551 | " at Object.enter (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:375:25)",
552 | " at visit (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/language/visitor.js:242:26)",
553 | " at Object.validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/graphql/validation/validate.js:73:24)",
554 | " at validate (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:211:32)",
555 | " at Object. (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:124:42)",
556 | " at Generator.next ()",
557 | " at fulfilled (/Users/andrewtang/Desktop/goblinsharks-apollo/node_modules/apollo-server-core/dist/requestPipeline.js:4:58)",
558 | " at process._tickCallback (internal/process/next_tick.js:68:7)"
559 | ]
560 | }
561 | ]
562 | }
--------------------------------------------------------------------------------
/bin/db/fileController.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs').promises;
2 | const path = require('path');
3 | const jsonData = require("./data.json");
4 | const errData = require('./err.json');
5 |
6 | async function createFile(filename) {
7 | try { // if file does not exist.
8 | const fileStatus = await fs.open(__dirname + '/data.json','r')
9 | }
10 | catch { // creates file.
11 | await fs.writeFile(__dirname + '/data.json',JSON.stringify({}))
12 | }
13 | }
14 |
15 | async function appendFile(queryKey,resolverName,speed,id){
16 | try{
17 | if (!jsonData[queryKey]){ // checking if the query type is defined - -
18 | jsonData[queryKey]= {};
19 | }
20 | if (!jsonData[queryKey][resolverName]){ // checking if the particular resolver has been defined.
21 | jsonData[queryKey][resolverName] = [];
22 | }
23 | jsonData[queryKey][resolverName].push({ // each resolver execution is logged with this object -
24 | speed: speed,
25 | frequency: 1,
26 | time: Date.now(),
27 | id: id
28 | })
29 | fs.writeFile(path.join(__dirname,'data.json'), JSON.stringify(jsonData,null,2)) // write new data to json
30 | } catch {
31 | console.log('unable to append')
32 | }
33 | };
34 |
35 | async function trackError (err, time) {
36 | try{
37 | const { extensions, message } = err; // declaring path separately to avoid overwriting path module
38 | const resolverPath = err.path
39 | const errObj = {
40 | message,
41 | path : resolverPath,
42 | time,
43 | stacktrace: extensions.exception.stacktrace
44 | }
45 | if (!errData.errors) {
46 | errData.errors = [];
47 | }
48 | errData.errors.push(errObj)
49 | console.log(errData)
50 | console.log('dirname inside of filecontroller', __dirname);
51 | await fs.writeFile(path.join(__dirname,'err.json'), JSON.stringify(errData,null,2))
52 | // await fs.writeFile(path.join(__dirname,'errors.json'), JSON.stringify({},null,2))
53 | } catch(e) {
54 | console.log(e)
55 | console.log('unable to track errors')
56 | }
57 | // console.log(err);
58 |
59 | };
60 |
61 |
62 | module.exports = {
63 | createFile,
64 | appendFile,
65 | trackError
66 | }
67 |
--------------------------------------------------------------------------------
/bin/exec.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const { exec } = require('child_process');
3 | const goblin = require('commander');
4 | const path = require('path');
5 |
6 | goblin
7 | .command('monitor') // argument passed to bin script
8 | .alias('m') // shorthand for monitor argument e.g. goblin monitor === goblin m
9 | .description('Start GoblinQL Monitoring Service') // part of --help flag for goblin script
10 | .action(() => exec(`node ${__dirname}/server/wsServer.js & sleep 0.25; open http://localhost:9000` ))
11 |
12 | goblin.parse(process.argv); // commander parses and processes arguments to execute script in shell
13 |
14 |
15 | // .action(() => exec(`node ${__dirname}/server.js & open http://localhost:9000/goblinql` ))
16 |
--------------------------------------------------------------------------------
/bin/goblin.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const { exec } = require('child_process');
3 | const goblin = require('commander');
4 |
5 | goblin
6 | .command('server')
7 | .alias('s')
8 | .description('Start GoblinQL Monitoring')
9 | .action(() => exec('node ./node_modules/goblin-ql/server.js & open http://localhost:9000/goblinql'))
10 |
11 | goblin.parse(process.argv);
--------------------------------------------------------------------------------
/bin/server/express.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const path = require('path');
3 | const app = express();
4 | // const cors = require('cors');
5 |
6 |
7 | console.log('connected to server');
8 |
9 | app.use(express.static(path.join(__dirname,'../../bin'))); // serving the bin directory as main source of static files.
10 |
11 | app.get('/', (req, res) => {
12 | res.sendFile(path.resolve(__dirname + '../../client/dist/index.html'));
13 | });
14 |
15 |
16 |
17 | module.exports = app;
--------------------------------------------------------------------------------
/bin/server/wsServer.js:
--------------------------------------------------------------------------------
1 | const httpServer = require('http').createServer();
2 | const WebSocket = require('ws').Server
3 | const app = require('./express.js')
4 | const fs = require('fs');
5 | const path = require('path');
6 |
7 |
8 | // Note: both the express server and the Websocket server sit on top of the Httpserver (port 9000)
9 |
10 | const wss = new WebSocket({
11 | server: httpServer
12 | });
13 |
14 | httpServer.on('request', app);
15 |
16 | wss.on('connection', (ws) => { // initiating ws connection
17 | console.log('Websocket connection established');
18 | fs.watchFile(path.join(__dirname,'../db/data.json'), { interval:1000 }, (data) => { // listening for changes to data.json
19 | // broadcast(data);
20 | ws.send(JSON.stringify({hello:"World"})); // sending to client updated data
21 | console.log('file changed');
22 | })
23 | });
24 |
25 |
26 |
27 | httpServer.listen(9000, () => {
28 | console.log('listening on port 9000')
29 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "goblin-ql",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "src/main.js",
6 | "bin": {
7 | "goblin": "./bin/exec.js"
8 | },
9 | "scripts": {
10 | "test": "jest",
11 | "start": "webpack --mode development",
12 | "dev": "webpack --mode development & goblin monitor",
13 | "build": "webpack --mode production"
14 | },
15 | "keywords": [],
16 | "author": "Andrew Tang, Justin Fung, Billy Lee, Sorouuush",
17 | "license": "ISC",
18 | "dependencies": {
19 | "@material-ui/core": "^4.3.3",
20 | "@material-ui/icons": "^4.2.1",
21 | "@types/react": "^16.9.2",
22 | "@types/react-dom": "^16.9.0",
23 | "chart.js": "^2.8.0",
24 | "commander": "^3.0.0",
25 | "express": "^4.17.1",
26 | "g": "^2.0.1",
27 | "nodemon": "^1.19.1",
28 | "performance-now": "^2.1.0",
29 | "react": "^16.9.0",
30 | "react-chartjs-2": "^2.7.6",
31 | "react-dom": "^16.9.0",
32 | "sleep-ms": "^2.0.1",
33 | "uniqid": "^5.0.3",
34 | "ws": "^7.1.2"
35 | },
36 | "devDependencies": {
37 | "awesome-typescript-loader": "^5.2.1",
38 | "cors": "^2.8.5",
39 | "css-loader": "^3.2.0",
40 | "enzyme": "^3.10.0",
41 | "enzyme-adapter-react-16": "^1.14.0",
42 | "html-webpack-plugin": "^3.2.0",
43 | "jest": "^24.9.0",
44 | "style-loader": "^1.0.0",
45 | "typescript": "^3.6.2",
46 | "webpack": "^4.39.3",
47 | "webpack-cli": "^3.3.7",
48 | "webpack-dev-server": "^3.8.0"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/enableTracking.js:
--------------------------------------------------------------------------------
1 | const now = require('performance-now')
2 | const { appendFile } = require("../bin/db/fileController")
3 | const uniqid = require('uniqid');
4 |
5 | module.exports = function enableTracking(resolversObject,queryField) {
6 | // takes resolvers object of key value pairs -
7 | // key refers to resolver name, value refers to resolver function definition
8 | const newResolversObject = {}
9 | const fields = Object.keys(resolversObject);
10 | const resolverFunctions = Object.values(resolversObject);
11 |
12 | const updatedResolverFunctions = resolverFunctions.map((resolverFunc,index) => {
13 | const fieldName = fields[index];
14 | const currentResolver = async function(...args) {
15 | const [parent, params, ctx, info] = args // 4 arguments available to resolvers.
16 | // if (!parent){
17 | // // console.log(info)
18 | // }
19 | if (!ctx['id']) { // setting a unique id per request on the context obj
20 | ctx['id'] = uniqid.process();
21 |
22 | }
23 | const id = ctx.id
24 | var t0 = now();
25 | const resolverReturnValue = await resolverFunc(...args) // executing the original resolver.
26 | var t1 = now();
27 | let speed = parseFloat((t1-t0).toFixed(4));
28 | await appendFile(queryField,fieldName,speed,id);
29 |
30 | console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to run the ', fieldName + ' resolver.');
31 | return resolverReturnValue
32 | }
33 | Object.defineProperty(currentResolver,'name', {value:fieldName,writable:true}) // dynamically naming all of the resolvers respective to their original name
34 | return currentResolver
35 | })
36 |
37 | fields.forEach((field,index) => { // mapping to each field each respective resolver that has been updated.
38 | newResolversObject[field] = updatedResolverFunctions[index]
39 | })
40 | return newResolversObject
41 | }
42 |
--------------------------------------------------------------------------------
/src/grabFields.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/goblinsharks/d573085a9e1d2cdd6d944025ee8686da1f140afa/src/grabFields.js
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | const mapResolvers = require("./mapResolvers")
2 | const { trackError } = require("../bin/db/fileController.js")
3 |
4 |
5 | const enableMonitoring = (resolvers) => {
6 | const injectedResolvers = mapResolvers(resolvers)
7 | return injectedResolvers
8 | };
9 |
10 |
11 |
12 |
13 | module.exports = { enableMonitoring, trackError}
14 |
--------------------------------------------------------------------------------
/src/mapResolvers.js:
--------------------------------------------------------------------------------
1 | const enableTracking = require("./enableTracking")
2 |
3 | function mapResolvers(originalResolversObject) {
4 | const updatedResolvers = {}
5 | const queries = Object.keys(originalResolversObject) // custom query types
6 | const resolvers = Object.values(originalResolversObject); // object containing a bunch of objects key value pairs of resolvers & field names
7 |
8 |
9 | queries.forEach((key,index)=>{
10 | updatedResolvers[key] = enableTracking(resolvers[index],key) // should return an object which contains keys of
11 | })
12 |
13 | return updatedResolvers
14 |
15 | }
16 |
17 |
18 | module.exports = mapResolvers
--------------------------------------------------------------------------------
/test/enableMonitoring.test.js:
--------------------------------------------------------------------------------
1 | const { enableMonitoring } = require('../src/main');
2 | const {stateTypeResolvers } = require('../testResolvers/mockResolvers')
3 |
4 | test('should return an object', () => {
5 | expect(typeof enableMonitoring({})).toBe('object')
6 | })
7 |
8 | test('resolver state does not change', () => {
9 | expect(JSON.stringify(enableMonitoring(stateTypeResolvers).State.name)).toBe((JSON.stringify(stateTypeResolvers.State.name)))
10 | })
11 |
12 | // test('resolver name does not change', () => {
13 | // expect(enableMonitoring(stateTypeResolvers).State.county.name).toBe(('name'))
14 | // })
15 |
16 | test('checking the state type', () => {
17 | console.log(stateTypeResolvers);
18 | expect(JSON.stringify(enableMonitoring(stateTypeResolvers))).toBe(JSON.stringify(stateTypeResolvers))
19 |
20 | })
21 |
22 | test('checking State total dosage', () => {
23 | expect(JSON.stringify(enableMonitoring(stateTypeResolvers).State.total_dosage)).toBe((JSON.stringify(stateTypeResolvers.State.total_dosage)))
24 | })
25 |
26 | test('checking total_manufactured', () => {
27 | expect(JSON.stringify(enableMonitoring(stateTypeResolvers).State.total_manufactured)).toBe((JSON.stringify(stateTypeResolvers.State.total_manufactured)))
28 | })
29 |
30 | test('Checking county', () => {
31 | expect(JSON.stringify(enableMonitoring(stateTypeResolvers).State.county)).toBe((JSON.stringify(stateTypeResolvers.State.county)))
32 | })
--------------------------------------------------------------------------------
/test/enableTracking.test.js:
--------------------------------------------------------------------------------
1 | const enableTracking = require('../src/enableTracking');
2 |
3 | test('should return an object', () => {
4 | expect(typeof enableTracking({})).toBe('object')
5 | })
6 |
7 |
8 | // test('checking if filds value is right', () => {
9 | // console.log(enableTracking);
10 | // expect(JSON.stringify(enableTracking.fields)).toBe(JSON.stringify(Object.keys(resolversObject)))
11 |
12 | // })
13 |
--------------------------------------------------------------------------------
/testResolvers/mockResolvers.js:
--------------------------------------------------------------------------------
1 | const stateTypeResolvers = {
2 | Query: {
3 | state(parent, args, context, info) {
4 | // allowing child resolvers to access the arg --
5 | return 'California'
6 | }
7 | },
8 | State: {
9 | async name(parent,args) {
10 | return ("California")
11 | },
12 | async total_dosage(parent,args) {
13 | console.log(21)
14 | },
15 |
16 | async total_manufactured(parent,args) {
17 | console.log(421312)
18 | },
19 | county(parent,args){ // giving access state and county to child field nodes
20 | return {state: parent, county:args.county}
21 | }
22 | }
23 | }
24 |
25 |
26 | const mockResolverObject = {
27 | async name(parent,args) {
28 | console.log("California")
29 | },
30 | async total_dosage(parent,args) {
31 | console.log(21)
32 | },
33 |
34 | async total_manufactured(parent,args) {
35 | console.log(421312)
36 | },
37 | county(parent,args){ // giving access state and county to child field nodes
38 | return {state: parent, county:args.county}
39 | }
40 | }
41 |
42 | module.exports = {
43 | stateTypeResolvers,
44 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "sourceMap": true,
4 | "noImplicitAny": false,
5 | "module": "commonjs",
6 | "target": "es6",
7 | "lib": [
8 | "es2015",
9 | "es2017",
10 | "dom"
11 | ],
12 | "removeComments": true,
13 | "allowSyntheticDefaultImports": false,
14 | "jsx": "react",
15 | "allowJs": true,
16 | "baseUrl": "./",
17 | "paths": {
18 | "components/*": [
19 | "src/components/*"
20 | ],
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | mode: 'development',
5 | watch: true,
6 | watchOptions: {
7 | ignored: /node_modules/,
8 | aggregateTimeout: 1000
9 | },
10 | entry: './bin/client/src/index.tsx',
11 | resolve: {
12 | extensions: ['.ts', '.tsx', '.js']
13 | },
14 | output: {
15 | path: path.join(__dirname, '/bin/client/dist'),
16 | filename: 'bundle.min.js'
17 | },
18 | module: {
19 | rules: [
20 | {
21 | test: /\.tsx?$/,
22 | loader: 'awesome-typescript-loader'
23 | },
24 | {
25 | test: /\.css$/,
26 | use: ['style-loader', 'css-loader'],
27 | }
28 | ]
29 | },
30 | }
31 |
--------------------------------------------------------------------------------