diff --git a/foomo/docs/devops/monitoring/_category_.json b/foomo/docs/devops/monitoring/_category_.json index 1fa344f..47bd214 100644 --- a/foomo/docs/devops/monitoring/_category_.json +++ b/foomo/docs/devops/monitoring/_category_.json @@ -1,4 +1,4 @@ { - "label": "Monitoring", - "position": 1 - } \ No newline at end of file + "label": "Monitoring", + "position": 1 +} diff --git a/foomo/docs/frontend/rtfm.md b/foomo/docs/frontend/rtfm.md new file mode 100644 index 0000000..110f119 --- /dev/null +++ b/foomo/docs/frontend/rtfm.md @@ -0,0 +1,47 @@ +--- +sidebar_label: RTFM +sidebar_position: 2 +--- +# External documentation resources + +## Runtime / browser + +In general the [Mozilla Developer Network - MDN](https://developer.mozilla.org/) is a great resource, if you want to know, what your browser is capable of. + +Once you found out, how great an API is, the question to answer will be ["can I use"](https://caniuse.com/) feature X. https://caniuse.com/ is a great resource to find the answers, when trying to understand, if a browser API / feature is ready to use for your audience. + +# JavaScript + +JavaScript historically has a very bad reputation. Please enjoy the following classic piece of infotainment: https://www.destroyallsoftware.com/talks/wat + +As JavaScript has been massively iterated on, the runtimes hav ecome crazy fast and the language keeps on evolving. + +The (mostly functional) subset of the language, that is being used in modern JavaScript / TypeScript projects to is highly expressive and reads well. + +Please take the time and learn about + +- functional programming +- variable scope +- modern JavaScript syntax + - arrow functions + - new keywords + - spreading + - ... +- promises + + +# CSS + +- CSS block model +- flex box + +# Browser APIs + +- canvas +- fetch +- local storage +- websockets +- sse server side events +- built in types + +## TypeScript \ No newline at end of file diff --git a/foomo/docs/frontend/setup.md b/foomo/docs/frontend/setup.md index 2029360..4892317 100644 --- a/foomo/docs/frontend/setup.md +++ b/foomo/docs/frontend/setup.md @@ -4,28 +4,23 @@ sidebar_position: 2 --- # Frontend setup -How to setup your machine +How to setup your machine for frontend development -```jsx live -function Clock(props) { +## Install software - const [date, setDate] = useState(new Date()); +### Mac - useEffect(() => { - var timerID = setInterval(() => tick(), 1000); - return function cleanup() { - clearInterval(timerID); - }; - }); +First of all install `brew` from https://brew.sh - function tick() { - setDate(new Date()); - } - - return ( -
-

It is {date.toLocaleTimeString()}.

