Skip to content

Commit 25f509b

Browse files
Merge pull request #7 from SimplrJS/feature/lerna
Feature/lerna
2 parents 97758da + 620e7ad commit 25f509b

File tree

87 files changed

+1872
-3269
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+1872
-3269
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,4 @@ paket-files/
250250
# JetBrains Rider
251251
.idea/
252252
*.sln.iml
253+
yarn.lock

docs/2017-04/2017-04-08.md

Lines changed: 0 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +0,0 @@
1-
## April 8 ([discuss](https://github.com/SimplrJS/simplr-forms/pull/1))
2-
3-
### Attendees
4-
5-
* [Dovydas](https://twitter.com/dovydasnav) (QuatroDev)
6-
* [Martynas](https://twitter.com/MartiogalaLT) (QuatroDev)
7-
8-
### Why do we need yet another forms library?
9-
10-
Over the past few years we worked with React, we tried **MANY** form libraries that are out there.
11-
12-
#### Problems with existing libraries
13-
14-
* There is no de-facto standard library for forms in React, like there is for routing ([react-router](https://github.com/ReactTraining/react-router))
15-
* They all have their limitations and usually big ones
16-
* Performance is usually bottlenecking as the project grows
17-
* No really flux friendly
18-
* Not friendly with TypeScript
19-
* There is not a single library that is built **in the React way**
20-
21-
Ok, so the big one is the libraries can never be consumed in a **React** way, which raises a whole bunch of other problems:
22-
* You have to learn everything from the ground up to use the library
23-
* When you write your app in a declarative react way, you have to fallback to imperative or semi-imperative way for forms
24-
* Library has to reinvent the wheel to *do things*
25-
* Lifecycle management becomes hell on earth
26-
* Race conditions appear out of the blue
27-
28-
I could go on here, but [Michael Jackson](https://github.com/mjackson) said it better [here](https://www.youtube.com/watch?v=Vur2dAFZ4GE)
29-
and the problems are more than apparent.
30-
31-
## So why do we start now?
32-
33-
Well, technically, we started almost a year ago (Jan 12, 2016) by building a `simplr-forms` v0.0.4 and used it internally.
34-
35-
v1.0.0 was also released internally on May 30, 2016.
36-
37-
v2.0.0 as well, released internally on September 7th, 2016.
38-
39-
We introduced v3.0.0-beta in Dec 7, 2016. And we made all possible mistakes during these 3 versions (hopefully).
40-
41-
We had 113 different alphas, betas, RCs and stable ones in between.
42-
43-
And more than a year later, we still don't see a proper library for forms out there. This is why we are putting the efforts into
44-
spec'ing, architecting and building the library out there in public.
45-
46-
### What's the plan?
47-
48-
For a few days already we were talking and ploting the architecture, raising and solving problems on the whiteboard.
49-
At the moment we are ready to to start coding, but first - we'll try to write out ideas.
50-
51-
### Integrity with flux
52-
53-
During 3 versions, we tried different approaches, to have forms:
54-
- Live on their own
55-
- Live in the flux lifecycle
56-
- Something in between the first two
57-
58-
At the moment, we think the best way to have responsive forms (as of fast response time), we have to make the library live on its own.
59-
60-
And for architectural integration (flux/redux/mobx/etc), we hope to make initial flux and redux versions ourselves and then get some help from community as the library becomes **the best forms library out there**.
61-
62-
## Let's get to the point
63-
64-
### Lifecycle
65-
66-
For forms lifecycle, we will be using somewhat flux-ish architecture of actions and at first and it's gonna be quick-and-dirty switches and immutable objects. Later on, we will incorporate [simplr-flux package](https://github.com/SimplrJS/simplr-flux), as we will open-source it soon.
67-
68-
### Principles
69-
70-
1. The source code is written in TypeScript.
71-
2. Architecture is compile-time checked as much as possible.
72-
3. Declarative API first. An imperative API is not going to be first-class citizen.
73-
4. Simplicity in developer-facing API, performance in the backend.
74-
5. Have React Fiber in mind.
75-
6. Validation is first-class citizen.
76-
77-
### Code samples
78-
79-
To get the idea how JSX looks:
80-
81-
```tsx
82-
<Form onSubmit={this.onFormSubmit}>
83-
<Text name="FirstName">
84-
<Validators.MinLength value={3} errorMessage="First name has to be at least ${value} long."/>
85-
<Validators.MaxLength value={10} errorMessage="First name has to be at most ${value} long."/>
86-
</Text>
87-
<Submit>Submit</Submit>
88-
</Form>
89-
```
90-
91-
And the rendered DOM:
92-
```html
93-
<form>
94-
<input type="text" name="FirstName" />
95-
<button type="submit">Submit</button>
96-
</form>
97-
```
98-
99-
As you can see, no wrappers, no custom elements, divs, spans or anything, just a clean form with inputs and buttons.
100-
101-
Having clean output really helps with styling, because you see the same structure in JSX, except for `simplr-forms` specific validators inside text element.
102-
103-
For now, we have to render validators in the virtual DOM, because `input` elements cannot have childrens (at least some of them).
104-
105-
That will change with React Fiber coming in as it will have the ability to return array of elements in the `render` function. With that change, we will be able to render validators alongside, but, of course, that is yet to come.
106-
107-
### Validators
108-
109-
A really important functionality while using forms is data validation.
110-
111-
And the main pains behind validation are:
112-
* Reusability of validators code
113-
* An easy way of defining the requirements of your data
114-
115-
Imperative API is probably the worst solution for this, which leaves a nice spot for declarative one. Unfortunately, there is no way of doing that today, but...
116-
117-
We have another package `simplr-validation`, which was released internally on Feb 15, 2016 and did not change much since. We had 19 versions of the package and most of them were adding functionality, not changing the core principles. Which means the package is done right from the start.
118-
119-
#### More interesting use case
120-
121-
Want to have your mind blown?
122-
123-
Suppose you need to validate your username to be:
124-
* 4 to 128 symbols of length
125-
* Unique in your system, which is a call to your server
126-
127-
Take a second to think how would you approach it today. Then look at this:
128-
129-
```tsx
130-
import { MinLength, MaxLength, DebouncerValidator } from "simplr-forms-core/validators";
131-
132-
<Text name="username">
133-
<MinLength value={4} errorMessage="Min length is ${value}!" />
134-
<MaxLength value={128} errorMessage="Max length is ${value}!" />
135-
/*
136-
Waits for 3 seconds before executing to the next validator.
137-
If the value changes before debouncer expires,
138-
the validation will be stopped and rejected as an error.
139-
Also, form store will ignore validation changes until the value is the newest,
140-
therefore store will update validation result to Valid or Invalid
141-
only after ALL needed validators are executed.
142-
*/
143-
<DebouncerValidator value={3000} />
144-
<CostyValidatorToTheServer />
145-
</Text>
146-
```
147-
148-
What you see here is a declarative way to check all of the requirements *AND* do it in an optimal manner, which is debouncing for some time until the user stops typing the username.
149-
150-
Mind blown? :tada: I hoped so. :clap:
151-
152-
### Coding time!
153-
154-
There are more things to cover here, but we are already hyped-up to get our hands dirty and start coding.
155-
156-
The feedback and questions are more than welcome!
157-
158-
------------
159-
160-
Please feel free to discuss these notes in the [corresponding pull request](https://github.com/SimplrJS/simplr-forms/pull/1).
161-

docs/2017-04/2017-04-14.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
## April 14 ([discuss](https://github.com/SimplrJS/simplr-forms/pull/4))
2+
3+
### Attendees
4+
5+
* [Dovydas](https://twitter.com/dovydasnav) (QuatroDev)
6+
* [Martynas](https://twitter.com/MartiogalaLT) (QuatroDev)
7+
* [Giedrius](https://twitter.com/giedrucis) (QuatroDev)
8+
* [Aurimas](https://twitter.com/waikys) (QuatroDev)
9+
10+
### simplr-forms-core is done for pre-alpha
11+
12+
During the week, we worked on `simplr-forms-core` to have a solid foundation for `simplr-forms-dom` and `simplr-forms-native`.
13+
14+
Most of the coding was done by Dovydas and Martynas, with valuable and fast reviews by Giedrius.
15+
Feels good to work with such an amazing team.
16+
17+
Also, Aurimas joined our efforts by preparing react-native app for development of `simplr-forms-native`. Thanks, Aurimas!
18+
19+
We will start working on both `dom` and `native` packages soon.
20+
21+
### So... What happened during the week?
22+
23+
We can confidently say that we have a solid first appearances of `core`, which consists of:
24+
* [`form-stores-handler`][1] - a general manager for all forms data stores
25+
* [`form-store`][2] - a data store for one particular form
26+
* [`base-form`][3] - a base component for a form to register to store and provide context for children, register with `form-stores-handler`, etc.
27+
* [`base-field`][4] - a base component for field that is aware of the parent form, registers and registers to and from form store, incorporates React lifecycle events, etc.
28+
29+
These 4 pretty much cover the base of the whole library.
30+
31+
Of course, there is more to it.
32+
33+
[`form-stores-handler`][1] and [`base-form`][3] extend [`ActionEmitter`][5] for you to be able to `addListener`
34+
for actions and know when the store is created, updates it's state or even more specific [actions][6],
35+
e.g. [value][7] or [props][8] are updated.
36+
37+
This enables another amazing thing: now we can externalize validation!
38+
39+
> Shoutout to Giedrius for publishing [`ActionEmitter`][5] right on time.
40+
> And for us all to debugging it in a single day :smile:
41+
42+
### Externalized validation
43+
44+
We understand that most developers use whatever they get out-of-the-box,
45+
especially if what they get is an easy-to-consume and also an optimal solution.
46+
47+
But sometimes usage of project-specific validation library is a must.
48+
49+
For example, there are quite a few industries with very specific data structures and their validations.
50+
Medicine, aviation, insurance, finance... And that's just a few on the tip of the tongue.
51+
52+
Therefore, externalizing validation is an amazing step forward to using `simplr-forms`
53+
no matter what data validation requirements you have.
54+
55+
### Testing
56+
57+
A library without tests these days is a scary and unstable bomb with a timer that shows gibberish on it's timer,
58+
i.e. you don't know when it is gonna hit you.
59+
60+
Therefore, we already have 44 tests in 4 test suites.
61+
62+
And we will write as much more as we need to ensure everything will progress forward
63+
and this library becomes de-facto a standard, a no brainer when anyone thinks about React and forms.
64+
65+
### What's next?
66+
67+
Releasing pre-alpha of `simplr-forms-core` and starting development of `simplr-forms-dom` and (maybe) `simplr-forms-native`.
68+
69+
Also, `simplr-validation` is coming into the light as we evaluate all of the peaces for it.
70+
71+
And now... It's coding time again! :tada:
72+
73+
------------
74+
75+
The feedback and questions are more than welcome!
76+
77+
------------
78+
79+
Please feel free to discuss these notes in the [corresponding pull request](https://github.com/SimplrJS/simplr-forms/pull/4).
80+
81+
[1]: https://github.com/SimplrJS/simplr-forms/blob/dev/packages/simplr-forms-core/src/stores/form-stores-handler.ts
82+
[2]: https://github.com/SimplrJS/simplr-forms/blob/dev/packages/simplr-forms-core/src/stores/form-store.ts
83+
[3]: https://github.com/SimplrJS/simplr-forms/blob/dev/packages/simplr-forms-core/src/abstractions/base-form.ts
84+
[4]: https://github.com/SimplrJS/simplr-forms/blob/dev/packages/simplr-forms-core/src/abstractions/base-field.ts
85+
[5]: https://github.com/SimplrJS/action-emitter
86+
[6]: https://github.com/SimplrJS/simplr-forms/tree/dev/packages/simplr-forms-core/src/actions
87+
[7]: https://github.com/SimplrJS/simplr-forms/blob/dev/packages/simplr-forms-core/src/actions/form-store-actions.ts#L3-L9
88+
[8]: https://github.com/SimplrJS/simplr-forms/blob/dev/packages/simplr-forms-core/src/actions/form-store-actions.ts#L11-L17

lerna.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"lerna": "2.0.0-rc.1",
3+
"packages": [
4+
"packages/*"
5+
],
6+
"version": "4.0.0-alpha",
7+
"command": {
8+
"init": {
9+
"exact": true
10+
}
11+
}
12+
}

package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "simplr-forms",
3+
"private": true,
4+
"scripts": {},
5+
"devDependencies": {
6+
"lerna": "2.0.0-rc.1",
7+
"typescript": "2.3.0"
8+
}
9+
}

packages/simplr-forms-core/__tests__/stores/form-store.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,49 @@ describe("Form store", () => {
157157
}
158158
});
159159

160+
it("skip validation when newValue has expired", async (done) => {
161+
const formId = "FORM-ID";
162+
const fieldId = "FIELD-ID";
163+
const initialValue = "INITIAL-VALUE";
164+
const formStore = new FormStore(formId);
165+
const formError = "field error";
166+
167+
formStore.RegisterField(fieldId, initialValue);
168+
const validationPromise = new Promise<void>((resolve, reject) => {
169+
setTimeout(() => {
170+
reject(formError);
171+
}, 50);
172+
});
173+
174+
formStore.Validate(fieldId, validationPromise);
175+
176+
// Imitate removal of last letter
177+
formStore.ValueChanged(fieldId, initialValue.slice(0, initialValue.length - 1));
178+
179+
try {
180+
expect(formStore.GetField(fieldId).Validating).toBe(true);
181+
} catch (error) {
182+
done.fail(error);
183+
}
184+
185+
try {
186+
await validationPromise;
187+
} catch (err) {
188+
// Validation promise was rejected
189+
// Expects in the subsequent try block
190+
}
191+
192+
try {
193+
// It SHOULD still validating to be true because validation was skipped of expired value
194+
expect(formStore.GetField(fieldId).Validating).toBe(true);
195+
expect(formStore.GetField(fieldId).Error).toBeUndefined();
196+
} catch (err) {
197+
done.fail(err);
198+
}
199+
200+
done();
201+
});
202+
160203
it("registers field with props", () => {
161204
const formId = "FORM-ID";
162205
const fieldId = "FIELD-ID";

packages/simplr-forms-core/__tests__/tsconfig.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@
1111
"pretty": true,
1212
"strict": true,
1313
"noEmit": true,
14-
"noUnusedLocals": true
14+
"noUnusedLocals": true,
15+
"lib": [
16+
"dom",
17+
"dom.iterable",
18+
"es6"
19+
]
1520
},
1621
"exclude": [
1722
"node_modules",

0 commit comments

Comments
 (0)