feat: dox++

This commit is contained in:
cha0s 2023-12-31 16:23:28 -06:00
parent 9c4d273279
commit 06417c2c76
18 changed files with 552 additions and 8 deletions

4
.gitignore vendored
View File

@ -116,11 +116,7 @@ dist
.pnp.*
# local
/build
/yarn.lock
# package-locals
/packages/*/yarn.lock
# Generated documentation
/dox

View File

@ -12,7 +12,7 @@
This is largely untested software. There are undoubtedly many bugs that haven't yet been found.
I reserve the right to break all semantic versioning guarantees as long as the project is v1.x.x! 😈
I reserve the right to break all semantic versioning guarantees as long as there is a critical need for fundamental changes that significantly improve the project's architecture, performance, or address security vulnerabilities, and these modifications are deemed essential for the long-term stability, innovation, and overall betterment of the software. The project is young enough that I can get away with that. This will be revisited.
**You've been warned!**

View File

@ -0,0 +1,47 @@
// @ts-check
// `@type` JSDoc annotations allow editor autocompletion and type checking
// (when paired with `@ts-check`).
// There are various equivalent ways to declare your Docusaurus config.
// See: https://docusaurus.io/docs/api/docusaurus-config
// For some reason we get a webpack warning if we use import here...
const {configDefaults} = require('@flecks/dox/server'); // eslint-disable-line import/no-extraneous-dependencies
export default async function flecksDocusaurus() {
const defaults = configDefaults();
/** @type {import('@docusaurus/types').Config} */
const config = {
...defaults,
title: 'flecks',
tagline: 'not static',
// favicon: 'img/flecks.svg',
url: 'https://cha0s.github.io',
baseUrl: '/flecks/',
organizationName: 'cha0s', // Usually your GitHub org/user name.
projectName: 'flecks', // Usually your repo name.
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...defaults.themeConfig,
navbar: {
title: 'flecks',
// logo: {
// alt: 'flecks logo',
// src: 'img/flecks.svg',
// },
items: [
{
href: 'https://github.com/cha0s/flecks',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
copyright: `Copyright © ${new Date().getFullYear()} cha0s. Built with Docusaurus.`,
},
}),
};
return config;
}

17
build/flecks.yml Normal file
View File

@ -0,0 +1,17 @@
'@flecks/core': {}
'@flecks/create-app': {}
'@flecks/create-fleck': {}
'@flecks/db': {}
'@flecks/docker': {}
'@flecks/dox': {}
'@flecks/electron': {}
'@flecks/fleck': {}
'@flecks/governor': {}
'@flecks/react': {}
'@flecks/redis': {}
'@flecks/redux': {}
'@flecks/repl': {}
'@flecks/server': {}
'@flecks/socket': {}
'@flecks/user': {}
'@flecks/web': {}

View File

@ -8,15 +8,29 @@
"bfp": "for i in $(npx lerna exec pwd); do cd $i; bfp || break; done; cd ../..",
"build": "lerna run build",
"clean": "for i in $(npx lerna exec pwd); do cd $i; rm -rf yarn.lock node_modules; yarn; done; cd ../..",
"dox": "FLECKS_ENV_FLECKS_DOX_SERVER_filenameRewriters=\"{\\\"^@flecks/(.*):([0-9]+):([0-9]+)\\\": \\\"<a href='https://github.com/cha0s/flecks/tree/$(git rev-parse --short HEAD)/packages/\\$1#L\\$2'>@flecks/\\$1:\\$2:\\$3</a>\\\"}\" yarn flecks dox",
"lint": "lerna run lint",
"publish": "lerna publish --conventional-commits --contents=dist --registry https://registry.npmjs.org",
"refresh": "npm run clean && npm run bfp",
"test": "lerna run test --no-bail -- --silent"
},
"dependencies": {},
"devDependencies": {
"@flecks/core": "*",
"@flecks/core": "^2.0.3",
"@flecks/create-app": "*",
"@flecks/create-fleck": "*",
"@flecks/db": "*",
"@flecks/docker": "*",
"@flecks/dox": "^2.0.3",
"@flecks/electron": "*",
"@flecks/fleck": "*",
"@flecks/governor": "*",
"@flecks/react": "*",
"@flecks/redis": "*",
"@flecks/redux": "*",
"@flecks/repl": "*",
"@flecks/server": "*",
"@flecks/socket": "*",
"@flecks/user": "*",
"@flecks/web": "*",
"lerna": "^7.4.2"
}
}

