Skip to content
This repository was archived by the owner on Feb 15, 2025. It is now read-only.

Commit 41a4cdf

Browse files
authored
Merge pull request #83 from agile-ts/develop
Develop
2 parents 75543c0 + feec19e commit 41a4cdf

File tree

4 files changed

+181
-41
lines changed

4 files changed

+181
-41
lines changed

docs/examples/react/All.mdx

+3
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,6 @@ export const CodeSandBoxEmbed = ({ uri, height }) => (
4444
## 👴 First State [Class Component]
4545
<CodeSandBoxEmbed uri={"agilets-first-state-with-hoc-1qdew"}/>
4646

47+
## ✔️ Simple Todo List
48+
<CodeSandBoxEmbed uri={"agilets-simple-todo-list-glmc4"}/>
49+

docs/main/Introduction.md

+64-21
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ sidebar_label: Introduction
55
slug: /introduction/
66
---
77

8-
> **Global, Spacy, Scalable State and Logic Framework**
8+
> **Global State and Logic Framework**
99
1010
<a href="https://github.com/agile-ts/agile">
1111
<img src="https://img.shields.io/github/license/agile-ts/agile.svg?label=license&style=flat&colorA=293140&colorB=4a4872" alt="GitHub License"/></a>
@@ -21,18 +21,12 @@ slug: /introduction/
2121
<br />
2222
<br />
2323

24-
:::warning
25-
26-
These docs are work in progress
27-
and not completed yet!
28-
29-
:::
30-
3124
## 👋 Introduction
3225

33-
AgileTs is a global, simple, well-tested State Management Framework implemented in TypeScript.
34-
It's more flexible and boilerplate-free than frameworks like Redux and has a powerful approach to reducing the codebase size through a
35-
centralized memory design pattern. The philosophy behind AgileTs is simple:
26+
AgileTs is a global, simple, well-tested State Management Framework implemented in Typescript.
27+
It offers a reimagined API that focus on **developer experience** and allows you to **quickly** and **easily** manage your States.
28+
Besides States, AgileTs offers other powerful classes which make your life easier.
29+
The philosophy behind AgileTs is simple:
3630

3731
### 🚅 Straightforward
3832
Write minimalistic, boilerplate-free code that captures your intent.
@@ -43,6 +37,7 @@ Write minimalistic, boilerplate-free code that captures your intent.
4337
```ts
4438
MY_STATE.undo(); // Undo latest change
4539
MY_STATE.is({hello: "jeff"}); // Check if State has the Value '{hello: "jeff"}'
40+
MY_STATE.watch((value) => {console.log(value);}); // Watch on State changes
4641
```
4742
- Store State in any Storage, like [Local Storage](https://www.w3schools.com/html/html5_webstorage.asp)
4843
```ts
@@ -54,6 +49,12 @@ Write minimalistic, boilerplate-free code that captures your intent.
5449
MY_COLLECTION.collect({id: 1, name: "Frank"});
5550
MY_COLLECTION.collect({id: 2, name: "Dieter"});
5651
```
52+
- Compute State depending on other States
53+
```ts
54+
const MY_INTRODUCTION = App.createComputed(() => {
55+
return `Hello I am '${MY_NAME.vale}' and I use ${MY_STATE_MANAGER.value} for State Management.`;
56+
});
57+
```
5758

5859
### 🤸‍ Flexible
5960

@@ -69,7 +70,7 @@ The benefit of keeping logic separate to UI-Components is to make your code more
6970
### 🎯 Easy to Use
7071

7172
Learn the powerful tools of AgileTs in a short amount of time. An excellent place to start are
72-
our [Quick Start](./Installation.md) Guides, or if you are no fan of following any tutorial,
73+
our [Quick Start](./Installation.md) Guides, or if you don't like following any tutorial,
7374
jump straight into our [Example](../examples) section.
7475

7576

@@ -92,7 +93,7 @@ const MY_FIRST_STATE = App.createState("Hello Stranger!");
9293
// -- myComponent.whatever ------------------------------------------
9394

9495
// Finally, we bind the just initialized State to our desired UI-Component
95-
// And wolla, it's reactive. Everytime the State mutates the Component gets rerendered
96+
// And wolla, it's reactive. Everytime the State mutates the Component rerenders
9697
const myFirstState = useAgile(MY_FIRST_STATE); // returns value of State ("Hello Stranger!")
9798
```
9899

@@ -112,7 +113,7 @@ More examples can be found in the [Example](../examples/Indroduction.md) Section
112113
## 👨‍💻 When use AgileTs
113114

114115
AgileTs is thought to handle the business logic and logic in general that isn't explicitly bound to a Component of your application.
115-
So you should use AgileTs if you have to handle any global State and logic that you want to manage at a central place.
116+
We recommend using AgileTs to manage global States and their logic at a central place.
116117

117118
## 👨‍🏫 Learn AgileTs
118119

@@ -156,20 +157,62 @@ Without any context this section might be useless to you. As the name suggests,
156157
AgileTs, which are outsourced for a better overview. You might get redirected to parts of the Interface Section from
157158
other docs. Often to learn some more about specific properties of an interface.
158159

159-
## ❓ Something missing
160+
## 💬 What others say
160161

161-
If you find issues with the documentation or have suggestions on how to improve the documentation or the project in
162-
general, please [file an issue](https://github.com/agile/agile-ts/issues) for us or join
163-
our [Discord Community](https://discord.gg/T9GzreAwPH).
162+
Actually nothing, yet. If you want to be the first one, don't mind tweeting what ever you think about AgileTs.
163+
But don't forget to tag [@AgileFramework](https://twitter.com/AgileFramework), otherwise we can't find your tweet.
164+
165+
## 🌏 Creation of AgileTs
166+
167+
After exploring the many options for Javascript State libraries, including the popular Redux and MobX.
168+
I felt like I need a simpler, more straightforward solution.
169+
One day I accidentally stumbled across a stream from [@jamiepine](https://twitter.com/jamiepine).
170+
Jamie was using an interesting approach of State Management which I haven't seen yet.
171+
The framework he used, was PulseJs, the ancestor of AgileTs, so to speak.
172+
I liked this concept of State Management a lot and started using it in my own projects.
173+
At this point in time (spring 2020) it wasn't officially released.
174+
Therefore, it was quite buggy and had no documentation. But I figured out of to use it anyway
175+
and saved my finding in a small [pre-documentation](https://www.notion.so/bennoworkspace/Pulse-v3-No-official-Docs-4e92e8d02dd3423582fa95072806cab6) for PulseJs fellows.
176+
The months went by and no stable version came out. Not even a npm package.
177+
In July, I came to the conclusion to contribute to PulseJs, in order to speed the development process a bit up.
178+
But before I could do anything, I had to figure out how PulseJs works internally.
179+
After hours, I still haven't figured out how it works. This was due to the fact that I was a Typescript noob,
180+
and the codebase was not contributor friendly. (No comments, variables called x, a, b, ..).
181+
In order to learn how PulseJs works and to get a deeper understanding of Typescript,
182+
I decided to rewrite PulseJs from scratch in a separate project, later AgileTs.
183+
After a while, I got the hang and had a good understanding how PulseJs works under the hood.
184+
Now that I knew how PulseJs works, I could finally start contributing.
185+
My [first contribution](https://github.com/pulse-framework/pulse/commits?author=bennodev19) was on the 16th August 2020,
186+
where I refactored the `PulseHOC`. Unfortunately PulseJs was moving further and further away from my idea of an ideal State Management Framework.
187+
For instance, they introduced the `Pulse.Core`, which more or less forced me to define all States, Actions in a single object called `core`.
188+
I wouldn't say I liked that change since I switched among other reasons to PulseJs in order to not define all my States in a single object.
189+
Because of this relatively large design change, I would have to rebuild my entire State Management Logic of my applications.
190+
Which I didn't want to do, because I liked the old concept more.
191+
Luckily I had the refactored PulseJs version lying around, which I created to learn how PulseJs works internally and released it as an own framework called
192+
[agile-architecture](https://www.npmjs.com/package/agile-architecture).
193+
Agile-Architecture was at that point just an old refactored version of PulseJs without the `Pulse.Core`.
194+
Another reason I turned away from PulseJs, besides the different visions, was the leak of organisation.
195+
Some of my changes never got merged into the `master` branch. Why? Idk. But I am sure that it was not intentional.
196+
For instance, I fixed an annoying `usePulse` type issue, and 8 months later, it is still not merged into the `master`.
197+
Why should I contribute if my changes, which fixed a problem I had, will never be in the release version.
198+
Now that I had my own State Management Framework, I had more control and adapted it to my needs.
199+
Over the time AgileTs evolved away from PulseJs with other visions and goals.
200+
During this time I rewrote and optimized all internal classes, created tests and created a documentation.
201+
Today AgileTs has only a similar syntax to PulseJs. Internal, it works entirely different.
202+
203+
**Conclusion:** The idea of AgileTs is based on PulseJs, and I would have loved to continue working on PulseJs.
204+
But certain circumstances, such as a poor organization and different visions,
205+
have driven me to write my own State Manager based on the ground concept of PulseJs and MVVM frameworks.
164206

165207
## 🎉 Credits
166208

167209
AgileTs is inspired by MVVM frameworks like [MobX](https://mobx.js.org/README.html)
168210
and [PulseJs](https://github.com/pulse-framework/pulse).
169211

170-
## 💬 What others say
212+
## ❓ Something missing
171213

172-
Actually nothing, yet. If you want to be the first one, don't mind tweeting what ever you think about AgileTs.
173-
But don't forget to tag [@AgileFramework](https://twitter.com/AgileFramework), otherwise we can't find your tweet.
214+
If you find issues with the documentation or have suggestions on how to improve the documentation or the project in
215+
general, please [file an issue](https://github.com/agile/agile-ts/issues) for us or join
216+
our [Discord Community](https://discord.gg/T9GzreAwPH).
174217

175218

docs/main/StyleGuide.md

+108-14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,98 @@ Feel free to choose one of them and adapt it to your needs.
1717

1818
## 🚀 Inspiration 1
1919

20+
In general, the `Style Guide 1` is intended for smaller applications,
21+
since we put the whole business logic into one singe file called `store.ts`.
22+
If your applications scales and has many entities we don't recommend this Style Guide.
23+
It might get a mess to put everything into a singe file.
24+
25+
#### 🖥 Example Application
26+
- [Simple Todo List](https://codesandbox.io/s/agilets-simple-todo-list-glmc4)
27+
28+
In this Style-Guide, we have a so-called `store.ts` file at the top-level of our `src` folder, besides our UI-Components.
29+
The `store.ts` is thought to be the brain of our application and should contain all business logic
30+
and logic in general that isn't explicitly bound to a Component.
31+
This outsourcing of our logic makes our code more decoupled,
32+
portable, and above all easy testable.
33+
34+
Below you see where our `store.ts` file might be located in the main tree.
35+
```js {3} title="MyApp"
36+
my-app
37+
├── src
38+
│ └── store.ts
39+
│ └── render
40+
.
41+
```
42+
We use the `store.ts` file of a simple TODO application to visually illustrate how it can be constructed.
43+
44+
### 📝 store.ts
45+
46+
In the `store.ts` file we instantiate the Agile Instance (`Agile`) and define all Agile Sub Instances (`MY_TODOS`).
47+
In addition, all actions (`updateTodo()`, `toogleTodo()`, ..) and if you are using Typescript, interfaces (`TodoInterface`) are located here.
48+
If you are wondering why in the hell should I write the global States uppercase. Well, it has a simple advantage.
49+
You can easily differentiate between global and local States.
50+
```ts
51+
import { Agile } from "@agile-ts/core";
52+
import reactIntegration from "@agile-ts/react";
53+
54+
export interface TodoInterface {
55+
id: number;
56+
text: string;
57+
done: boolean;
58+
}
59+
60+
// Create Agile Instance
61+
const App = new Agile().integrate(reactIntegration);
62+
63+
// Create Collection (A dynamic Array of States)
64+
export const MY_TODOS = App.createCollection<TodoInterface>({
65+
key: "todos"
66+
}).persist(); // perist does store the Collection in the Local Storage
67+
68+
export const updateTodo = (id: number, text: string): void => {
69+
MY_TODOS.update(id, { text: text });
70+
};
71+
72+
export const toggleTodo = (id: number): void => {
73+
MY_TODOS.update(id, { done: true });
74+
};
75+
76+
export const removeTodo = (id: number): void => {
77+
MY_TODOS.remove(id).everywhere();
78+
};
79+
80+
export const addTodo = (text: string): void => {
81+
MY_TODOS.collect(
82+
{
83+
id: randomId(),
84+
text: text,
85+
done: false
86+
}
87+
);
88+
};
89+
```
90+
91+
92+
93+
<br />
94+
95+
---
96+
97+
<br />
98+
99+
100+
101+
## 🚀 Inspiration 2
102+
103+
At the first look the `Style Guide 2` might look very boiler-plate-ey.
104+
Every entity has its own directory, with a bunch of files.
105+
True, for small applications like a simple singe page application, this might be an overkill.
106+
But for enterprise applications that have planned to scale, its definitely worth a try.
107+
108+
#### 🖥 ExampleApplications
109+
Currently, no open source application is using this `Style Guide`.
110+
But I have worked with it in a private repo, and I love it.
111+
20112
In this Style-Guide, we have a so-called `core` at the top-level of our `src` folder, besides our UI-Components.
21113
The `core` is thought to be the brain of our application and should contain all business logic
22114
and logic in general that isn't explicitly bound to a Component.
@@ -32,7 +124,7 @@ my-app
32124
.
33125
```
34126
We use the `core` of a simple TODO application to visually illustrate how such a `core` can be constructed.
35-
Our todo application has two main [Entities](#📁-entities), that AgileTs should handle.
127+
Our todo application has two main [Entities](#📁-entities), which a State Manager like AgileTs should handle.
36128
The **User** and of course, the **TODO-Item**. These two parts are mapped in our `core`.
37129
```js title="TodoList-Core"
38130
core
@@ -55,7 +147,7 @@ core
55147
|── index.ts
56148
.
57149
```
58-
Each property you find above in the folder structure of the `TodoList-Core`, is described in detail below ⬇️.
150+
Each property you find in the above folder structure of the `TodoList-Core`, is described in detail below ⬇️.
59151

60152
## 📁 api
61153

@@ -65,8 +157,8 @@ If your application doesn't need to communicate to a `backend,` you can entirely
65157

66158
### 📝 index.ts
67159

68-
To make rest calls possible, we initialize our api class in the `index` file in the `api` folder.
69-
The defined API Instance will be mainly used in the [route](#-routets) file of an [Entity](#-entities),
160+
To make rest calls possible, we initialize our api class in the `index` file of the `api` folder.
161+
The defined API Instance will be mainly used in the [route](#-routets) files of the [Entities](#-entities),
70162
where we define the single routes to the backend.
71163
```ts title="index.ts"
72164
import API from '@agile-ts/api';
@@ -89,7 +181,7 @@ Each `Entity` manages its Data separately by doing rest calls or mutating States
89181
structured, readable and improves maintainability.
90182

91183
**For example:** <br />
92-
The _User Entity_ should only treat the user's whole logic and shouldn't do rest calls, for instance, for the _Todo Entity_.
184+
The _User Entity_ should only treat the user's whole logic and shouldn't do rest calls, for instance, for the _Todo-Item Entity_.
93185

94186
### 📝 index.ts
95187

@@ -111,15 +203,15 @@ export default {
111203

112204
### 📝 .action.ts
113205

114-
Here all actions of the Entity are listed.
206+
All actions of the Entity are defined in this file.
115207
In general, an action modifies the `State`, makes rest calls (through the functions provided by the [route.ts](#-routets) file),
116208
and computes some values if necessary.
117209
In principle, actions always happen in response to an event. For example, if the add todo button got clicked.
118210
Therefore, they should be called after action sounding names. For instance `createTodo`, `removeTodo`.
119211

120212
**For example:** <br />
121213
The creation of a Todo-Item in the UI-Layer triggers the `addTodo()` action,
122-
which then mutates our TodoItems State and makes a rest call to add the todo to our backend.
214+
which then mutates our TodoItems State and makes a rest call to the backend.
123215

124216
```ts title="todo.action.ts in 📁todo"
125217
import {TodoInterface} from './todo.interface';
@@ -141,7 +233,9 @@ export const addTodo = async (userId: string, description: string): Promise<void
141233
### 📝 .controller.ts
142234

143235
The `controller.ts` manages and represents the Agile Sub Instance (like States, Collections, ..) for an Entity.
144-
These Agile Sub Instances might get modified by the actions in the [action.ts](#📝-.action.ts) or bound to a Component in the UI-Layer.
236+
These Agile Sub Instances might get modified by the actions in the [action.ts](#📝-.action.ts) file or bound to Components in the UI-Layer.
237+
If you are wondering why in the hell should I write the global States uppercase. Well, it has a simple advantage.
238+
You can easily differentiate between global and local States.
145239
```ts title="todo.controller.ts in 📁todo"
146240
import {App} from '../../app';
147241
import {TodoInterface} from './todo.interface';
@@ -165,7 +259,7 @@ The `interface` section can be ignored by non [Typescript](https://www.typescrip
165259
:::
166260

167261
If you are a [Typescript](https://www.typescriptlang.org/) user, you properly want to create some interfaces for your Entity.
168-
These interfaces belonging to this Entity should be defined here.
262+
These interfaces belonging to the Entity should be defined here.
169263

170264
**For example** <br />
171265
In case of the TODO-Entity, it contains the `TodoInterface`.
@@ -181,8 +275,8 @@ export interface TodoInterface {
181275

182276
### 📝 .route.ts
183277

184-
In order to communicate to our server, we have to create [rest calls](https://en.wikipedia.org/wiki/Representational_state_transfer).
185-
For better maintainability, these rest calls are outsourced from the [action.ts](#-actionts) and provided by this section in function shape.
278+
In order to communicate to our backend, we have to create [rest calls](https://en.wikipedia.org/wiki/Representational_state_transfer).
279+
For better maintainability, these rest calls are outsourced from the [action.ts](#-actionts) file and provided by this section in function shape.
186280
These route functions should only be used in the [action.ts](#-actionts) of the Entity.
187281
It's not recommended calling them from outside the corresponding Entity.
188282
```ts title="todo.route.ts in 📁todo"
@@ -213,7 +307,7 @@ States, Collections, etc. can then be created with the help of this instance.
213307
import {Agile} from "@agile-ts/core";
214308
import reactIntegration from "@agile-ts/react";
215309

216-
export const App = new Agile({logJobs: true}).use(reactIntegration);
310+
export const App = new Agile({logJobs: true}).integrate(reactIntegration);
217311
```
218312

219313
## 📝 index.ts
@@ -247,11 +341,11 @@ export default core;
247341

248342

249343

250-
## 🚀 Inspiration 2
344+
## 🚀 Inspiration 3
251345

252346
:::note
253347

254-
There is no second Inspiration yet, but feel free to share your own 'style guide' inspiration here. Every contribution
348+
There is no third Inspiration yet, but feel free to share your own 'style guide' inspiration here. Every contribution
255349
is welcome. :D
256350

257351
:::

0 commit comments

Comments
 (0)