diff --git a/src/Umbraco.Web.UI.Client/src/stories/guides.stories.mdx b/src/Umbraco.Web.UI.Client/src/stories/guides.stories.mdx
index 59a1d654ba..11208a3328 100644
--- a/src/Umbraco.Web.UI.Client/src/stories/guides.stories.mdx
+++ b/src/Umbraco.Web.UI.Client/src/stories/guides.stories.mdx
@@ -10,12 +10,12 @@ In this document you will get a overview of the articles — Enabling you to get
# Temology
There is a few words that covers certain concepts, which is good to learn to easilier decode the purpose of code.
-- **Resource** A API enabling communication with a server. [Go to Context API Guide](/?path=/story/guides-resource--page)
-- **Store** A API representing data, generally coming from the server. Most stores would talk with one or more resources. [Go to Context API Guide](/?path=/story/guides-store--page)
+- **Resource** A API enabling communication with a server. [Go to Resource Guide](/?path=/story/guides-resource--page)
+- **Store** A API representing data, generally coming from the server. Most stores would talk with one or more resources. [Go to Store Guide](/?path=/story/guides-store--page)
-- **State** A reactive data store, holding some data, when data is changed all observers will be notified, if relevant.
+- **State** A reactive container holding data, when data is changed all its Observables will be notified.
- **Observable** An observable is the hook for others to subscribe to the data or part of the data of a State.
-- **Observe** Observe is the term of what we do when subscriping to a Observable.
+- **Observe** Observe is the term of what we do when subscriping to a Observable, We observe and observable.
- **Context-API** The name of the system used to serve APIs(instances/classes) that for a certain context in the DOM. An API that is served via the Context-API is called a Context [Go to Context API Guide](/?path=/story/guides-umbraco-element--page)
- **Context Provider** One that provides a class instance as a Context API.
diff --git a/src/Umbraco.Web.UI.Client/src/stories/store.stories.mdx b/src/Umbraco.Web.UI.Client/src/stories/store.stories.mdx
index c4d979bdc2..6c95d84da2 100644
--- a/src/Umbraco.Web.UI.Client/src/stories/store.stories.mdx
+++ b/src/Umbraco.Web.UI.Client/src/stories/store.stories.mdx
@@ -1,11 +1,11 @@
import { Meta } from '@storybook/addon-docs';
-
+
# Store
-A store is the link between a Resource and a implementation, mostly taken form as a Context.
+A store is the link between a Resource and a data implementation. A store is mainly taken form as a Context, In other words we will have to Consume the Context(Store) to get the Store.
Generally a Store will be holding one or more RxJS Subjects, each Subject is made available for Subscription via a RxJS Observable.
### A Simple Store:
@@ -13,20 +13,154 @@ Generally a Store will be holding one or more RxJS Subjects, each Subject is mad
````
class MyProductStore {
- protected _products = new ArrayState(>[]);
- public readonly products = this._items.asObservable();
+ #products = new ArrayState(>[], (product) => product.key);
+
+ public readonly products = this.#products.asObservable();
protected host: UmbControllerHostInterface;
constructor(host: UmbControllerHostInterface) {
this.host = host;
+
+ // The Store provides it self as a Context-API.
+ new UmbContextProviderController(_host, 'MyStoreContextAlias', this);
}
+}
+````
+
+In this example we created a ArrayState, A State which is specific to Arrays.
+This holds the data for one or more Observables to convey for outsiders.
+
+This example shows how to use the store:
+
+````
+class MyImplementation extends UmbLitElement {
+
+ private _myProductStore?: MyProductStore;
+
+ constructor() {
+ super();
+
+ // Notice the consume callback is triggered initially and everytime the Context is changed.
+ this.consume('MyStoreContextAlias', (context) => {
+ this._myProductStore = context;
+
+ this._observeAllProducts();
+ });
+ }
+
+
+ private _observeAllProducts() {
+ if (!this._myProductStore) return;
+
+ // Notice this callback will be triggered initially and each time the products change:
+ this.observe(this._myProductStore.products, (products) => {
+ console.log("The data of all products is:", products);
+ });
+ }
+
+}
+````
+
+
+
+
+### A bit more meaningful Store:
+
+Here we added a method that returns an Observable that is specific to the requested product.
+
+````
+class MyProductStore {
+
+ ...
+
getByKey(key: string) {
+
+ // Request data via a Resource to then take part of this state when recieved.
tryExecuteAndNotify(this.host, ProductResource.getByKey({key})).then(({ data }) => {
if (data) {
- this._products.append(data.items);
+ this.#products.append(data.items);
}
});
+
+ // Return a Observable part, to listen for this specific product and the future changes of it.
+ return createObservablePart(this.#data, (documents) =>
+ documents.find((document) => document.key === key)
+ );
}
}
````
+
+
+An example using this method:
+
+````
+class MyImplementation extends UmbLitElement {
+
+ private _myProductStore?: MyProductStore;
+
+ constructor() {
+ super();
+
+ // Notice the consume callback is triggered initially and everytime the Context is changed.
+ this.consume('MyStoreContextAlias', (context) => {
+ this._myProductStore = context;
+
+ this._observeASpecificProduct();
+ });
+ }
+
+ private _observeASpecificProduct() {
+ if (!this._myProductStore) return;
+
+ // Notice this callback will be triggered initially and each time the specific product change:
+ this.observe(this._myProductStore.getByKey('1234'), (product) => {
+ console.log("The data of product `1234`` is:", product);
+ });
+ }
+
+}
+````
+
+
+
+### Create many Observables:
+
+A Store must hold different Observables some very general and others specific. All in perspective of what types of observes we like to accommodate.
+
+This example give some inspiration to how fine grained this can become:
+
+````
+class MyProductStore {
+
+ #products = new ArrayState(>[]);
+
+ public readonly products = this.#products.asObservable();
+ public readonly amountOfProducts = createObservablePart(this.#products, (products) => products.length);
+ public readonly topTenRatedProducts = createObservablePart(this.#products, (products) => products.sort((a, b) => b.rating - a.rating).slice(0, 10));
+
+ ...
+
+}
+````
+
+An observer of an Observable will only be triggered if the specific part of that data has changed.
+With this we can make a high performant application, only triggering the parts that needs to update when data is changed.
+
+
+
+
+### Ensure unique data:
+
+For incoming data to replace existing data, we need to clarify what makes a entry of the array unique.
+In the examples of this guide each product has a key, and we have clarified this to the State by giving it the little method `(product) => product.key` as part of the its creation:
+
+````
+class MyProductStore {
+
+ #products = new ArrayState(>[], (product) => product.key);
+
+ ...
+
+}
+````