1
website/docs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/flecks

View File

@ -0,0 +1,84 @@
---
title: Configuration
description: Configure `flecks.yml` and your application.
---
import InstallPackage from '@site/helpers/install-package';
You have a flecks application! ...but it doesn't do much. This is because a flecks application is
composed of individual flecks. By default, your application will have two flecks: `@flecks/core` and
`@flecks/server`. Each fleck may have configuration that can be set through `flecks.yml`. For a
list of configurable core flecks, see [the generated configuration page](/docs/flecks/config).
## First steps
A good first configuration step is to set the ID of your application.
Your `flecks.yml` will look like this after you generate your application:
```yml
'@flecks/core': {}
'@flecks/server': {}
```
Your application's ID is configured at the `id` key of `@flecks/core`'s configuration. To set your
application's ID to `hello_world`, update your `flecks.yml` to look like this:
```yml
// highlight-start
'@flecks/core':
id: 'hello_world'
// highlight-end
'@flecks/server': {}
```
## Getting somewhere
If you were studious enough to take a peek at [the generated configuration page](/docs/flecks/config)
above, you may have noticed that there were a bunch more flecks there than just the two in our
application.
For instance, there is a `@flecks/web` fleck that turns your little old server application into one
that can build and serve a webpage. You can add it to your application in two steps.
1. Add the package to your project using your favorite package manager:
<InstallPackage pkg="@flecks/web" />
2. Add the fleck to your `flecks.yml`:
```yml
'@flecks/core':
id: 'hello_world'
'@flecks/server': {}
// highlight-next-line
'@flecks/web': {}
```
Now, if you run `npm start`, you'll see a line in the output:
```
@flecks/web/server/http HTTP server up @ 0.0.0.0:32340!
```
## Finally... a white page?
If you visit `localhost:32340` in your browser, you should now see... a blank white page! Don't fret
though; if you open the devtools in your browser, you will see a little messaging from your
application that will look something like:
```
[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.
[HMR] Waiting for update signal from WDS...
flecks client v2.0.3 loading runtime...
```
This is a good sign! This means we successfully added a web server with HMR enabled by default.
Oh, the possibilities...
## Proceed with the hooking
How does flecks know to start the web server when the application starts? Great question! This is
accomplished through the use of [hooks](#todo).
Next, we'll learn how to create our own fleck and do a little hooking of our own. Take that, dad!

View File

@ -0,0 +1,147 @@
---
title: Creating a fleck
description: A fleck is a module but also so much more.
---
import InstallPackage from '@site/helpers/install-package';
So you want to create a fleck. Think you got what it takes?
If you are following along from the previous getting started
[configuration page](./configuration), you have an application with 3 flecks:
- `@flecks/core`
- `@flecks/server`
- `@flecks/web`
<details>
<summary>About that "3 flecks" thing...</summary>
Actually, your application has 6 flecks at this point:
- `@flecks/core`
- `@flecks/core/server`
- `@flecks/server`
- `@flecks/server/server`
- `@flecks/web`
- `@flecks/web/server`
flecks will load the `[...]/server` fleck under any fleck that is loaded on the server. This is
also the case when using `@flecks/web` which will automatically load `[...]/client` flecks
which are only loaded in the browser. We'll be exploring this specifically in the next section.
If you're intersted in diving deeper, see [the platforms concept page](#todo).
Some frameworks make it a little cheesier to work with isomorphic code, but the flecks
philosophy is that visibility is believability: you'll have to be explicit about which code
runs where.
</details>
## Your first fleck
Let's make your website greet the user with a good ol' **hello world**.
To do this, you'll be creating your own little fleck. You'll create the fleck at `src/hello-world`.
A fleck is just a package, so we'll need to add a `package.json`. Nothing much; a name will suffice:
### `package.json`
```json
{
"name": "hello-world",
}
```
and we'll add our little source file:
### `index.js`
```javascript
exports.hooks = {
'@flecks/web/client.up': async () => {
window.document.body.append('hello world');
},
};
```
You should now have a `src` directory that looks like this:
```
src
└── hello-world
├── index.js
└── package.json
```
Good? Good! Now, let's add this to our `flecks.yml`:
```yml
'@flecks/core':
id: 'hello_world'
'@flecks/server': {}
'@flecks/web': {}
// highlight-next-line
'hello-world:./src/hello-world': {}
```
### Aliasing for the win
Notice there's a colon separating the path for this one. This is because this is an
[aliased fleck](#todo). The part before the colon is the alias and the part after is the
path to the package.
Now, restart your application and visit your website. Glorious, isn't it?
By the way, your other application code can import the alias (e.g. `require('hello-world');`)
[as if it were a package](https://webpack.js.org/configuration/resolve/#resolvealias).
<details>
<summary>Wait, my flecks don't have to be in <code>node_modules</code>?</summary>
Nope! That's an intentional feature. When you're developing applications, it can be real nice to
just pull in local source "packages". If you're wondering how this works, see
[the alias concept page](#todo).
You probably shouldn't do things like name an alias the same thing as a package that actually
exists in your `node_modules` directory. If you'd like to help define what happens in that case
you could always [submit a pull request](https://github.com/cha0s/flecks/compare).
That being said, sharing your package on npm is a cool thing to do, so be rad and share your
awesome flecks with the rest of us!
</details>
## Everything so far... plus Electron!
Let's add another core fleck. flecks ships with a core fleck `@flecks/electron`. This runs your
application inside of an instance of [Electron](https://www.electronjs.org/). You'll add the fleck:
<InstallPackage pkg="@flecks/electron" />
Then you'll update your `flecks.yml` like so:
```yml
'@flecks/core':
id: 'hello_world'
// highlight-start
'@flecks/electron': {}
'@flecks/server':
up:
- '...'
- '@flecks/web'
- '@flecks/electron'
// highlight-end
'@flecks/web': {}
'hello-world:./src/hello-world': {}
```
### ~~flecking~~ pecking order
Did you notice we added some configuration to `@flecks/server`? The `up` key configures the order in
which flecks are initialized when the server comes up. We make sure `@flecks/web` initializes
before `@flecks/electron` so there's a webpage to visit. There are future plans to make this the
default with no configuration required.
Finally `npm start` and you should see something like this:
![An image of our simple hello world application running inside an Electron window](./flecks-electron.png)
Cool, huh?

View File

@ -0,0 +1,14 @@
---
title: Documentation
description: Document your project.
---
# Documentation
Ah, the most ~~boring~~ awesome part of development.
flecks provides a fleck called `@flecks/dox` that helps you generate a documentation website for
your project. In fact, this very website you're viewing now has been built with the same tooling!
`@flecks/dox` implements a [CLI command](/flecks/docs/flecks/@flecks/dox/hooks#fleckscorecommands)
to run [Docusaurus](https://docusaurus.io/) and generate a documentation site for your project.

View File

@ -0,0 +1,20 @@
---
description: flecks core handles the orchestration of your flecks
slug: /flecks-core
---
# `@flecks/core`
## CLI
## Debug logs
## Helpers
### Event emitter
### Middleware
### Compose
## `@flecks/core/server`

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,6 @@
---
title: Installation
description: How to get started with your first flecks project
---
This is some text.

View File

@ -0,0 +1,61 @@
---
description: flecks makes a joy of JavaScript app development.
slug: /
---
# Introduction
⚡️ flecks will help you build a **flexible and powerful application in no time**.
💸 Save time and money and don't duplicate effort. Instead, **lean on infrastructure that already exists** to solve your problems.
💥 Ready for more? Use **advanced features** like [running flecks on your toaster](#todo)
🧐 Flecks is an **exceptionally-extensible fullstack application production system**. Its true purpose
is to make application development a more joyful endeavor. Intelligent defaults combined with
a highly dynamic structure motivate consistency while allowing you to easily express your own
opinions.
## Features {#features}
flecks is built with supreme attention to the developer and end-user experience.
- 🧩 **Small but pluggable**
- The simplest application is two flecks, `core` and `server`: you don't pay for what you don't buy
- Endlessly configurable through built-in hooks and then your own
- 🛠️ **Ready to build real applications**
- babel + Webpack 5
- [React](#todo)/[redux](#todo)
- [Database](#todo)
- [electron](#todo)
- [docker](#todo)
- [REPL](#todo)
- [websockets](#todo) with lots of goodies like binary packing and packet dispatching out of the box
- [docusaurus](#todo): This documentation website you're looking at, available to your own apps for your own documentation by simply adding [`@flecks/dox`](#todo) to your own application
- 👷 **Developers, developers, developers**
- 🪄 Easy to create a fleck; no need to publish packages or use voodoo
- Write server or client (or both) tests, run on server/in browser/[your own custom platform](#todo)
- HMR (even on the server)
- Create a fleck with your [redux slice](https://redux-toolkit.js.org/api/createslice/) provided through a hook. Finally, real [ducks](https://github.com/erikras/ducks-modular-redux)!
- Easily spin up a database or redis server ([or...](/docs/flecks/hooks#flecksdockercontainers)) using [Docker](#todo) during development, and generate a `Dockerfile` and `docker-compose.yml` automatically for production
- Small hookable core means less exposed wires. You could always help by [submitting a pull request](https://github.com/cha0s/flecks/compare) though.
Our shared goal—to help you quickly develop your application. We share our best practices to help you build your application right and well.
## Design principles {#design-principles}
- **Little to learn**. flecks should be easy to learn and use as the API is quite small. Most things will still be achievable by users, even if it takes them more code and more time to write. Not having abstractions is better than having the wrong abstractions, and we don't want users to have to hack around the wrong abstractions. Mandatory talk—[Minimal API Surface Area](https://www.youtube.com/watch?v=4anAwXYqLG8).
- **Intuitive**. Users will not feel overwhelmed when looking at the project directory of a flecks project or adding new features. It should look intuitive and easy to build on top of, using approaches they are familiar with.
- **Modular**. flecks is built from the ground up with separation of concerns as a first-class concern.
- **Sensible defaults**. Common and popular performance optimizations and configurations will be done for users but they are given the option to override them.
- **No vendor lock-in**. Users are not required to use the default flecks, although they are highly encouraged to.
We believe that, as developers, knowing how a library works helps us become better at using it. Hence we're dedicating effort to explaining the architecture and various aspects of flecks with the hope that users reading it will gain a deeper understanding and be even more proficient in using it.
## Staying informed {#staying-informed}
- [GitHub](https://github.com/cha0s/flecks)
## Something missing? {#something-missing}
If you find issues with the documentation or have suggestions on how to improve the documentation or the project in general, please [file an issue](https://github.com/cha0s/flecks/issues/new) for us.

View File

@ -0,0 +1,11 @@
---
description: It might matter where your code is running.
---
# Isomorphism
All this code we're writing could be running on your Node.js server, it could be running in the
browser, or both.
flecks solves this problem with [platforms](#todo) and the intelligent inclusion of only the code
relevant to the platform where the code is running.

View File

@ -0,0 +1,19 @@
import CodeBlock from '@theme/CodeBlock';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
export default function PackageInstall({pkg}) {
return (
<Tabs>
<TabItem value="npm" label="npm" default>
<CodeBlock language="bash">npm install {pkg}</CodeBlock>
</TabItem>
<TabItem value="yarn" label="Yarn" default>
<CodeBlock language="bash">yarn add {pkg}</CodeBlock>
</TabItem>
<TabItem value="bun" label="Bun" default>
<CodeBlock language="bash">bun install {pkg}</CodeBlock>
</TabItem>
</Tabs>
);
}

41
website/pages/index.jsx Normal file
View File

@ -0,0 +1,41 @@
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import Heading from '@theme/Heading';
import styles from './index.module.css';
function HomepageHeader() {
const {siteConfig} = useDocusaurusContext();
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<Heading as="h1" className="hero__title">
{siteConfig.title}
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/docs"
>
Your documentation here
</Link>
</div>
</div>
</header>
);
}
export default function Home() {
const {siteConfig} = useDocusaurusContext();
return (
<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />"
>
<HomepageHeader />
</Layout>
);
}

View File

@ -0,0 +1,23 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
}
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
}

43
website/sidebars.js Normal file
View File

@ -0,0 +1,43 @@
export default {
flecksSidebar: [
'introduction',
{
type: 'category',
label: 'Getting Started',
link: {
type: 'generated-index',
},
collapsed: false,
items: [
'installation',
'configuration',
'creating-flecks',
],
},
{
type: 'category',
label: 'Guides',
link: {
type: 'generated-index',
},
collapsed: false,
items: [
'documentation',
'isomorphism',
],
},
{
type: 'category',
label: 'Generated details',
link: {
type: 'generated-index',
},
items: [
'flecks/@flecks/dox/hooks',
'flecks/@flecks/dox/config',
'flecks/@flecks/dox/build-configs',
'flecks/@flecks/dox/TODO',
],
},
],
};