Example #1
0
func main() {
	logrus.StandardLogger().Level = logrus.DebugLevel

	logrus.Debug("starting up")

	baseVM := otto.New()

	smRead := logDuration("read sourcemap")
	smData, err := ioutil.ReadFile("../client/public/bundle.server.js.map")
	if err != nil {
		panic(err)
	}
	smRead()

	smParse := logDuration("parse sourcemap")
	sm, err := sourcemap.Read(bytes.NewReader(smData))
	if err != nil {
		panic(err)
	}
	smParse()

	jsRead := logDuration("read javascript")
	jsData, err := ioutil.ReadFile("../client/public/bundle.server.js")
	if err != nil {
		panic(err)
	}
	jsRead()

	jsCompiled := logDuration("compile javascript")
	s, err := baseVM.CompileWithSourceMap("bundle.js", string(jsData), &sm)
	if err != nil {
		panic(err)
	}
	jsCompiled()

	jsInitialised := logDuration("initialise javascript")
	if _, err := baseVM.Run(s); err != nil {
		panic(err)
	}
	jsInitialised()

	tpl, err := template.ParseFiles("./index.template")
	if err != nil {
		panic(err)
	}

	apiRouter := mux.NewRouter()

	apiRouter.Path("/api/v1/posts").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		posts := `[
			{"id":1,"title":"hello1 ","content":"hi there one!"},
			{"id":2,"title":"hello 2","content":"hi there two!"}
		]`

		w.Header().Set("content-type", "application/json")
		if _, err := w.Write([]byte(posts)); err != nil {
			panic(err)
		}
	})

	m := mux.NewRouter()

	m.PathPrefix("/api/v1").Handler(apiRouter)

	m.PathPrefix("/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		vmCopied := logDuration("copy vm")
		vm := baseVM.Copy()
		vmCopied()

		l := loop.New(vm)
		if err := fetch.DefineWithHandler(vm, l, apiRouter); err != nil {
			panic(err)
		}

		fn, err := vm.Get("renderApplication")
		if err != nil {
			panic(err)
		}

		m := map[string]interface{}{
			"redirect": func(u string) {
				http.Redirect(w, r, u, 301)
			},
			"error": func(e string) {
				http.Error(w, e, http.StatusInternalServerError)
			},
			"notFound": func() {
				http.NotFound(w, r)
			},
			"success": func(d string) {
				w.Header().Set("content-type", "text/html")

				tpl.Execute(w, map[string]string{
					"html": d,
				})
			},
		}

		v, err := vm.ToValue(m)
		if err != nil {
			panic(err)
		}

		jsRun := logDuration("run javascript")
		if _, err := fn.Call(otto.UndefinedValue(), r.URL.String(), otto.NullValue(), v); err != nil {
			panic(err)
		}
		jsRun()

		jsFinished := logDuration("wait for js")
		if err := l.Run(); err != nil {
			panic(err)
		}
		jsFinished()
	})

	n := negroni.New()

	n.Use(negroni.NewRecovery())
	n.Use(negronilogrus.NewMiddleware())
	st := negroni.NewStatic(http.Dir("../client/public"))
	st.IndexFile = "NOT_USED_I_HOPE"
	n.Use(st)
	n.UseHandler(m)

	logrus.Info("listening")
	if err := http.ListenAndServe(":3000", n); err != nil {
		panic(err)
	}
}
Example #2
0
func main() {
	logrus.StandardLogger().Level = logrus.DebugLevel

	logrus.Debug("starting up")

	baseVM := otto.New()

	smRead := logDuration("read sourcemap")
	smData, err := ioutil.ReadFile("../client/public/bundle.server.js.map")
	if err != nil {
		panic(err)
	}
	smRead()

	smParse := logDuration("parse sourcemap")
	sm, err := sourcemap.Read(bytes.NewReader(smData))
	if err != nil {
		panic(err)
	}
	smParse()

	jsRead := logDuration("read javascript")
	jsData, err := ioutil.ReadFile("../client/public/bundle.server.js")
	if err != nil {
		panic(err)
	}
	jsRead()

	// lodash has a lookahead regex that we don't care about, and it makes otto
	// unhappy. this is a hack to get rid of it.
	jsData = bytes.Replace(jsData, []byte(`(?=`), []byte(`(`), -1)

	jsCompiled := logDuration("compile javascript")
	s, err := baseVM.CompileWithSourceMap("bundle.js", string(jsData), &sm)
	if err != nil {
		if st := dumpDebugError(err); st != "" {
			fmt.Println(st)
		}
		panic(err)
	}
	jsCompiled()

	jsInitialised := logDuration("initialise javascript")
	if _, err := baseVM.Run(s); err != nil {
		if st := dumpDebugError(err); st != "" {
			fmt.Println(st)
		}
		panic(err)
	}
	jsInitialised()

	vmChan := make(chan *otto.Otto)
	go vmCopier(baseVM, vmChan)

	tpl, err := template.ParseFiles("./index.template")
	if err != nil {
		panic(err)
	}

	apiRouter := mux.NewRouter()

	var cats = []Cat{
		Cat{Name: "fluffy", FavouriteFood: "marshmallows"},
		Cat{Name: "beans", FavouriteFood: "legume"},
		Cat{Name: "misty", FavouriteFood: "meat"},
		Cat{Name: "sara", FavouriteFood: "fish"},
	}

	apiRouter.Path("/api/v1/cats").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Query().Get("search") == "" {
			w.Header().Set("content-type", "application/json")
			if err := json.NewEncoder(w).Encode(cats); err != nil {
				panic(err)
			}

			return
		}

		var d []Cat
		for _, c := range cats {
			if strings.Contains(strings.ToLower(c.Name), strings.ToLower(r.URL.Query().Get("search"))) {
				d = append(d, c)
			}
		}

		w.Header().Set("content-type", "application/json")
		if err := json.NewEncoder(w).Encode(d); err != nil {
			panic(err)
		}
	})

	apiRouter.Path("/api/v1/cats/{name}").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)

		for _, c := range cats {
			if strings.ToLower(c.Name) == vars["name"] {
				w.Header().Set("content-type", "application/json")
				if err := json.NewEncoder(w).Encode(c); err != nil {
					panic(err)
				}

				return
			}
		}

		http.NotFound(w, r)
	})

	m := mux.NewRouter()

	m.PathPrefix("/api/v1").Handler(apiRouter)

	m.PathPrefix("/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		vmCopied := logDuration("copy vm")
		vm := <-vmChan
		vmCopied()

		l := loop.New(vm)
		if err := fetch.DefineWithHandler(vm, l, apiRouter); err != nil {
			panic(err)
		}

		fn, err := vm.Get("renderApplication")
		if err != nil {
			panic(err)
		}

		m := map[string]interface{}{
			"redirect": func(u string) {
				http.Redirect(w, r, u, 301)
			},
			"error": func(e string) {
				http.Error(w, e, http.StatusInternalServerError)
			},
			"notFound": func() {
				http.NotFound(w, r)
			},
			"success": func(initialState, html string) {
				w.Header().Set("content-type", "text/html")

				tpl.Execute(w, map[string]string{
					"initialState": initialState,
					"html":         html,
				})
			},
		}

		v, err := vm.ToValue(m)
		if err != nil {
			panic(err)
		}

		jsRun := logDuration("run javascript")
		if _, err := fn.Call(otto.UndefinedValue(), r.URL.String(), otto.NullValue(), v); err != nil {
			if st := dumpDebugError(err); st != "" {
				panic(fmt.Errorf("%s", st))
			}
			panic(err)
		}
		jsRun()

		jsFinished := logDuration("wait for js")
		if err := l.Run(); err != nil {
			if st := dumpDebugError(err); st != "" {
				panic(fmt.Errorf("%s", st))
			}
			panic(err)
		}
		jsFinished()
	})

	n := negroni.New()

	n.Use(negroni.NewRecovery())
	n.Use(negronilogrus.NewMiddleware())
	st := negroni.NewStatic(http.Dir("../client/public"))
	st.IndexFile = "NOT_USED_I_HOPE"
	n.Use(st)
	n.UseHandler(m)

	logrus.Info("listening")
	if err := http.ListenAndServe(":3000", n); err != nil {
		panic(err)
	}
}