-
- ); -} +```zsh +brew install nvm +brew cask install iterm2 ``` + +### Linux + + + +### Windows + +Install Linux ;) \ No newline at end of file diff --git a/foomo/docs/frontend/stack.md b/foomo/docs/frontend/stack.md index 4fe19c0..8b194f5 100644 --- a/foomo/docs/frontend/stack.md +++ b/foomo/docs/frontend/stack.md @@ -7,8 +7,30 @@ tags: --- # Frontend Stack +Our frontend stack is permanently changing as the underlying eco system does. We are trying to adopt technologies at the "Slope of Enlightenment" in the [hype cycle](https://en.wikipedia.org/wiki/Gartner_hype_cycle). + +Former iterations of our stack were MVC or MVVM frontend frameworks. Since the arrival of React and state mangement libraries like Redux and Zustand we have been building reactive applications. + +Reactive frontends are fun to develop and they scale. + ## TypeScript -## React +Is our language of choice to build frontends for web applications. -## gotsrpc \ No newline at end of file +We have adopted TypeScript very early, right after its initial public release in 2012. Here is a list of motives: + +- it is a superset JavaScript +- it does not try to replace JavaScript like many other languages, which compile to JavaScript, it tries to complement and improve it, while staying compatible +- good type system +- great tooling + +While it seemed to be crazy to trust Microsoft as a friendly open source company, we have not been disappointed so far. + + +## React / Preact + +Declarative components and views, fast to develop and fast at runtime. + +## gotsrpc + +Since we are building services in Go and not with Node.js we have created a light weight RPC framework to integrate TypeScript with Go. \ No newline at end of file diff --git a/foomo/docs/frontend/typescript/_category_.json b/foomo/docs/frontend/typescript/_category_.json new file mode 100644 index 0000000..a6d4cd3 --- /dev/null +++ b/foomo/docs/frontend/typescript/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "TypeScript", + "position": 6 +} diff --git a/foomo/docs/frontend/typescript/objects.mdx b/foomo/docs/frontend/typescript/objects.mdx new file mode 100644 index 0000000..a193bc2 --- /dev/null +++ b/foomo/docs/frontend/typescript/objects.mdx @@ -0,0 +1,20 @@ +--- +sidebar_label: "Objects" +--- +import { TypeScriptPlayground } from "../../../src/components/TypeScriptPlayground"; + +# Object declaration syntax in TypeScript + +{` +let foo:{[index:string]:number} = { + foo: 1 +}; +`} + + +```tsx +let foo:{[index:string]:number} = { + foo: 1 +}; + +``` diff --git a/foomo/docs/frontend/typescript/spreading.md b/foomo/docs/frontend/typescript/spreading.md new file mode 100644 index 0000000..6f16c1a --- /dev/null +++ b/foomo/docs/frontend/typescript/spreading.md @@ -0,0 +1,89 @@ +# Spreading + +JavaScript spread syntax `(...)` is a surprisingly powerful construct. It has two main use cases in our applications: + +## Efficiently copying data + +The most important use case for this is when you are working with your applications state. + +```jsx live +function () { + // let´s start with a relatively simple object + const foo = { + a: 1, + b: 2, + nested: { + child: "is not a copy", + }, + }; + // this will create a shallow copy of foo and add a field "c" + const bar = { ...foo, c: 3 }; + // please note, that the nested property "nested" is not deeply copied, + // thus changes to this object will also affect foo.nested + bar.nested.child += " <- I told you so"; + + // .foo has been copied though and changes to it affect the original only + foo.a += 1; + return ( + <> + +
foo: {JSON.stringify(foo)}
+ +
bar: {JSON.stringify(bar)}
+ + ); +} +``` + +## Populating jsx attributes + +```jsx live +function() { + // a simple Component, that will render all fields in props + const Foo = (props) => ( + + ); + const data = { + a: 1, + b: 2, + c: 3 + } + const {c,...part} = data; + return ( + <> +

all data props

+ +

all data props and d

+ +

just a part of the props, @themre please explain ;)

