diff --git a/.editorconfig b/.editorconfig
index 6e87a003da..493aaa0524 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -8,6 +8,5 @@ indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
-[*.md]
+[*.{md,mdx}]
max_line_length = off
-trim_trailing_whitespace = false
diff --git a/README.md b/README.md
index 025c21cb3f..4cae28f890 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://www.rx-angular.io/)
+[](https://rx-angular.io/)
# RxAngular 
@@ -7,10 +7,10 @@ performance and template rendering.
RxAngular is divided into different packages:
-- [📦@rx-angular/cdk](https://github.com/rx-angular/rx-angular/tree/main/libs/cdk/README.md)
-- [📦@rx-angular/eslint-plugin](https://github.com/rx-angular/rx-angular/tree/main/libs/eslint-plugin/README.md)
-- [📦@rx-angular/state](https://github.com/rx-angular/rx-angular/tree/main/libs/state/README.md)
-- [📦@rx-angular/template](https://github.com/rx-angular/rx-angular/tree/main/libs/template/README.md)
+- [📦@rx-angular/cdk](https://rx-angular.io/docs/cdk)
+- [📦@rx-angular/eslint-plugin](https://rx-angular.io/docs/eslint-plugin)
+- [📦@rx-angular/state](https://rx-angular.io/docs/state)
+- [📦@rx-angular/template](https://rx-angular.io/docs/template)
Used together, you get a powerful tool for developing high-performance angular applications with or without NgZone.
@@ -63,17 +63,17 @@ This repository holds a set of helpers to create **fully reactive** as well as *
## Packages
-Find details in the linked readme files below for installation and setup instructions, examples and resources.
+Find details in the links to the official docs below for installation and setup instructions, examples and resources.
-- [📦@rx-angular/cdk](https://github.com/rx-angular/rx-angular/tree/main/libs/cdk/README.md) - Component Development Kit
-- [📦@rx-angular/eslint-plugin](https://github.com/rx-angular/rx-angular/tree/main/libs/eslint-plugin/README.md) - ESLint Plugin
-- [📦@rx-angular/state](https://github.com/rx-angular/rx-angular/tree/main/libs/state/README.md) - Imperative & Reactive Component State-Management
-- [📦@rx-angular/template](https://github.com/rx-angular/rx-angular/tree/main/libs/template/README.md) - High-Performance Non-Blocking Rendering
+- [📦@rx-angular/cdk](https://rx-angular.io/docs/cdk) - Component Development Kit
+- [📦@rx-angular/eslint-plugin](https://rx-angular.io/docs/eslint-plugin) - ESLint Plugin
+- [📦@rx-angular/state](https://rx-angular.io/docs/state) - Imperative & Reactive Component State-Management
+- [📦@rx-angular/template](https://rx-angular.io/docs/template) - High-Performance Non-Blocking Rendering
## Version Compatibility
-| Angular | RxJS | @rx-angular/state | @rx-angular/template | @rx-angular/cdk |
-|------------------------|----------------------|-------------------|----------------------|---------------------|
+| Angular | RxJS | @rx-angular/state | @rx-angular/template | @rx-angular/cdk |
+| ---------------------- | -------------------- | ----------------- | -------------------- | ------------------- |
| `14` | `^7.4.0` | `> 1.4.6` | `> 1.0.0-beta.29` | `> 1.0.0-alpha.10` |
| `^12.0.0` or `^13.0.0` | `^6.5.5` or `^7.4.0` | `> 1.4.6` | `> 1.0.0-beta.29` | `> 1.0.0-alpha.10` |
| `^11.0.0` | `^6.5.5` | `<= 1.4.6` | `<= 1.0.0-beta.29` | `<= 1.0.0-alpha.10` |
diff --git a/apps/demos/src/app/features/template/render-callback/renderCallback.md b/apps/demos/src/app/features/template/render-callback/renderCallback.md
index 7cba5956bd..efa0f06b95 100644
--- a/apps/demos/src/app/features/template/render-callback/renderCallback.md
+++ b/apps/demos/src/app/features/template/render-callback/renderCallback.md
@@ -1,56 +1,62 @@
### Using the RenderCallback
- The RenderCallback notifies users about when the `LetDirective` "rendered" the latest values of the
- active template.
- At the time the `rendered` callback emits, the DOM should be already updated with the latest changes connected
- to this instance.
- The callback will emit the latest value rendered to the template.
-
- Since structural directives currently do not support `@Output` bindings, developers have to use other mechanics
- to access this event.
- Beyond the traditional approach the `LetDirectives` offers an input property as renderCallback.
- This enables developers to bind a `NextObserver` (e.g. `Subject`) to the `LetDirective`which will emit after
- rendering happened.
-
- You can choose between using the [Template syntax](https://angular.io/guide/template-syntax), injecting the
- `LetDirective` as `@ViewChild()` and subscribe the event manually or providing a RenderCallback on your own.
-
- Please note that due to the built-in
- [coalescing][https://github.com/rx-angular/rx-angular/blob/main/libs/template/docs/concepts.md] can cause this
- callback different in situations where multiple `LetDirectives` are used to render the same
- `Component`. Make sure to subscribe to every instance in your component to avoid missing render
- notifications.
-
- #### RenderCallback Input
- ```html
-
-
- ```
- ```ts
- // inside of your component
- \@ViewChild(LetDirective) rxLet: LetDirective;
- this.rxLet.rendered.subscribe(value => console.log('afterRender', value));
- ```
+
+The RenderCallback notifies users about when the `LetDirective` "rendered" the latest values of the
+active template.
+At the time the `rendered` callback emits, the DOM should be already updated with the latest changes connected
+to this instance.
+The callback will emit the latest value rendered to the template.
+
+Since structural directives currently do not support `@Output` bindings, developers have to use other mechanics
+to access this event.
+Beyond the traditional approach the `LetDirectives` offers an input property as renderCallback.
+This enables developers to bind a `NextObserver` (e.g. `Subject`) to the `LetDirective`which will emit after
+rendering happened.
+
+You can choose between using the [Template syntax](https://angular.io/guide/template-syntax), injecting the
+`LetDirective` as `@ViewChild()` and subscribe the event manually or providing a RenderCallback on your own.
+
+Please note that due to the built-in
+[coalescing][https://rx-angular.io/docs/template/concepts] can cause this
+callback different in situations where multiple `LetDirectives` are used to render the same
+`Component`. Make sure to subscribe to every instance in your component to avoid missing render
+notifications.
+
+#### RenderCallback Input
+
+```html
+
+
+```
+
+```ts
+// inside of your component
+\@ViewChild(LetDirective) rxLet: LetDirective;
+this.rxLet.rendered.subscribe(value => console.log('afterRender', value));
+```
diff --git a/apps/demos/src/app/features/tutorials/basics/Readme.md b/apps/demos/src/app/features/tutorials/basics/README.md
similarity index 99%
rename from apps/demos/src/app/features/tutorials/basics/Readme.md
rename to apps/demos/src/app/features/tutorials/basics/README.md
index 3a46791e62..bf478916f2 100644
--- a/apps/demos/src/app/features/tutorials/basics/Readme.md
+++ b/apps/demos/src/app/features/tutorials/basics/README.md
@@ -24,6 +24,7 @@ There is a background process running in the child component. The input value fr
Furthermore, there is a refresh button. A click on it also refreshes the list data.
The topics we will discuss in this tutorial include:
+
- [Setting up a reactive state, selections, and UI interactions][1-setup]
- [Handling @Inputs reactively][2-input-bindings]
- [Handling @Output reactively][3-output-bindings]
diff --git a/apps/docs/docs/cdk/_category_.json b/apps/docs/docs/cdk/_category_.json
index ec7cadc82b..111d9f8584 100644
--- a/apps/docs/docs/cdk/_category_.json
+++ b/apps/docs/docs/cdk/_category_.json
@@ -1,8 +1,3 @@
{
- "label": "@rx-angular/cdk",
- "position": 1,
- "link": {
- "type": "generated-index",
- "description": "RxAngular CDK"
- }
+ "label": "@rx-angular/cdk"
}
diff --git a/apps/docs/docs/cdk/api/_category_.json b/apps/docs/docs/cdk/api/_category_.json
index 8ec0189c3a..b53f31d81a 100644
--- a/apps/docs/docs/cdk/api/_category_.json
+++ b/apps/docs/docs/cdk/api/_category_.json
@@ -1,4 +1,9 @@
{
"label": "API",
- "link": null
+ "position": 100,
+ "link": {
+ "type": "generated-index",
+ "title": "API reference",
+ "slug": "/state/cdk"
+ }
}
diff --git a/apps/docs/docs/cdk/cdk.mdx b/apps/docs/docs/cdk/cdk.mdx
new file mode 100644
index 0000000000..1e9e8cb85b
--- /dev/null
+++ b/apps/docs/docs/cdk/cdk.mdx
@@ -0,0 +1,15 @@
+---
+sidebar_label: '@rx-angular/cdk'
+sidebar_position: 1
+title: 'CDK'
+hide_title: true
+---
+
+import Readme, { toc as readmeToc } from '@site/../../libs/cdk/README.md';
+
+
+
+
+
+
+export const toc = [...readmeToc];
diff --git a/libs/cdk/coalescing/docs/Readme.md b/apps/docs/docs/cdk/coalescing/_docs.md
similarity index 80%
rename from libs/cdk/coalescing/docs/Readme.md
rename to apps/docs/docs/cdk/coalescing/_docs.md
index 0f8153ef46..34bf1ca6de 100644
--- a/libs/cdk/coalescing/docs/Readme.md
+++ b/apps/docs/docs/cdk/coalescing/_docs.md
@@ -1,13 +1,13 @@
-# Resources
+## Resources
-**Example applications:**
+**Example applications:**
A demo application is available on [GitHub](https://github.com/BioPhoton/rx-angular-cdk-coalescing).
-# Motivation
+## Motivation
Coalescing means multiple things "merge" into one.
-
+
If two or more things coalesce, they come merge togeather into one thing or system.
Natively Angular is using this under the hood already for a long time.
@@ -16,13 +16,13 @@ In RxAngular coalescing is used for merging multiple emissions, streams or calls
The next example shows the effect of coalescing visualized in flame charts.
-
+
_no coalescing vs. coalescing on microtask. visualized in flame charts_
The non-coalesced component has three consequetive heavy computations in the template whilest the coalesced component only has to do the same computation once in order to complete the same job.
Even on a small components scale the difference in performance can be significant.
-# Available Approaches
+## Available approaches
There are 2 places in Angular we have coalescing already implemented in the framework:
@@ -31,6 +31,7 @@ There are 2 places in Angular we have coalescing already implemented in the fram
- RxAngular adds another option where we can apply those techniques manually wherever we want.
**The Benefits**
+
- ✅ Coalescing techniques as RxJS operators
- ✅ Configurable durationSelector for all kind of scheduling methods
- ✅ Scope coalescing to a specific component or object
@@ -40,7 +41,7 @@ There are 2 places in Angular we have coalescing already implemented in the fram
Before we dive into the usage of this package we may want to understand already existing coalescing mechanisms in Angular and why it is used to get better performance.
-## Coalescing of `ApplicationRef#tick` calls
+### Coalescing of `ApplicationRef#tick` calls
As chances are high multiple changes occur at the same time Angular's change detection would end up getting triggered also multiple times.
This is the reason why Angular implemented coalescing for those calls.
@@ -49,16 +50,16 @@ In the following image we see 3 changes that call `ChangeDetectorRef#markForChec
The internal logic then delays these calls for a while by using `requestAnimationFrame` and calls `ApplicationRef#tick` only one time after the next animation frame arrives.
This way Angular's change detection and re-evaluation/re-rendering of the app get executed only once for all calls that fall into the duration from invocation until the next animation frame lands.
-
+
If we visualize the same behavior based on flame charts, we can understand the internal logic and naming of the different steps in that process more technically.
The graphic shows the start of the coalescing duration, the different browser events and where the execution of certain logic is moved to.
-
+
With that information, we should be able to reflect this concept also onto other usages in Angular.
-## Coalescing with `ngZoneEventCoalescing` settings
+### Coalescing with `ngZoneEventCoalescing` settings
Angular's bootstrap method can be configured to use a config property called `ngZoneEventCoalescing`.
@@ -68,12 +69,12 @@ platformBrowserDynamic()
.catch((err) => console.error(err));
```
-This setting applies the technique of coalescing to fired events bound by Angular.
+This setting applies the technique of coalescing to fired events bound by Angular.
It will coalesce any event emissions occurring during the duration of an animation frame and after that, run `ApplicationRef#tick` only one time instead of multiple times.
This is mainly impactful if we deal with event-heavy templates. The diagrams below shows the difference between 2 events with and without coalescing.
-
+


@@ -101,7 +102,7 @@ As these situations typically occur across multiple components or are hard to sc
```
-# RxAngular Coalescing operators
+## RxAngular coalescing operators
While developing RxAngular, one of the first things we had to tackle for performant change detection was coalescing of `ChangeDetectorRef#detectChanges` calls on component level,
but in fact, the shipped logic can be applied anywhere.
@@ -113,13 +114,13 @@ There are 2 main pieces to understand:
In the section usage we will go into more detail.
-## Marble Diagram
+### Marble Diagram
-
+
-
+
-## Setup
+### Setup
The coalescing features can be used directly from the `cdk` package or indirectly through the `template` package.
To do so, install the `cdk` package and, if needed, the packages depending on it:
@@ -132,7 +133,7 @@ npm i @rx-angular/cdk
yarn add @rx-angular/cdk
```
-## Usage
+### Usage
As coalescing was already explained in the Angular context, we can take that one step further and look at it in a more agnostic way.
@@ -156,19 +157,19 @@ RxAngular's `coalesceWith` operator helps to merge together when applied to the
from([1, 2, 3]).pipe(coalesceWith()).subscribe(doStuff); // 1 x doStuff logs 3
```
-### Coalescing duration
+#### Coalescing duration
By default, the duration in which values get united is derived from a micro task which executes immediately after the synchronous code got executed.
See the diagram for details:
-
+
To have more fine-grained control over the duration of coalescing an optional parameter `durationSelector` is provided.
`durationSelector` is of type `Observable` and the first emission of it terminates the coalescing duration.
You could pass e.g. `interval(0)` as `durationSelector` to use a `setInterval` as duration period.
-> **💡 Pro Tip**
+> **💡 Pro Tip**
> Even a longer duration based on milliseconds, e.g. `interval(500)` can be used as duration.
>
> For more information on the different scheduling options you could have a look at the different scheduling API's like
@@ -177,9 +178,9 @@ You could pass e.g. `interval(0)` as `durationSelector` to use a `setInterval` a
A real life example where `coalesceWith` comes in handy is runnning manual change detection with `ChangeDetectorRef#detectChanges()`.
The below diagram displays the cycle of updates, coalescing and rendering of values in a component.
-
+
-### Coalescing scope
+#### Coalescing scope
If we think about the underlying principle of coalescing a little bit more we may ask our self how the logic knows what to do? How is it done that some work that is scheduled multiple times get executed only once?
Surely there must be a variable stored somewhere that knows if coalescing is currently ongoing or not.
@@ -222,12 +223,12 @@ With this in mind, we can go one step further and look at change detection acros
The following diagram illustrates change detection in component level:
-
+
-> **⚠ Notice:**
+> **⚠ Notice:**
> Be cautious with globally shared coalescing scopes. It could lead to unwanted behaviour and loss of updates when used incorrectly.
-
+
Again, why is this the case?
@@ -246,11 +247,11 @@ from([component1, component2, component3])
.subscribe((component) => component.cdr.detectChanges()); // only component 3 gets called
```
-# Example usage in RxAngular
+## Example usage in RxAngular
As RxAngular/cdk packages are not only here to build other tools but also to build RxAngular it self lets see where we used it under the hood.
-In the [template](https://github.com/rx-angular/rx-angular/edit/main/libs/template) package we have a couple of directives and pipes that use the coalescing logic internally.
+In the [template](https://rx-angular.io/docs/template) package we have a couple of directives and pipes that use the coalescing logic internally.
It is done in a way where the directives and services automatically take the most performant scope to bind coalescing to.
The example below shows multiple components rendering the same or parts of the same value. The scopes are applied automatically and named for all different usages.
@@ -261,4 +262,4 @@ The example below shows multiple components rendering the same or parts of the s
- As pipe in the component's template
- As structural directive in the component's template
-
+
diff --git a/apps/docs/docs/cdk/coalescing/coalescing.mdx b/apps/docs/docs/cdk/coalescing/coalescing.mdx
new file mode 100644
index 0000000000..ebe7720003
--- /dev/null
+++ b/apps/docs/docs/cdk/coalescing/coalescing.mdx
@@ -0,0 +1,20 @@
+---
+sidebar_label: 'Coalescing'
+sidebar_position: 1
+title: 'Coalescing'
+hide_title: true
+---
+
+import Readme, {
+ toc as readmeToc,
+} from '@site/../../libs/cdk/coalescing/README.md';
+import Docs, { toc as docsToc } from './_docs.md';
+
+
+
+
+
+
+
+
+export const toc = [...readmeToc, ...docsToc];
diff --git a/libs/cdk/coercing/docs/Readme.md b/apps/docs/docs/cdk/coercing/_docs.md
similarity index 94%
rename from libs/cdk/coercing/docs/Readme.md
rename to apps/docs/docs/cdk/coercing/_docs.md
index e800bf8331..497cad20ef 100644
--- a/libs/cdk/coercing/docs/Readme.md
+++ b/apps/docs/docs/cdk/coercing/_docs.md
@@ -1,18 +1,17 @@
-# Resources
+## Resources
-**Example applications:**
+**Example applications:**
A demo application is available on [GitHub](https://github.com/BioPhoton/rx-angular-cdk-coercing).
-# Motivation
+## Motivation
Coercing, or to be more specific type coercion is the process of converting a value from one type to another.
-This can be done with any primitive value in JavaScript. e.g. number, string, Symbol, boolean, null, undefined.
+This can be done with any primitive value in JavaScript. e.g. number, string, Symbol, boolean, null, undefined.
Another type where we also can apply coercing is the `Observable` type.

-
In practice you can apply this technique in 2 ways:
- **explicitly** e.g. `Number(string)` coercres a string to a number
@@ -54,10 +53,10 @@ export class AppComponent {
}
```
-# Available Approaches
+## Available approaches
- [@angular/cdk/coercion](https://www.npmjs.com/package/@angular/cdk)
-- [@rx-angular/cdk/coercion](https://www.npmjs.com/package/@rx-angular/cdk)
+- [@rx-angular/cdk/coercing](https://www.npmjs.com/package/@rx-angular/cdk)
**The Benefits of RxAngular**
@@ -67,7 +66,7 @@ export class AppComponent {
- ✅ Fully tested
- ✅ Well Documented
-# RxAngular Coercing helpers
+## RxAngular coercing helpers
**Factories:**
@@ -82,7 +81,7 @@ export class AppComponent {
In the section usage we will go into more detail.
-## Setup
+### Setup
The coalescing features can be used directly from the `cdk` package or indirectly through the `template` package.
To do so, install the `cdk` package and, if needed, the packages depending on it:
@@ -95,7 +94,7 @@ npm i @rx-angular/cdk
yarn add @rx-angular/cdk
```
-## Usage
+### Usage
In the following we will sketch some usecases where coercing operators can be used.
@@ -163,7 +162,9 @@ This comes in handy for later processing and improves performance.
})
export class AppComponent {
_prop1 = new Subject>();
- prop1Observables$: Observable = this._prop1.pipe(coerceDistinctWith());
+ prop1Observables$: Observable = this._prop1.pipe(
+ coerceDistinctWith()
+ );
@Input()
set prop1(val: Observable | number) {
@@ -199,8 +200,8 @@ A minimal implementation if it would look like this:
export class AppComponent {
_prop1 = new Subject>();
prop1Changes$: Observable = this._prop1.pipe(
- coerceDistinctWith(),
- switchAll()
+ coerceDistinctWith(),
+ switchAll()
);
@Input()
@@ -215,7 +216,6 @@ Here we apply the `switchAll` operator to unsubscribe the previouse observable a
by using the `coerceAllFactory` function we can compose this pattern with less code and still have the option to decide on the way of compostion.
-
```typescript
@Component({
// ...
@@ -223,7 +223,7 @@ by using the `coerceAllFactory` function we can compose this pattern with less c
export class AppComponent {
_prop1 = coerceAllFactory();
prop1Changes$: Observable = this._prop1.values$;
-
+
@Input()
set prop1(val: Observable | number) {
this._prop1.next(val);
@@ -233,7 +233,7 @@ export class AppComponent {
Another benefit here is that only the `next` method is exposed.
-By default a normal `Subject` is used and `switchAll` is applied.
+By default a normal `Subject` is used and `switchAll` is applied.
As there are quite some ways to process higher order observables the factory provides optional configuration parameter.
```typescript
diff --git a/apps/docs/docs/cdk/coercing/coercing.mdx b/apps/docs/docs/cdk/coercing/coercing.mdx
new file mode 100644
index 0000000000..ed5012070a
--- /dev/null
+++ b/apps/docs/docs/cdk/coercing/coercing.mdx
@@ -0,0 +1,20 @@
+---
+sidebar_label: 'Coercing'
+sidebar_position: 1
+title: 'Coercing'
+hide_title: true
+---
+
+import Readme, {
+ toc as readmeToc,
+} from '@site/../../libs/cdk/coercing/README.md';
+import Docs, { toc as docsToc } from './_docs.md';
+
+
+
+
+
+
+
+
+export const toc = [...readmeToc, ...docsToc];
diff --git a/libs/cdk/notifications/docs/Readme.md b/apps/docs/docs/cdk/notifications/_docs.md
similarity index 62%
rename from libs/cdk/notifications/docs/Readme.md
rename to apps/docs/docs/cdk/notifications/_docs.md
index aa58f1d578..0ecf842231 100644
--- a/libs/cdk/notifications/docs/Readme.md
+++ b/apps/docs/docs/cdk/notifications/_docs.md
@@ -1,9 +1,9 @@
-# Resources
+## Resources
-**Example applications:**
+**Example applications:**
A demo application is available on [GitHub](https://stackblitz.com/edit/angular-async-ngif-with-error-tpb4uc).
-# Motivation
+## Motivation

@@ -12,50 +12,45 @@ When dealing with asynchronouse code we always have some contextual information
The a good example is a `[Promise](https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise)` used in a UI where you can list items and search them.
The following states can apply to this UI:
+
- Initial loading of the list. (loading spinner)
- Display of the data (The actual value is now given and displayed)
- Error in the asynchronouse process (A error message is displayed)
- Completion of the process (Communicates that the process is completed)
- Subsquent search actions (loading spinner)
-
```typescript
@Component({
selector: 'any-component',
template: `
-
+
- `
+ `,
})
-export class AnyComponent {
+export class AnyComponent {
// ...
}
```
If we organize them visually 4 states, 3 of them contextual are given:
+
- **suspense** (communicating progress)
- update/**next** (the result it self, or parts of it)
- **error** (communicating error)
@@ -67,39 +62,39 @@ For those states we use the term **reactive context** which includes the state a
Whith this concept we can create helpers that support to implement the handling of reactive context in a more elegant way.
-A good example is the [`rxLet`](https://github.com/rx-angular/rx-angular/blob/main/libs/template/docs/api/let-directive.md) directive:
+A good example is the [`rxLet`](../../template/api/let-directive.md) directive:
```typescript
@Component({
selector: 'any-component',
template: `
-
+
Count: {{ count }}
-
- Negative Count
-
-
-
- Error!
-
+ Negative Count
-
- Complete!
-
+ Error!
-
- Loading...
-
- `
+ Complete!
+
+ Loading...
+ `,
})
-export class AnyComponent {
+export class AnyComponent {
// ...
}
```
-
**The Benefits**
- ✅ A mental model for contextual state
@@ -122,7 +117,7 @@ yarn add @rx-angular/cdk
## Usage
-The whole section is about extending the notification channels with a 4th state.
+The whole section is about extending the notification channels with a 4th state.
The new type is called `RxNotifications`. In the following we will see a couple of helper functions that deal with that type.
For wrapping a value into a RxNotification we provide 3 helpers:
@@ -130,30 +125,39 @@ For wrapping a value into a RxNotification we provide 3 helpers:
**RxErrorNotification**
```typescript
- const errorNotification: RxErrorNotification = toRxErrorNotification();
- const errorNotification: RxErrorNotification = toRxErrorNotification(new Error());
- const errorNotification: RxErrorNotification = toRxErrorNotification(new Error(), 'lastValue');
+const errorNotification: RxErrorNotification = toRxErrorNotification();
+const errorNotification: RxErrorNotification = toRxErrorNotification(
+ new Error()
+);
+const errorNotification: RxErrorNotification = toRxErrorNotification(
+ new Error(),
+ 'lastValue'
+);
```
**toRxSuspenseNotification**
```typescript
- const toRxSuspenseNotification: RxSuspenseNotification = toRxSuspenseNotification();
- const toRxSuspenseNotification: RxSuspenseNotification = toRxSuspenseNotification('lastValue');
+const toRxSuspenseNotification: RxSuspenseNotification =
+ toRxSuspenseNotification();
+const toRxSuspenseNotification: RxSuspenseNotification =
+ toRxSuspenseNotification('lastValue');
```
-
+
**toRxCompleteNotification**
```typescript
- const toRxCompleteNotification: RxCompleteNotification = toRxCompleteNotification();
- const toRxCompleteNotification: RxCompleteNotification = toRxCompleteNotification('lastValue');
+const toRxCompleteNotification: RxCompleteNotification =
+ toRxCompleteNotification();
+const toRxCompleteNotification: RxCompleteNotification =
+ toRxCompleteNotification('lastValue');
```
**rxMaterialize**
```typescript
- const websocketUpdates$: Observable = interval(3000);
- const materialized$: Observable> = websocketUpdates.pipe(
- rxMaterialize()
- );
+const websocketUpdates$: Observable = interval(3000);
+const materialized$: Observable> = websocketUpdates.pipe(
+ rxMaterialize()
+);
```
diff --git a/apps/docs/docs/cdk/notifications/notifications.mdx b/apps/docs/docs/cdk/notifications/notifications.mdx
new file mode 100644
index 0000000000..842ddbdf2e
--- /dev/null
+++ b/apps/docs/docs/cdk/notifications/notifications.mdx
@@ -0,0 +1,20 @@
+---
+sidebar_label: 'Notifications'
+sidebar_position: 1
+title: 'Notifications'
+hide_title: true
+---
+
+import Readme, {
+ toc as readmeToc,
+} from '@site/../../libs/cdk/notifications/README.md';
+import Docs, { toc as docsToc } from './_docs.md';
+
+
+
+
+
+
+
+
+export const toc = [...readmeToc, ...docsToc];
diff --git a/libs/cdk/render-strategies/docs/README.md b/apps/docs/docs/cdk/render-strategies/_docs.md
similarity index 90%
rename from libs/cdk/render-strategies/docs/README.md
rename to apps/docs/docs/cdk/render-strategies/_docs.md
index 6ad9e79910..1d1399aaea 100644
--- a/libs/cdk/render-strategies/docs/README.md
+++ b/apps/docs/docs/cdk/render-strategies/_docs.md
@@ -1,6 +1,6 @@
-# Render Strategies
+## Render strategies
-##### Explicit fine-grained control of change detection in Angular
+> Explicit fine-grained control of change detection in Angular

@@ -15,7 +15,7 @@ Furthermore, they provide new ways of explicitly tying truly push-based state ma
A strategy exposes the work to perform (e.g. `cdRef#markForCheck`, `cdRef#detectChanges`) as well as the scheduling mechanism to developers for configuration & customization via the interface `RxStrategyCredentials`.
-`Directive`s, `Service`s or `Component`s of your application can make use of these strategies as an easy API for the key [concepts](https://github.com/rx-angular/rx-angular/blob/main/libs/template/docs/concepts.md) of rendering performance.
+`Directive`s, `Service`s or `Component`s of your application can make use of these strategies as an easy API for the key [concepts](../../template/concepts/concepts.md) of rendering performance.
This architecture enables modern features like:
@@ -31,7 +31,7 @@ This architecture enables modern features like:
**BasicStrategies**
-[BasicStrategies](https://github.com/rx-angular/rx-angular/blob/master/libs/cdk/render-strategies/docs/basic-strategies.md) wrap modern ivy APIs like `ɵmarkDirty` and `ɵdetectChanges` as well as a strategy to "noop" change detection.
+[BasicStrategies](strategies/basic-strategies.md) wrap modern ivy APIs like `ɵmarkDirty` and `ɵdetectChanges` as well as a strategy to "noop" change detection.
As a fallback for the migration process or comparison testing, Angulars default change detection behaviour is also provided as a strategy.
This set aims to get the first option for zone-less rendering (`ɵmarkDirty`), more control on the top-down process, and improve performance drastically by only rendering components that received updates.
@@ -40,7 +40,7 @@ This set aims to get the first option for zone-less rendering (`ɵmarkDirty`), m
**ConcurrentStrategies**
-The [ConcurrentStrategies](https://github.com/rx-angular/rx-angular/blob/master/libs/cdk/render-strategies/docs/concurrent-strategies.md) utilize the latest technologies to enable priority-based change detection for non-blocking rendering and smooth user experiences. It combines the most performant scheduling techniques with a highly performant queueing mechanism.
+The [ConcurrentStrategies](strategies/concurrent-strategies.md) utilize the latest technologies to enable priority-based change detection for non-blocking rendering and smooth user experiences. It combines the most performant scheduling techniques with a highly performant queueing mechanism.
Read more about the internal techniques [here](https://www.npmjs.com/package/scheduler) or [here](https://github.com/WICG/scheduling-apis).
The name **ConcurrentStrategies** implies that concepts of [react concurrent mode](https://reactjs.org/docs/concurrent-mode-intro.html) are transported into the world of Angular.
@@ -53,7 +53,6 @@ With these sets of strategies and the possibility of switching them at runtime w

-
**Render strategies pave the way for truly non-blocking applications, targeted for any device or platform 🚀**
+
+
+export const toc = [...readmeToc, ...docsToc];
diff --git a/libs/cdk/render-strategies/docs/strategy-provider.md b/apps/docs/docs/cdk/render-strategies/rx-strategy-provider.md
similarity index 84%
rename from libs/cdk/render-strategies/docs/strategy-provider.md
rename to apps/docs/docs/cdk/render-strategies/rx-strategy-provider.md
index 155dd842cf..f7a22cfd11 100644
--- a/libs/cdk/render-strategies/docs/strategy-provider.md
+++ b/apps/docs/docs/cdk/render-strategies/rx-strategy-provider.md
@@ -2,17 +2,17 @@
`RxStrategyProvider` is the best way to consume full power of concurrent strategies to schedule any kind of work.
-> Want to play with it? Here's [demo link](https://stackblitz.com/edit/angular-ivy-1vfpoe)
+> Want to play with it? Here's [demo link](https://stackblitz.com/edit/angular-ivy-1vfpoe)
## Motivation
-Chromium based browsers considers all tasks that taking more than 50ms as long tasks. If task runs more than 50ms, users will start noticing lags. Optimally all user interactions should happen at 30 fps framerate with 32ms budget per browser task. In ideal world it should be 60 fps and 16ms budget.
+Chromium based browsers considers all tasks that taking more than 50ms as long tasks. If task runs more than 50ms, users will start noticing lags. Optimally all user interactions should happen at 30 fps framerate with 32ms budget per browser task. In ideal world it should be 60 fps and 16ms budget.
> 💡 In reality browser has a reserved overhead of 4ms, try to stick to 28ms of work for 30 fps and 12ms for 60 fps.
## Scheduling mechanisms in browser
-There are multiple ways to schedule task in the browser.
+There are multiple ways to schedule task in the browser.
- `setTimeout`
- `requestAnimationFrame`
@@ -26,9 +26,9 @@ None of them has a full notion about what happens in the browser and can be unre
> 💡 Under the hood all our concurrent strategies are based on MessageChannel technology.
-To address the problem of long tasks and help browser split the work @rx-angular/cdk provides concurrent strategies. This strategies will help browser to chunk the work into non-blocking tasks whenever it's possible.
+To address the problem of long tasks and help browser split the work @rx-angular/cdk provides concurrent strategies. This strategies will help browser to chunk the work into non-blocking tasks whenever it's possible.
-You can read detailed information about concurrent strategies [here](https://github.com/rx-angular/rx-angular/blob/main/libs/cdk/render-strategies/docs/concurrent-strategies.md).
+You can read detailed information about concurrent strategies [here](strategies/concurrent-strategies.md).
## RxStrategyProvider APIs
@@ -37,7 +37,7 @@ Full signature of the service available below, but we will focus only on methods
```typescript
@Injectable({ providedIn: 'root' })
export class RxStrategyProvider {
-
+
get config(): Required>;
get strategies(): RxStrategies;
@@ -78,6 +78,7 @@ export class RxStrategyProvider {
This method returns current `RxAngularConfig` used in the service.
Config includes:
+
- strategy that currently in use - `primaryStrategy`
- array of custom user defined strategies - `customStrategies`
- setting that is responsible for running in our outside of the zone.js - `patchZone`
@@ -85,7 +86,7 @@ Config includes:
#### Usage example
```typescript
-const defaultConfig = this.strategyProvider.config;
+const defaultConfig = this.strategyProvider.config;
```
### `get strategies()`
@@ -119,7 +120,7 @@ const primaryStrategy = this.strategyProvider.primaryStrategy;
```
```html
-
+
```
### `strategies$`
@@ -158,7 +159,7 @@ const strategyNames$ = this.strategyProvider.strategyNames$;
### `schedule` & `scheduleWith`
-These methods allows users to schedule any kind of work.
+These methods allows users to schedule any kind of work.
- `schedule` returns an observable (don't forget to subscribe!)
- `scheduleWith` returns a `MonoTypeOperatorFunction` so you can use this method inside rxjs `pipe`
@@ -176,16 +177,19 @@ Options are configuration object that you can use to setup the scheduling behavi
#### Usage examples
```typescript
-this.strategyProvider.schedule(() =>
- myWork(),
- {strategy: 'idle', patchZone: false, scope: this}
-).subscribe();
-
-myObservable$.pipe(
- this.strategyProvider.scheduleWith(
- () => myWork(),
- {strategy: 'idle', patchZone: false, scope: this})
-).subscribe();
+this.strategyProvider
+ .schedule(() => myWork(), { strategy: 'idle', patchZone: false, scope: this })
+ .subscribe();
+
+myObservable$
+ .pipe(
+ this.strategyProvider.scheduleWith(() => myWork(), {
+ strategy: 'idle',
+ patchZone: false,
+ scope: this,
+ })
+ )
+ .subscribe();
```
### `scheduleCD` method
@@ -198,10 +202,11 @@ Imperative method that you can use to schedule change detection cycle. You must
#### Usage example
```typescript
-this.strategyProvider.scheduleCd(this.changeDetectorRef, {afterCD: myWork()});
+this.strategyProvider.scheduleCd(this.changeDetectorRef, { afterCD: myWork() });
```
## Links
+
- [Demo](https://stackblitz.com/edit/angular-ivy-1vfpoe)
-- [Detailed information about strategies](https://github.com/rx-angular/rx-angular/tree/master/libs/cdk/render-strategies)
+- [Detailed information about strategies](render-strategies.mdx)
- [MessageChannel documentation](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel)
diff --git a/libs/cdk/render-strategies/docs/basic-strategies.md b/apps/docs/docs/cdk/render-strategies/strategies/basic-strategies.md
similarity index 86%
rename from libs/cdk/render-strategies/docs/basic-strategies.md
rename to apps/docs/docs/cdk/render-strategies/strategies/basic-strategies.md
index 0111bd27a8..3d14ed5db6 100644
--- a/libs/cdk/render-strategies/docs/basic-strategies.md
+++ b/apps/docs/docs/cdk/render-strategies/strategies/basic-strategies.md
@@ -1,4 +1,4 @@
-# Basic Strategies
+# Basic strategies
## Concepts
@@ -8,6 +8,7 @@ To apply changes to a component template we need to re-evaluate the template. In
This process will execute whenever a component's template is re-evaluated through `async`, `push`, `ChangedDetectorRef.detectChanges` or a structural directive template is re-evaluated through `EmbeddedView.detectChanges`.
It can be pretty time consuming and directly depends on the following factors:
+
- HTML size (only for init and destroy and bundle-size)
- JS size (only for init and destroy and bundle-size)
- number of event bindings (only for init and destroy)
@@ -20,27 +21,29 @@ Some of the problems related to work of Angular are:
**Out of bound change detection:**
If we perform this re-evaluation without any visual change for the user (over-rendering) we introduce noticeable performance degradations.
-The out of bound change detection can be caused through:
- - Zone pollution
- - Missing ChangeDetectionStrategy.OnPush
- - Component template projection
- - Pull-based rendering processes
-
+The out of bound change detection can be caused through:
+
+- Zone pollution
+- Missing ChangeDetectionStrategy.OnPush
+- Component template projection
+- Pull-based rendering processes
+
**Out of bound template evaluation:**
-If we perform a re-evaluation of a single property in the template any other expression/binding also gets re-evaluated.
+If we perform a re-evaluation of a single property in the template any other expression/binding also gets re-evaluated.
Again over-rendering introduces noticeable performance degradations.
The out of bound template evaluation can be caused through:
- - Pull-based rendering processes
- - any reactive change through `async`
- - any call to `cdRef.detectChanges`
+- Pull-based rendering processes
+- any reactive change through `async`
+- any call to `cdRef.detectChanges`
**Work performed for out of viewport content:**
If we perform a re-evaluation or even re-rendering of the DOM of elements outside of the viewport we perform useless work for the user.
This will pollute the main thread and reduced time for more important content to get rendered.
The re-evaluation or browser re-rendering can be caused by:
+
- Bad style changes
- Big LCP (Largest Contentful Paint) elements
- Large amount of content
@@ -50,7 +53,7 @@ The re-evaluation or browser re-rendering can be caused by:

The change detection system that is currently implemented in Angular is pull-based, but way more important, as a side effect it also runs CD globally.
-It performs a re-rendering where at optimum every single component on the path from the root to the actual UI update needs to get re-evaluated.
+It performs a re-rendering where at optimum every single component on the path from the root to the actual UI update needs to get re-evaluated.
A lot of performed work is useless.
Technically the methods to run change detection are `markForCheck` / `markViewDirty`, `ɵmarkDirty` and `tick`.
@@ -61,32 +64,30 @@ Technically the methods we can use for it are `detectChanges` or `ɵdetectChange

-
### Pull vs push based
-

Consuming value changes can be done by **constantly** watching the source for changes and **pull** them,
- or subscribe to the changes like a DOM event binding **once** and get the changes **pushed**.
+or subscribe to the changes like a DOM event binding **once** and get the changes **pushed**.
In a simple setup the pull might be a quick solution and you just `.get()` the value, but a push based architecture always scales better.
Compare it with HTTP calls vs WebSockets.
-If we apply this concepts to our change detection mechanics we can directly apply changes where they are needd and skip nearly all the unnessecary work.
+If we apply this concepts to our change detection mechanics we can directly apply changes where they are needd and skip nearly all the unnessecary work.
In combination with Observables, and EmbeddedViews change detection can be speed up dramatically by this architecture.
-
+

### Strategies
-| Name | Priority | Render Method | Scheduling | Render Deadline |
-|-------------------------| -------- | ----------------- | ----------------------- | --------------- |
-| `"native"` | ❌ | ⮁ `markForCheck` | `requestAnimationFrame` | N/A |
+| Name | Priority | Render Method | Scheduling | Render Deadline |
+| ------------------------- | -------- | ----------------- | ----------------------- | --------------- |
+| `"native"` | ❌ | ⮁ `markForCheck` | `requestAnimationFrame` | N/A |
| `"global"` - _deprecated_ | ❌ | ⮁ `ɵmarkDirty` | `requestAnimationFrame` | N/A |
-| `"local"` | ❌ | 🠗 `detectChanges` | `requestAnimationFrame` | N/A |
-| `"noop"` | ❌ | - `noop` | `requestAnimationFrame` | N/A |
+| `"local"` | ❌ | 🠗 `detectChanges` | `requestAnimationFrame` | N/A |
+| `"noop"` | ❌ | - `noop` | `requestAnimationFrame` | N/A |
#### Native
@@ -103,7 +104,7 @@ as the internally called function [`markViewDirty`](https://github.com/angular/a
#### Global Strategy
-> **deprecated**
+> **deprecated**
> angular [drops support](https://github.com/angular/angular/pull/46806) for `ɵmarkDirty`
This strategy leverages Angular's internal [`ɵmarkDirty`](https://github.com/angular/angular/blob/930eeaf177a4c277f437f42314605ff8dc56fc82/packages/core/src/render3/instructions/change_detection.ts#L36) render method.
@@ -155,41 +156,32 @@ The no-operation strategy does nothing. It can be a valuable tool for performanc
| ------ | ------------- | ------------- | ---------- | ---------- |
| `noop` | ✔ | - `noop` | ❌ | ❌ |
-
## Usage
### Component / Service
```ts
-import {RxStrategyProvider} from '@rx-angular/cdk/render-strategies';
+import { RxStrategyProvider } from '@rx-angular/cdk/render-strategies';
@Component()
class Component {
-
constructor(private strategyProvider: RxStrategyProvider) {
- strategyProvider.schedule(() => {}, {strategyName: 'local'})
+ strategyProvider.schedule(() => {}, { strategyName: 'local' });
}
-
}
```
### Template
```ts
-import {LetModule} from '@rx-angular/template/let';
-import {ForModule} from '@rx-angular/template/for';
-import {PushModule} from '@rx-angular/template/push';
+import { LetModule } from '@rx-angular/template/let';
+import { ForModule } from '@rx-angular/template/for';
+import { PushModule } from '@rx-angular/template/push';
@Module({
- imports: [
- LetModule,
- ForModule,
- PushModule
- ]
+ imports: [LetModule, ForModule, PushModule],
})
-class Module {
-
-}
+class Module {}
```
```html
diff --git a/libs/cdk/render-strategies/docs/concurrent-strategies.md b/apps/docs/docs/cdk/render-strategies/strategies/concurrent-strategies.md
similarity index 90%
rename from libs/cdk/render-strategies/docs/concurrent-strategies.md
rename to apps/docs/docs/cdk/render-strategies/strategies/concurrent-strategies.md
index 10e818dcbf..297fdacc44 100644
--- a/libs/cdk/render-strategies/docs/concurrent-strategies.md
+++ b/apps/docs/docs/cdk/render-strategies/strategies/concurrent-strategies.md
@@ -1,17 +1,19 @@
-# Concurrent Strategies
+# Concurrent strategies
Based on the [RAIL model](https://web.dev/rail/), e.g. if your app provides animated user feedback within more than 16ms (less than 60 frames per second), it feels laggy to the user and leads to bad UX.
From the UX perspective that means users should not experience blocking periods more than 16 ms.
## Concepts
+
There are 5 core concepts of the concurrent strategies:
+
- Frame budget / Frame drop
- Scheduling
- Priority
- Chunking
- Concurrent Scheduling
-### Frame budget / Frame Drop
+### Frame budget / Frame drop
The Browser has only one UI thread (main thread), meaning things happen one after another.
@@ -48,11 +50,12 @@ When it comes to scripting work we can do 2 things to avoid that:
- reduce scripting work and let the user interact earlier
- chunk up work and use scheduling API's to distribute the work overtime and let the user interact in between.
-It is often the case that the work just can't get reduced so we have to schedule.
+It is often the case that the work just can't get reduced so we have to schedule.

Some of the possible APIs are:
+
- queueMicrotask
- setTimeout
- postMessage
@@ -70,7 +73,7 @@ A simple way to schedule work is using `setTimeout`.
```typescript
function work(): viod {
- concole.log('work done!');
+ concole.log('work done!');
}
const asyncId = setTimeout(work);
@@ -84,11 +87,10 @@ This is important for cancellation and cleanup logic.
```typescript
clearTimeout(asyncId);
-```
+```
If we pass the asyncId as parameter to the `clearTimeout` function we can cancel the scheduling and `work` will never get executed.
-
### Priority

@@ -102,7 +104,7 @@ Input handlers (tap, click etc.) often need to schedule a combination of differe
To get the best user experience we should prioritize this tasks.
-There are couple of scheduling APIs mentioned under scheduling.
+There are couple of scheduling APIs mentioned under scheduling.
They all help to prioritize the work and define the moment of execution differently.

@@ -127,14 +129,15 @@ This scenario gets to a problem depending on:
- the number of Angular elements
- the amount of work done in the elements
-### Concurrent Scheduling
+### Concurrent scheduling

Concurrent scheduling is a marketing term and simply means that there is a mechanism in place that knows how much time is spent in the current task.
-This number is called frame budget and measured in milliseconds. As a result of this technique we're getting prioritized user-centric scheduling behaviours.
+This number is called frame budget and measured in milliseconds. As a result of this technique we're getting prioritized user-centric scheduling behaviours.
This enables:
+
- scheduling
- cancellation
- fine grained prioritization
@@ -142,14 +145,14 @@ This enables:
- render deadlines
One of the first things to understand is the term "frame budget".
-It means we have a maximum time (which is globally defined) a task can take before yielding to the main thread. e.g. 60frames/1000ms=16.6666ms animations or 50ms long task.
+It means we have a maximum time (which is globally defined) a task can take before yielding to the main thread. e.g. 60frames/1000ms=16.6666ms animations or 50ms long task.
Scheduling with notion of frame budget enables us to split work into individual browser tasks as soon as we exceed the budget.
-We then yield to the main thread and are interactive again until the next batch of tasks will get processed.
+We then yield to the main thread and are interactive again until the next batch of tasks will get processed.

-The special thing about the set of concurrent strategies is they have a render deadline.
+The special thing about the set of concurrent strategies is they have a render deadline.
It means if the scheduled tasks in the global queue of work is not exhausted after a certain time window, we stop the chunking process.
Instead all remaining work will get executed as fast as possible. This means in one synchronous block (that potentially can causes a frame drop).
@@ -196,10 +199,10 @@ Tooltips should be displayed immediately on mouse over. Any delay will be very n
@Component({
selector: 'item-image',
template: `
-
`,
})
@@ -209,21 +212,25 @@ export class ItemsListComponent {
constructor(private strategyProvider: RxStrategyProvider) {}
showTooltip() {
- this.strategyProvider.schedule(
- () => {
- // create tooltip
- },
- { strategy: 'immediate' }
- ).subscribe();
+ this.strategyProvider
+ .schedule(
+ () => {
+ // create tooltip
+ },
+ { strategy: 'immediate' }
+ )
+ .subscribe();
}
hideTooltip() {
- this.strategyProvider.schedule(
- () => {
- // destroy tooltip
- },
- { strategy: 'immediate' }
- ).subscribe();
+ this.strategyProvider
+ .schedule(
+ () => {
+ // destroy tooltip
+ },
+ { strategy: 'immediate' }
+ )
+ .subscribe();
}
}
```
@@ -231,7 +238,7 @@ export class ItemsListComponent {
> **⚠ Notice:**
> Be aware to avoid scheduling large or non-urgent work with immediate priority as it blocks rendering
-### User Blocking
+### User blocking

@@ -279,17 +286,19 @@ export class DropdownComponent {
}
hideDropdown() {
- this.strategyProvider.schedule(
- () => {
- // destroy dropdown
- },
- { strategy: 'userBlocking' }
- ).subscribe();
+ this.strategyProvider
+ .schedule(
+ () => {
+ // destroy dropdown
+ },
+ { strategy: 'userBlocking' }
+ )
+ .subscribe();
}
}
```
-> **⚠ Notice:**
+> **⚠ Notice:**
> Be aware to avoid scheduling large or non-urgent work with `userBlocking` priority as it blocks rendering after 250ms
### Normal
@@ -310,7 +319,7 @@ Heavy work visible to the user. For example, since it has a higher timeout, it i

-For `normal` strategy a perfect example will be rendering of the items list.
+For `normal` strategy a perfect example will be rendering of the items list.
It is often the case that rendering of big lists blocks user interactions. In combination with `rxFor` directive such operations become truly unblocking.
@@ -373,22 +382,26 @@ export class ItemsListComponent {
) {}
openCreateItemPopup() {
- this.strategyProvider.schedule(() => {
- // logic to lazy load popup component
- }, {strategy: 'low'}).subscribe();
+ this.strategyProvider
+ .schedule(
+ () => {
+ // logic to lazy load popup component
+ },
+ { strategy: 'low' }
+ )
+ .subscribe();
}
-
}
```
-> **⚠ Notice:**
+> **⚠ Notice:**
> This priority fits well for things that should happen but has lower priority. For any non-urgent background process `idle` is the best fit.
### Idle

-Urgent work that should happen in the background and is not initiated but visible by the user. This occurs right after current task and has the lowest priority.
+Urgent work that should happen in the background and is not initiated but visible by the user. This occurs right after current task and has the lowest priority.
| Render Method | Scheduling | Render Deadline |
| ----------------- | ------------- | --------------- |
@@ -425,22 +438,28 @@ export class ItemsListComponent {
private strategyProvider: RxStrategyProvider,
private webSocket: WebSocketService
) {
- this.items$.pipe(
- this.strategyProvider.scheduleWith(
- items => this.webSocket.syncItems(items),
- {strategy: 'idle'}
- )
- ).subscribe();
+ this.items$
+ .pipe(
+ this.strategyProvider.scheduleWith(
+ (items) => this.webSocket.syncItems(items),
+ { strategy: 'idle' }
+ )
+ )
+ .subscribe();
}
openCreateItemPopup() {
- this.strategyProvider.schedule(() => {
- // logic to lazy load popup component
- }, {strategy: 'low'}).subscribe();
+ this.strategyProvider
+ .schedule(
+ () => {
+ // logic to lazy load popup component
+ },
+ { strategy: 'low' }
+ )
+ .subscribe();
}
-
}
```
-> **⚠ Notice:**
+> **⚠ Notice:**
> This priority fits well for low priority background processes that are not affecting user interactions.
diff --git a/libs/cdk/render-strategies/docs/strategies.md b/apps/docs/docs/cdk/render-strategies/strategies/strategies.mdx
similarity index 91%
rename from libs/cdk/render-strategies/docs/strategies.md
rename to apps/docs/docs/cdk/render-strategies/strategies/strategies.mdx
index fd9ff95123..718530bf18 100644
--- a/libs/cdk/render-strategies/docs/strategies.md
+++ b/apps/docs/docs/cdk/render-strategies/strategies/strategies.mdx
@@ -1,3 +1,9 @@
+---
+sidebar_label: 'Strategies'
+sidebar_position: 1
+hide_title: true
+---
+
# Strategies
Before we go into detail with the provided strategies, let's understand angulars vanilla behaviour first.
@@ -19,13 +25,15 @@ In many cases, this leads to heavy refactorings to get the performance flaw out
Strategies give us a way to control how Angular's rendering is executed and which render method is used.
-**Strategy Sets:**
-- [Basic Strategies](https://github.com/rx-angular/rx-angular/blob/master/libs/cdk/render-strategies/docs/basic-strategies.md)
-- [Concurrent Strategies](https://github.com/rx-angular/rx-angular/blob/master/libs/cdk/render-strategies/docs/concurrent-strategies.md)
+**Strategy sets:**
+
+- [Basic strategies](basic-strategies.md)
+- [Concurrent strategies](concurrent-strategies.md)
## Usage
### Configure existing features
+
```typescript
@Component({
selector: 'immediate',
@@ -58,8 +66,7 @@ export class RenderCallbackComponent {
}
```
-
-### Custom Strategies
+### Custom strategies
```typescript
export type RxRenderWork = (
diff --git a/apps/docs/docs/cdk/template-management/template-management.mdx b/apps/docs/docs/cdk/template-management/template-management.mdx
new file mode 100644
index 0000000000..162133509f
--- /dev/null
+++ b/apps/docs/docs/cdk/template-management/template-management.mdx
@@ -0,0 +1,17 @@
+---
+sidebar_label: 'Template management'
+sidebar_position: 1
+title: 'Template management'
+hide_title: true
+---
+
+import Readme, {
+ toc as readmeToc,
+} from '@site/../../libs/cdk/template/README.md';
+
+
+
+
+
+
+export const toc = [...readmeToc];
diff --git a/apps/docs/docs/cdk/transformations/transformations.mdx b/apps/docs/docs/cdk/transformations/transformations.mdx
new file mode 100644
index 0000000000..ec3c1a265e
--- /dev/null
+++ b/apps/docs/docs/cdk/transformations/transformations.mdx
@@ -0,0 +1,14 @@
+---
+sidebar_label: 'Transformations'
+sidebar_position: 1
+title: 'Transformations'
+hide_title: true
+---
+
+import Readme, {
+ toc as readmeToc,
+} from '@site/../../libs/cdk/transformations/README.md';
+
+
+
+export const toc = [...readmeToc];
diff --git a/libs/cdk/zone-configurations/docs/zone-flags.md b/apps/docs/docs/cdk/zone-configurations/_docs.md
similarity index 97%
rename from libs/cdk/zone-configurations/docs/zone-flags.md
rename to apps/docs/docs/cdk/zone-configurations/_docs.md
index 9ddf1f0ada..7e6935407a 100644
--- a/libs/cdk/zone-configurations/docs/zone-flags.md
+++ b/apps/docs/docs/cdk/zone-configurations/_docs.md
@@ -1,9 +1,9 @@
-# Resources
+## Resources
-**Example applications:**
+**Example applications:**
A demo application is available on [GitHub](https://github.com/BioPhoton/rx-angular-cdk-zone-configuration).
-# Motivation
+## Motivation
**How zone.js works by default**
@@ -19,7 +19,7 @@ Zone can be [disabled fully](https://angular.io/guide/zone#disabling-zone), but
To set up zone flags we can use the direct `window` properties as documented in the [official docs](https://angular.io/guide/zone#setting-up-zonejs). The best documentation can be found in the source [zone-flags](https://github.com/angular/angular/blob/master/packages/zone.js/lib/zone.configurations.api.ts).
-# Available Approaches
+## Available approaches
In the following, we will discuss the vanilla JavaScript approach without any abstraction or DX to understand the fundamentals, as well as serve an approach for a setup with RxAngulars `@rx-angular/cdk/zone-config` helper.
@@ -35,7 +35,7 @@ RxAngular should be our go-to approach as it serves as a more convenient way to
- ✅ Assertion if zone-flags are not correctly used
- ✅ Convenience methods
-# Impact
+## Impact
Zone flags can land an incredible performance improvement, but also can cause a lot of problems related to change detection if it was not in a proper state.
@@ -49,7 +49,7 @@ A second charts is with timer, scroll and xhr events turned off.

-# Risks & What can break
+## Risks & what can break
Applications that rely on global state management are in a good position because they rely on push-based change propagation already. Therefore there is no reason for the dirty marking from the root.
With some specific local state management, it is manageable to fix possible bugs quite easily for most of the flags.
@@ -59,7 +59,7 @@ Another risk with zone flags is it will also affect **third-party libs** that re
In general, if you turn off some flags, nothing may break cause others are still present. And only when 70% of flags would be turned off, you'd see some major regression in UI.
That's why important not only to disable the flag and check that app is ok but also to go over the codebase checking that change detection would be triggered correctly without zone.
-# Migration and Precondition
+## Migration and precondition
1. Make sure `ChangeDetectionStrategy.OnPush` is set for the app's root component and the app is working properly. This is needed to ensure an immutable change propagation.
2. To prioritize the flags we need to compare we can ask the following questions:
@@ -81,7 +81,7 @@ That's why important not only to disable the flag and check that app is ok but a
7. Take flame chart measurements or use breakpoints to ensure they are working
8. Test your application and see everything works fine
-# Alternatives
+## Alternatives
An even **less granular way** to disable zone functionality is turning it off completely.
diff --git a/libs/cdk/zone-configurations/docs/how-to-debug-zone-flags.md b/apps/docs/docs/cdk/zone-configurations/how-to-debug-zone-flags.md
similarity index 95%
rename from libs/cdk/zone-configurations/docs/how-to-debug-zone-flags.md
rename to apps/docs/docs/cdk/zone-configurations/how-to-debug-zone-flags.md
index fe314553f0..107844211d 100644
--- a/libs/cdk/zone-configurations/docs/how-to-debug-zone-flags.md
+++ b/apps/docs/docs/cdk/zone-configurations/how-to-debug-zone-flags.md
@@ -76,7 +76,7 @@ The check if the flag is set should now return true:
console.log(window.__Zone_disable_timers); // logs 'false' if the flag is active
```
-
+
Now, `globalThis` should have no original/unpatched version present under the zone symbol.
@@ -86,7 +86,7 @@ console.log(window.__zone_symbol__setTimeout);
console.log(window.__zone_symbol__clearTimeout);
```
-
+
> **💡 Pro Tipps:**
>
diff --git a/libs/cdk/zone-configurations/docs/how-to-setup-zone-flags.md b/apps/docs/docs/cdk/zone-configurations/how-to-setup-zone-flags.md
similarity index 99%
rename from libs/cdk/zone-configurations/docs/how-to-setup-zone-flags.md
rename to apps/docs/docs/cdk/zone-configurations/how-to-setup-zone-flags.md
index 4990854ec2..48b62ac85b 100644
--- a/libs/cdk/zone-configurations/docs/how-to-setup-zone-flags.md
+++ b/apps/docs/docs/cdk/zone-configurations/how-to-setup-zone-flags.md
@@ -1,7 +1,5 @@
# How to set up zone flags
----
-
## Resources
**Example application:**
@@ -9,7 +7,7 @@ A demo application is available on [GitHub](https://github.com/BioPhoton/rx-angu
## Concepts
-### The Patching Mechanism
+### The patching mechanism
API patching or monkey-patching means we take an existing API and override its behavior globally or in specific places.
@@ -37,7 +35,7 @@ EventTarget.prototype.addEventListener = patchedAddEventListener;
Here we patch the global `addEventListener` API.
Every fired event in the Browser will now pass our patch from above.
-### The Flagging Mechanism
+### The flagging mechanism
When `zone.js` is first time initialised on the page, it takes values of flags already located in `window` object.
So it's important to set them **before `zone.js` is init**. So we need to inject `zone-flags.js` code **above** the zone code.
diff --git a/apps/docs/docs/cdk/zone-configurations/zone-configurations.mdx b/apps/docs/docs/cdk/zone-configurations/zone-configurations.mdx
new file mode 100644
index 0000000000..a93458b054
--- /dev/null
+++ b/apps/docs/docs/cdk/zone-configurations/zone-configurations.mdx
@@ -0,0 +1,20 @@
+---
+sidebar_label: 'Zone configurations'
+sidebar_position: 1
+title: 'Zone configurations'
+hide_title: true
+---
+
+import Readme, {
+ toc as readmeToc,
+} from '@site/../../libs/cdk/zone-configurations/README.md';
+import Docs, { toc as docsToc } from './_docs.md';
+
+
+
+
+
+
+
+
+export const toc = [...readmeToc, ...docsToc];
diff --git a/libs/cdk/zone-less/docs/README.md b/apps/docs/docs/cdk/zone-less/_docs.md
similarity index 82%
rename from libs/cdk/zone-less/docs/README.md
rename to apps/docs/docs/cdk/zone-less/_docs.md
index 4ce52abfcc..434d743220 100644
--- a/libs/cdk/zone-less/docs/README.md
+++ b/apps/docs/docs/cdk/zone-less/_docs.md
@@ -1,21 +1,21 @@
-# Resources
+## Resources
-**Example applications:**
+**Example applications:**
A demo application is available on [GitHub](https://github.com/BioPhoton/rx-angular-cdk-zone-less).
-# Motivation
+## Motivation
-By default, Angular or better say zone.js patches most of the asynchronouse API's of the Browser.
-This adds additional overhead on those API's and even more important, this leads to un-nessecary renderings of the Angular component tree, also known as overredering.
+By default, Angular or better say zone.js patches most of the asynchronouse API's of the Browser.
+This adds additional overhead on those API's and even more important, this leads to un-nessecary renderings of the Angular component tree, also known as overredering.
Until now developers where only able to either disable zone.js completely or wrapping another logic around the patched APIs to avoid change detection calls.
This of course requires to inject another service and also makes your code more cluttery and slow.
The zone-less package helps out here.
-It provides a general method to access the unpatched version of an API and also ships a set of commonly used APIs of the Browser as well as RxJS.
+It provides a general method to access the unpatched version of an API and also ships a set of commonly used APIs of the Browser as well as RxJS.
All those APIs are fully independent of zone.js and NgZone (which is normally used to run things outside Angular).
-# The Benefits
+## The benefits
- ✅ Finegrained ways to unpatch APIs
- ✅ Fastest option possible to run code outside of Angulars zone mechanism
@@ -23,19 +23,19 @@ All those APIs are fully independent of zone.js and NgZone (which is normally us
- ✅ Drop-in replacement for RxJS functions
- ✅ No need for `runOutsideAngular` and `NgZone` injection
-# RxAngular CDK/Zone-Less
+## RxAngular CDK/Zone-less
The way how zone.js works is, it patches all relevant async APIs of the Browser. This happens early on as zone.js is treated as polyfill.

All original logic of the patched API's is stored under a symbol in `window`. You can check that by logging for example the following value: `console.log(window.__zone_symbol__setTimeout)`.
-This will print the original unpatched API to the Brwosers console.
+This will print the original unpatched API to the Brwosers console.
-Internally the symbols and in turn the unpatched API's is what the zone-less package is using.
+Internally the symbols and in turn the unpatched API's is what the zone-less package is using.
The essential method used to get hold of the unpatched APIs is called `getZoneUnPatchedApi`. It takes a target i.e. `window` and a name of the method we want to retreive the unpatched version of.
-## Setup
+### Setup
The zone-less API's can be used directly from the `cdk` package.
To do so, install the `cdk` package and, if needed, the packages depending on it:
@@ -48,20 +48,18 @@ npm i @rx-angular/cdk
yarn add @rx-angular/cdk
```
-## Usage
+### Usage
-The utils folder contains the most essential functions used to unpatch APIs.
-Normally if developers want to avoid change detection through zone the have to inject `NgZone` and run the code that should not trigger change detection in the `runOutsideAngular` method.
+The utils folder contains the most essential functions used to unpatch APIs.
+Normally if developers want to avoid change detection through zone the have to inject `NgZone` and run the code that should not trigger change detection in the `runOutsideAngular` method.
```typescript
export class AnyComponent {
-
constructor(private ngZone: NgZone) {
- this.ngZone.runOutsideAngular(() => {
+ this.ngZone.runOutsideAngular(() => {
// code here
});
}
-
}
```
@@ -71,27 +69,24 @@ This introduces some lines of code and also takes time to retreive the service f
- getZoneUnPatchedApi
-The `getZoneUnPatchedApi` function is used in all other functions of the zone-less package to access the Browsers unpatched API's.
-
+The `getZoneUnPatchedApi` function is used in all other functions of the zone-less package to access the Browsers unpatched API's.
```typescript
@Component({
// ...
})
export class AppComponent {
-
doStuff() {
- // unpatched method of the window object
- getZoneUnPatchedApi('setTimeout')(
- () => console.log('tada!'),
- 300);
- };
-
+ // unpatched method of the window object
+ getZoneUnPatchedApi('setTimeout')(() => console.log('tada!'), 300);
+ }
+
doOtherStuff() {
// unpatched method of an HTML element
- getZoneUnPatchedApi(elem, 'addEventListener')('click', () => console.log('tada!') );
- };
-
+ getZoneUnPatchedApi(elem, 'addEventListener')('click', () =>
+ console.log('tada!')
+ );
+ }
}
```
@@ -113,14 +108,14 @@ import {setTimeout} from @rx-angular/cdk/zone-less
// ...
})
export class AppComponent {
-
+
doStuff() {
// unpatched method of the window object
setTimeout(
- () => console.log('tada!'),
+ () => console.log('tada!'),
300);
};
-
+
}
```
@@ -139,7 +134,7 @@ scheduler
- queue
- animationFrame
-As RxJS internally uses Browser API's it is pretty impossible to get rid of the zone involvment.
+As RxJS internally uses Browser API's it is pretty impossible to get rid of the zone involvment.
For this very reason we shipped the RxJS operators, schedulers and functions that would trigger zone as unpatched version.
```typescript
@@ -149,22 +144,21 @@ import {interval} from @rx-angular/cdk/zone-less
// ...
})
export class AppComponent {
-
+
doStuff() {
// unpatched method of RxJS lib
interval(300).subscribe();
};
-
+
}
```
-
-# Available Approaches
+## Available approaches
- `ngZone#runOutsideZone`
- `zone-configuration`
-## `ngZone#runOutsideAngular`
+### `ngZone#runOutsideAngular`
It is possible to inject an instance of NgZone into components and services etc to tell Angular to run a specific peice of coe outside of Angular.
@@ -173,27 +167,22 @@ It is possible to inject an instance of NgZone into components and services etc
// ...
})
export class AppComponent {
-
- constructor(private ngZone: NgZone) {
- }
-
+ constructor(private ngZone: NgZone) {}
+
doStuff() {
-
this.ngZone.runOutsideAngular(() => {
setTimeout(() => {
console.log('tada!');
- }, 300)
+ }, 300);
});
-
}
-
}
```
The downside here is we need to inject `NgZone` and rely on dependency injection wich is not only more code but also slow.
-## Zone Configuration
+### Zone Configuration
-Zone configuration is a less granular way to disable zone. It helps to cinfigure zone in a way where it don't patches specific API's at all.
+Zone configuration is a less granular way to disable zone. It helps to configure zone in a way where it don't patches specific APIs at all.
-You can read in detail about it in the docs of [`@rx-angular/cdk/zone-configuration`](https://github.com/rx-angular/rx-angular/blob/main/libs/cdk/zone-configurations/docs/zone-flags.md).
+You can read in detail about it in the docs of [`@rx-angular/cdk/zone-configuration`](../zone-configurations/zone-configurations.mdx).
diff --git a/apps/docs/docs/cdk/zone-less/zone-less.mdx b/apps/docs/docs/cdk/zone-less/zone-less.mdx
new file mode 100644
index 0000000000..2955956de5
--- /dev/null
+++ b/apps/docs/docs/cdk/zone-less/zone-less.mdx
@@ -0,0 +1,20 @@
+---
+sidebar_label: 'Zone-less'
+sidebar_position: 1
+title: 'Zone-less'
+hide_title: true
+---
+
+import Readme, {
+ toc as readmeToc,
+} from '@site/../../libs/cdk/zone-less/README.md';
+import Docs, { toc as docsToc } from './_docs.md';
+
+
+
+
+
+
+
+
+export const toc = [...readmeToc, ...docsToc];
diff --git a/apps/docs/docs/contributing.mdx b/apps/docs/docs/contributing.mdx
new file mode 100644
index 0000000000..fec1659c8b
--- /dev/null
+++ b/apps/docs/docs/contributing.mdx
@@ -0,0 +1,16 @@
+---
+sidebar_label: 'Contributing'
+title: 'Contributing'
+hide_title: true
+---
+
+import Contributing, {
+ toc as contributingToc,
+} from '@site/../../CONTRIBUTING.md';
+
+
+
+
+
+
+export const toc = [...contributingToc];
diff --git a/apps/docs/docs/eslint-plugin/_category_.json b/apps/docs/docs/eslint-plugin/_category_.json
new file mode 100644
index 0000000000..098a426f26
--- /dev/null
+++ b/apps/docs/docs/eslint-plugin/_category_.json
@@ -0,0 +1,3 @@
+{
+ "label": "@rx-angular/eslint-plugin"
+}
diff --git a/apps/docs/docs/eslint-plugin/eslint-plugin.mdx b/apps/docs/docs/eslint-plugin/eslint-plugin.mdx
new file mode 100644
index 0000000000..2d9579bbee
--- /dev/null
+++ b/apps/docs/docs/eslint-plugin/eslint-plugin.mdx
@@ -0,0 +1,17 @@
+---
+sidebar_label: '@rx-angular/eslint-plugin'
+sidebar_position: 1
+title: 'ESLint plugin'
+hide_title: true
+---
+
+import Readme, {
+ toc as readmeToc,
+} from '@site/../../libs/eslint-plugin/README.md';
+
+
+
+
+
+
+export const toc = [...readmeToc];
diff --git a/apps/docs/docs/eslint-plugin/rules/_category_.json b/apps/docs/docs/eslint-plugin/rules/_category_.json
new file mode 100644
index 0000000000..5ad72f43ce
--- /dev/null
+++ b/apps/docs/docs/eslint-plugin/rules/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "Rules",
+ "position": 1,
+ "link": {
+ "type": "generated-index",
+ "slug": "eslint-plugin/rules",
+ "title": "ESLint rules"
+ }
+}
diff --git a/libs/eslint-plugin/docs/rules/no-explicit-change-detection-apis.md b/apps/docs/docs/eslint-plugin/rules/no-explicit-change-detection-apis.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-explicit-change-detection-apis.md
rename to apps/docs/docs/eslint-plugin/rules/no-explicit-change-detection-apis.md
diff --git a/libs/eslint-plugin/docs/rules/no-rxstate-imperative-in-reactive.md b/apps/docs/docs/eslint-plugin/rules/no-rxstate-imperative-in-reactive.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-rxstate-imperative-in-reactive.md
rename to apps/docs/docs/eslint-plugin/rules/no-rxstate-imperative-in-reactive.md
diff --git a/libs/eslint-plugin/docs/rules/no-rxstate-subscriptions-outside-constructor.md b/apps/docs/docs/eslint-plugin/rules/no-rxstate-subscriptions-outside-constructor.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-rxstate-subscriptions-outside-constructor.md
rename to apps/docs/docs/eslint-plugin/rules/no-rxstate-subscriptions-outside-constructor.md
diff --git a/libs/eslint-plugin/docs/rules/no-zone-critical-browser-apis.md b/apps/docs/docs/eslint-plugin/rules/no-zone-critical-browser-apis.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-zone-critical-browser-apis.md
rename to apps/docs/docs/eslint-plugin/rules/no-zone-critical-browser-apis.md
diff --git a/libs/eslint-plugin/docs/rules/no-zone-critical-lodash-apis.md b/apps/docs/docs/eslint-plugin/rules/no-zone-critical-lodash-apis.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-zone-critical-lodash-apis.md
rename to apps/docs/docs/eslint-plugin/rules/no-zone-critical-lodash-apis.md
diff --git a/libs/eslint-plugin/docs/rules/no-zone-critical-rxjs-creation-apis.md b/apps/docs/docs/eslint-plugin/rules/no-zone-critical-rxjs-creation-apis.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-zone-critical-rxjs-creation-apis.md
rename to apps/docs/docs/eslint-plugin/rules/no-zone-critical-rxjs-creation-apis.md
diff --git a/libs/eslint-plugin/docs/rules/no-zone-critical-rxjs-operators.md b/apps/docs/docs/eslint-plugin/rules/no-zone-critical-rxjs-operators.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-zone-critical-rxjs-operators.md
rename to apps/docs/docs/eslint-plugin/rules/no-zone-critical-rxjs-operators.md
diff --git a/libs/eslint-plugin/docs/rules/no-zone-critical-rxjs-schedulers.md b/apps/docs/docs/eslint-plugin/rules/no-zone-critical-rxjs-schedulers.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-zone-critical-rxjs-schedulers.md
rename to apps/docs/docs/eslint-plugin/rules/no-zone-critical-rxjs-schedulers.md
diff --git a/libs/eslint-plugin/docs/rules/no-zone-run-apis.md b/apps/docs/docs/eslint-plugin/rules/no-zone-run-apis.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/no-zone-run-apis.md
rename to apps/docs/docs/eslint-plugin/rules/no-zone-run-apis.md
diff --git a/libs/eslint-plugin/docs/rules/prefer-no-layout-sensitive-apis.md b/apps/docs/docs/eslint-plugin/rules/prefer-no-layout-sensitive-apis.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/prefer-no-layout-sensitive-apis.md
rename to apps/docs/docs/eslint-plugin/rules/prefer-no-layout-sensitive-apis.md
diff --git a/libs/eslint-plugin/docs/rules/prefer-no-lodash-clone-deep.md b/apps/docs/docs/eslint-plugin/rules/prefer-no-lodash-clone-deep.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/prefer-no-lodash-clone-deep.md
rename to apps/docs/docs/eslint-plugin/rules/prefer-no-lodash-clone-deep.md
diff --git a/libs/eslint-plugin/docs/rules/prefer-no-lodash-is-equal.md b/apps/docs/docs/eslint-plugin/rules/prefer-no-lodash-is-equal.md
similarity index 100%
rename from libs/eslint-plugin/docs/rules/prefer-no-lodash-is-equal.md
rename to apps/docs/docs/eslint-plugin/rules/prefer-no-lodash-is-equal.md
diff --git a/apps/docs/docs/state/_category_.json b/apps/docs/docs/state/_category_.json
index 6b3aa07c72..979a643d40 100644
--- a/apps/docs/docs/state/_category_.json
+++ b/apps/docs/docs/state/_category_.json
@@ -1,8 +1,3 @@
{
- "label": "@rx-angular/state",
- "position": 2,
- "link": {
- "type": "doc",
- "id": "state/getting-started/overview"
- }
+ "label": "@rx-angular/state"
}
diff --git a/libs/state/actions/docs/Readme.md b/apps/docs/docs/state/actions/_docs.md
similarity index 72%
rename from libs/state/actions/docs/Readme.md
rename to apps/docs/docs/state/actions/_docs.md
index 66b66d20b2..a240149861 100644
--- a/libs/state/actions/docs/Readme.md
+++ b/apps/docs/docs/state/actions/_docs.md
@@ -1,11 +1,11 @@
-# Resources
+## Resources
**Example applications:**
A demo application is available on [GitHub](https://github.com/BioPhoton/rx-angular-state-actions).
-# Motivation
+## Motivation
-Signals, or a more commonly used name actions, are a common part of state management and reactive systems in general.
+Signals, or a more commonly used name actions, are a common part of state management and reactive systems in general.
Even if `@rx-angular/state` provides `set` method, sometimes you need to add behaviour to your user input or incoming events.
Subjects are normally used to implement this feature. This leads, especially in bigger applications, to a messy code that is bloated with Subjects.
@@ -15,25 +15,30 @@ Let's have a look at this piece of code:
```typescript
@Component({
template: `
- Search for: {{search$ | async}}
-