+ + + ); +} +``` diff --git a/foomo/src/components/Iframe.tsx b/foomo/src/components/Iframe.tsx index 18053ce..cfa749d 100644 --- a/foomo/src/components/Iframe.tsx +++ b/foomo/src/components/Iframe.tsx @@ -1,28 +1,34 @@ import React from "react"; -export const Iframe = (props: { proportion:number; src:string }) => ( -
- -
-); + > + + + ); +}; diff --git a/foomo/src/components/TypeScriptPlayground.tsx b/foomo/src/components/TypeScriptPlayground.tsx new file mode 100644 index 0000000..4c31bcd --- /dev/null +++ b/foomo/src/components/TypeScriptPlayground.tsx @@ -0,0 +1,192 @@ +import React from "react"; + +import Highlight, { defaultProps } from "prism-react-renderer"; + +const LZString = (() => { + function o(o, r) { + if (!t[o]) { + t[o] = {}; + for (var n = 0; n < o.length; n++) t[o][o.charAt(n)] = n; + } + return t[o][r]; + } + var r = String.fromCharCode, + n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$", + t = {}, + i = { + compressToBase64: function (o) { + if (null == o) return ""; + var r = i._compress(o, 6, function (o) { + return n.charAt(o); + }); + switch (r.length % 4) { + default: + case 0: + return r; + case 1: + return r + "==="; + case 2: + return r + "=="; + case 3: + return r + "="; + } + }, + compressToUTF16: function (o) { + return null == o + ? "" + : i._compress(o, 15, function (o) { + return r(o + 32); + }) + " "; + }, + compressToUint8Array: function (o) { + for ( + var r = i.compress(o), + n = new Uint8Array(2 * r.length), + e = 0, + t = r.length; + t > e; + e++ + ) { + var s = r.charCodeAt(e); + (n[2 * e] = s >>> 8), (n[2 * e + 1] = s % 256); + } + return n; + }, + compressToEncodedURIComponent: function (o) { + return null == o + ? "" + : i._compress(o, 6, function (o) { + return e.charAt(o); + }); + }, + compress: function (o) { + return i._compress(o, 16, function (o) { + return r(o); + }); + }, + _compress: function (o, r, n) { + if (null == o) return ""; + var e, + t, + i, + s = {}, + p = {}, + u = "", + c = "", + a = "", + l = 2, + f = 3, + h = 2, + d = [], + m = 0, + v = 0; + for (i = 0; i < o.length; i += 1) + if ( + ((u = o.charAt(i)), + Object.prototype.hasOwnProperty.call(s, u) || + ((s[u] = f++), (p[u] = !0)), + (c = a + u), + Object.prototype.hasOwnProperty.call(s, c)) + ) + a = c; + else { + if (Object.prototype.hasOwnProperty.call(p, a)) { + if (a.charCodeAt(0) < 256) { + for (e = 0; h > e; e++) + (m <<= 1), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++; + for (t = a.charCodeAt(0), e = 0; 8 > e; e++) + (m = (m << 1) | (1 & t)), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t >>= 1); + } else { + for (t = 1, e = 0; h > e; e++) + (m = (m << 1) | t), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t = 0); + for (t = a.charCodeAt(0), e = 0; 16 > e; e++) + (m = (m << 1) | (1 & t)), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t >>= 1); + } + l--, 0 == l && ((l = Math.pow(2, h)), h++), delete p[a]; + } else + for (t = s[a], e = 0; h > e; e++) + (m = (m << 1) | (1 & t)), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t >>= 1); + l--, + 0 == l && ((l = Math.pow(2, h)), h++), + (s[c] = f++), + (a = String(u)); + } + if ("" !== a) { + if (Object.prototype.hasOwnProperty.call(p, a)) { + if (a.charCodeAt(0) < 256) { + for (e = 0; h > e; e++) + (m <<= 1), v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++; + for (t = a.charCodeAt(0), e = 0; 8 > e; e++) + (m = (m << 1) | (1 & t)), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t >>= 1); + } else { + for (t = 1, e = 0; h > e; e++) + (m = (m << 1) | t), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t = 0); + for (t = a.charCodeAt(0), e = 0; 16 > e; e++) + (m = (m << 1) | (1 & t)), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t >>= 1); + } + l--, 0 == l && ((l = Math.pow(2, h)), h++), delete p[a]; + } else + for (t = s[a], e = 0; h > e; e++) + (m = (m << 1) | (1 & t)), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t >>= 1); + l--, 0 == l && ((l = Math.pow(2, h)), h++); + } + for (t = 2, e = 0; h > e; e++) + (m = (m << 1) | (1 & t)), + v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++, + (t >>= 1); + for (;;) { + if (((m <<= 1), v == r - 1)) { + d.push(n(m)); + break; + } + v++; + } + return d.join(""); + }, + }; + return i; +})(); + +export const TypeScriptPlayground = (props: { children: string }) => { + const url = + "https://www.typescriptlang.org/play?#code/" + + escape(LZString.compressToEncodedURIComponent(props.children)); + return ( +
+ + {({ className, style, tokens, getLineProps, getTokenProps }) => ( +
+            {tokens.map((line, i) => (
+              
+ {line.map((token, key) => ( + + ))} +
+ ))} +
+ )} +
+ + open in playground on www.typescriptlang.org + +
+ ); +}; diff --git a/foomo/src/pages/awesome-software.md b/foomo/src/pages/awesome-software.md index 81d8f89..0605224 100644 --- a/foomo/src/pages/awesome-software.md +++ b/foomo/src/pages/awesome-software.md @@ -2,6 +2,11 @@ A list of commercial and open source software we use, because it is awesome. +
+ Please note, when you are installing software, use a package manager +
+
+ ## desktop software ### devtools diff --git a/foomo/src/pages/index.tsx b/foomo/src/pages/index.tsx index ff559c7..f083268 100644 --- a/foomo/src/pages/index.tsx +++ b/foomo/src/pages/index.tsx @@ -1,7 +1,6 @@ import React from "react"; import clsx from "clsx"; import Layout from "@theme/Layout"; -import Link from "@docusaurus/Link"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import styles from "./index.module.css"; import HomepageFeatures from "../components/HomepageFeatures"; @@ -11,8 +10,12 @@ function HomepageHeader() { return (
-

{siteConfig.title}

@@ -40,32 +43,32 @@ export default function Home(): JSX.Element { marginRight: "auto", }} > -
+

foomo is an open source project, that has been maintained by the bestbytes team since 2011. It provides a wide range of tools and libraries, that help us to tackle challenging projects.

-

foomo can help, if you are

-
    -
  • - using Go to write services -
  • -
  • - building frontends with{" "} - TypeScript and{" "} - Next.js -
  • -
  • - running your software on k8s -
  • -
  • - looking for a solution to deeply integrate your frontends with a - headless cms -
  • -
- If more than two points apply, it will actually help a LOT +

foomo can help, if you are

+
    +
  • + using Go to write services +
  • +
  • + building frontends with{" "} + TypeScript and{" "} + Next.js +
  • +
  • + running your software on k8s +
  • +
  • + looking for a solution to deeply integrate your frontends with a + headless cms +
  • +
+ If more than two points apply, it will actually help a LOT