diff --git a/.changeset/khaki-mangos-shout.md b/.changeset/khaki-mangos-shout.md
new file mode 100644
index 00000000..adafd6b9
--- /dev/null
+++ b/.changeset/khaki-mangos-shout.md
@@ -0,0 +1,11 @@
+---
+'@agile-ts/core': patch
+'@agile-ts/react': patch
+'@agile-ts/utils': patch
+---
+
+
+- added move method
+- fixed 0 as itemKey issue
+- fixed computed tracking
+
diff --git a/README.md b/README.md
index d40a0733..f0983f43 100644
--- a/README.md
+++ b/README.md
@@ -185,7 +185,9 @@ To find out more, check out the [CONTRIBUTING.md](https://github.com/agile-ts/ag
| [@agile-ts/api](/packages/api) | [](https://www.npmjs.com/package/@agile-ts/api) | Promise based API |
| [@agile-ts/multieditor](/packages/multieditor) | [](https://www.npmjs.com/package/@agile-ts/multieditor) | Simple Form Manager |
| [@agile-ts/event](/packages/event) | [](https://www.npmjs.com/package/@agile-ts/event) | Handy class for emitting UI Events |
-
+| [@agile-ts/logger](/packages/logger) | [](https://www.npmjs.com/package/@agile-ts/logger) | Manages the logging of AgileTs |
+| [@agile-ts/utils](/packages/utils) | [](https://www.npmjs.com/package/@agile-ts/utils) | Util functions of AgileTs |
+| [@agile-ts/proxytree](/packages/proxytree) | [](https://www.npmjs.com/package/@agile-ts/proxytree) | Create Proxy Tree |
@@ -193,4 +195,4 @@ To find out more, check out the [CONTRIBUTING.md](https://github.com/agile-ts/ag
-AgileTs is inspired by [MVVM Frameworks](https://de.wikipedia.org/wiki/Model_View_ViewModel) like [MobX](https://mobx.js.org/README.html) and [PulseJs](https://github.com/pulse-framework/pulse).
\ No newline at end of file
+AgileTs is inspired by [MVVM Frameworks](https://de.wikipedia.org/wiki/Model_View_ViewModel) like [MobX](https://mobx.js.org/README.html) and [PulseJs](https://github.com/pulse-framework/pulse).
diff --git a/examples/react-native/README.md b/examples/react-native/README.md
index b59ce96a..623625f4 100644
--- a/examples/react-native/README.md
+++ b/examples/react-native/README.md
@@ -1,6 +1,30 @@
# `react-native` Examples
-Welcome, React-Native Developers, here you find all `react-native` related examples, which will hopefully take you a step further.
-To get an idea about each example, checkout our
-[examples](https://agile-ts.org/docs/examples/react-native) documentation page,
-which describes what the individual examples roughly do.
\ No newline at end of file
+Welcome, **React-Native Developers**,
+here you find all `react-native` related examples, which hopefully will take you one step further.
+As you surely noticed, there are two sub-folders called `develop` and `release`.
+Each of these two folders contains examples aimed at different target groups.
+
+### `develop`
+
+The `develop` examples are primarily intended for AgileTs contributors
+to test new features and bug fixes in a production-like environment.
+Therefore, we can see this section more as a playground for contributors.
+In these examples, AgileTs is imported using [`yalc`](https://github.com/wclr/yalc).
+`Yalc` is like a local npm store on your engine, which can be set up by following the guide on their [website](https://github.com/wclr/yalc).
+
+### `release`
+
+The `release` examples target people who want to see how AgileTs work in production-like environments.
+In these examples, AgileTs is imported as a release version.
+Therefore, you can simply run them on your local machine without further thinking.
+
+## 🛤 More
+
+Can't get enough of AgileTs?
+You can find even more examples in the [Example Section](https://agile-ts.org/docs/examples/react-native) on the AgileTs documentation.
+
+## ❓ Help
+
+If you have any further questions about these examples or AgileTs in general,
+don't hesitate to join our [Community Discord](https://discord.gg/T9GzreAwPH).
diff --git a/examples/react-native/AwesomeTSProject/.buckconfig b/examples/react-native/develop/AwesomeTSProject/.buckconfig
similarity index 100%
rename from examples/react-native/AwesomeTSProject/.buckconfig
rename to examples/react-native/develop/AwesomeTSProject/.buckconfig
diff --git a/examples/react-native/AwesomeTSProject/.eslintrc.js b/examples/react-native/develop/AwesomeTSProject/.eslintrc.js
similarity index 100%
rename from examples/react-native/AwesomeTSProject/.eslintrc.js
rename to examples/react-native/develop/AwesomeTSProject/.eslintrc.js
diff --git a/examples/react-native/AwesomeTSProject/.gitattributes b/examples/react-native/develop/AwesomeTSProject/.gitattributes
similarity index 100%
rename from examples/react-native/AwesomeTSProject/.gitattributes
rename to examples/react-native/develop/AwesomeTSProject/.gitattributes
diff --git a/examples/react-native/AwesomeTSProject/.gitignore b/examples/react-native/develop/AwesomeTSProject/.gitignore
similarity index 100%
rename from examples/react-native/AwesomeTSProject/.gitignore
rename to examples/react-native/develop/AwesomeTSProject/.gitignore
diff --git a/examples/react-native/AwesomeTSProject/.watchmanconfig b/examples/react-native/develop/AwesomeTSProject/.watchmanconfig
similarity index 100%
rename from examples/react-native/AwesomeTSProject/.watchmanconfig
rename to examples/react-native/develop/AwesomeTSProject/.watchmanconfig
diff --git a/examples/react-native/AwesomeTSProject/App.tsx b/examples/react-native/develop/AwesomeTSProject/App.tsx
similarity index 100%
rename from examples/react-native/AwesomeTSProject/App.tsx
rename to examples/react-native/develop/AwesomeTSProject/App.tsx
diff --git a/examples/react-native/AwesomeTSProject/README.md b/examples/react-native/develop/AwesomeTSProject/README.md
similarity index 100%
rename from examples/react-native/AwesomeTSProject/README.md
rename to examples/react-native/develop/AwesomeTSProject/README.md
diff --git a/examples/react-native/AwesomeTSProject/android/app/_BUCK b/examples/react-native/develop/AwesomeTSProject/android/app/_BUCK
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/_BUCK
rename to examples/react-native/develop/AwesomeTSProject/android/app/_BUCK
diff --git a/examples/react-native/AwesomeTSProject/android/app/build.gradle b/examples/react-native/develop/AwesomeTSProject/android/app/build.gradle
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/build.gradle
rename to examples/react-native/develop/AwesomeTSProject/android/app/build.gradle
diff --git a/examples/react-native/AwesomeTSProject/android/app/build_defs.bzl b/examples/react-native/develop/AwesomeTSProject/android/app/build_defs.bzl
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/build_defs.bzl
rename to examples/react-native/develop/AwesomeTSProject/android/app/build_defs.bzl
diff --git a/examples/react-native/AwesomeTSProject/android/app/debug.keystore b/examples/react-native/develop/AwesomeTSProject/android/app/debug.keystore
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/debug.keystore
rename to examples/react-native/develop/AwesomeTSProject/android/app/debug.keystore
diff --git a/examples/react-native/AwesomeTSProject/android/app/proguard-rules.pro b/examples/react-native/develop/AwesomeTSProject/android/app/proguard-rules.pro
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/proguard-rules.pro
rename to examples/react-native/develop/AwesomeTSProject/android/app/proguard-rules.pro
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/debug/AndroidManifest.xml b/examples/react-native/develop/AwesomeTSProject/android/app/src/debug/AndroidManifest.xml
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/debug/AndroidManifest.xml
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/debug/AndroidManifest.xml
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/debug/java/com/awesometsproject/ReactNativeFlipper.java b/examples/react-native/develop/AwesomeTSProject/android/app/src/debug/java/com/awesometsproject/ReactNativeFlipper.java
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/debug/java/com/awesometsproject/ReactNativeFlipper.java
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/debug/java/com/awesometsproject/ReactNativeFlipper.java
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/AndroidManifest.xml b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/AndroidManifest.xml
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/AndroidManifest.xml
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/AndroidManifest.xml
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/java/com/awesometsproject/MainActivity.java b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/java/com/awesometsproject/MainActivity.java
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/java/com/awesometsproject/MainActivity.java
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/java/com/awesometsproject/MainActivity.java
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/java/com/awesometsproject/MainApplication.java b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/java/com/awesometsproject/MainApplication.java
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/java/com/awesometsproject/MainApplication.java
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/java/com/awesometsproject/MainApplication.java
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/values/strings.xml b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/values/strings.xml
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/values/strings.xml
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/values/strings.xml
diff --git a/examples/react-native/AwesomeTSProject/android/app/src/main/res/values/styles.xml b/examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/values/styles.xml
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/app/src/main/res/values/styles.xml
rename to examples/react-native/develop/AwesomeTSProject/android/app/src/main/res/values/styles.xml
diff --git a/examples/react-native/AwesomeTSProject/android/build.gradle b/examples/react-native/develop/AwesomeTSProject/android/build.gradle
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/build.gradle
rename to examples/react-native/develop/AwesomeTSProject/android/build.gradle
diff --git a/examples/react-native/AwesomeTSProject/android/gradle.properties b/examples/react-native/develop/AwesomeTSProject/android/gradle.properties
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/gradle.properties
rename to examples/react-native/develop/AwesomeTSProject/android/gradle.properties
diff --git a/examples/react-native/AwesomeTSProject/android/gradle/wrapper/gradle-wrapper.jar b/examples/react-native/develop/AwesomeTSProject/android/gradle/wrapper/gradle-wrapper.jar
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/gradle/wrapper/gradle-wrapper.jar
rename to examples/react-native/develop/AwesomeTSProject/android/gradle/wrapper/gradle-wrapper.jar
diff --git a/examples/react-native/AwesomeTSProject/android/gradle/wrapper/gradle-wrapper.properties b/examples/react-native/develop/AwesomeTSProject/android/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/gradle/wrapper/gradle-wrapper.properties
rename to examples/react-native/develop/AwesomeTSProject/android/gradle/wrapper/gradle-wrapper.properties
diff --git a/examples/react-native/AwesomeTSProject/android/gradlew b/examples/react-native/develop/AwesomeTSProject/android/gradlew
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/gradlew
rename to examples/react-native/develop/AwesomeTSProject/android/gradlew
diff --git a/examples/react-native/AwesomeTSProject/android/gradlew.bat b/examples/react-native/develop/AwesomeTSProject/android/gradlew.bat
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/gradlew.bat
rename to examples/react-native/develop/AwesomeTSProject/android/gradlew.bat
diff --git a/examples/react-native/AwesomeTSProject/android/settings.gradle b/examples/react-native/develop/AwesomeTSProject/android/settings.gradle
similarity index 100%
rename from examples/react-native/AwesomeTSProject/android/settings.gradle
rename to examples/react-native/develop/AwesomeTSProject/android/settings.gradle
diff --git a/examples/react-native/AwesomeTSProject/app.json b/examples/react-native/develop/AwesomeTSProject/app.json
similarity index 100%
rename from examples/react-native/AwesomeTSProject/app.json
rename to examples/react-native/develop/AwesomeTSProject/app.json
diff --git a/examples/react-native/AwesomeTSProject/babel.config.js b/examples/react-native/develop/AwesomeTSProject/babel.config.js
similarity index 100%
rename from examples/react-native/AwesomeTSProject/babel.config.js
rename to examples/react-native/develop/AwesomeTSProject/babel.config.js
diff --git a/examples/react-native/AwesomeTSProject/core/index.ts b/examples/react-native/develop/AwesomeTSProject/core/index.ts
similarity index 100%
rename from examples/react-native/AwesomeTSProject/core/index.ts
rename to examples/react-native/develop/AwesomeTSProject/core/index.ts
diff --git a/examples/react-native/AwesomeTSProject/index.js b/examples/react-native/develop/AwesomeTSProject/index.js
similarity index 100%
rename from examples/react-native/AwesomeTSProject/index.js
rename to examples/react-native/develop/AwesomeTSProject/index.js
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject-tvOS/Info.plist b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject-tvOS/Info.plist
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject-tvOS/Info.plist
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject-tvOS/Info.plist
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject-tvOSTests/Info.plist b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject-tvOSTests/Info.plist
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject-tvOSTests/Info.plist
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject-tvOSTests/Info.plist
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/project.pbxproj b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/project.pbxproj
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/project.pbxproj
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/project.pbxproj
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/xcshareddata/xcschemes/AwesomeTSProject-tvOS.xcscheme b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/xcshareddata/xcschemes/AwesomeTSProject-tvOS.xcscheme
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/xcshareddata/xcschemes/AwesomeTSProject-tvOS.xcscheme
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/xcshareddata/xcschemes/AwesomeTSProject-tvOS.xcscheme
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/xcshareddata/xcschemes/AwesomeTSProject.xcscheme b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/xcshareddata/xcschemes/AwesomeTSProject.xcscheme
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/xcshareddata/xcschemes/AwesomeTSProject.xcscheme
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcodeproj/xcshareddata/xcschemes/AwesomeTSProject.xcscheme
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcworkspace/contents.xcworkspacedata b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcworkspace/contents.xcworkspacedata
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcworkspace/contents.xcworkspacedata
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/AppDelegate.h b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/AppDelegate.h
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/AppDelegate.h
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/AppDelegate.h
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/AppDelegate.m b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/AppDelegate.m
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/AppDelegate.m
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/AppDelegate.m
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/Images.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/Images.xcassets/AppIcon.appiconset/Contents.json
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/Images.xcassets/AppIcon.appiconset/Contents.json
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/Images.xcassets/Contents.json b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/Images.xcassets/Contents.json
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/Images.xcassets/Contents.json
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/Images.xcassets/Contents.json
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/Info.plist b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/Info.plist
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/Info.plist
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/Info.plist
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/LaunchScreen.storyboard b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/LaunchScreen.storyboard
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/LaunchScreen.storyboard
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/LaunchScreen.storyboard
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/main.m b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/main.m
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProject/main.m
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProject/main.m
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProjectTests/AwesomeTSProjectTests.m b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProjectTests/AwesomeTSProjectTests.m
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProjectTests/AwesomeTSProjectTests.m
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProjectTests/AwesomeTSProjectTests.m
diff --git a/examples/react-native/AwesomeTSProject/ios/AwesomeTSProjectTests/Info.plist b/examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProjectTests/Info.plist
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/AwesomeTSProjectTests/Info.plist
rename to examples/react-native/develop/AwesomeTSProject/ios/AwesomeTSProjectTests/Info.plist
diff --git a/examples/react-native/AwesomeTSProject/ios/Podfile b/examples/react-native/develop/AwesomeTSProject/ios/Podfile
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/Podfile
rename to examples/react-native/develop/AwesomeTSProject/ios/Podfile
diff --git a/examples/react-native/AwesomeTSProject/ios/Podfile.lock b/examples/react-native/develop/AwesomeTSProject/ios/Podfile.lock
similarity index 100%
rename from examples/react-native/AwesomeTSProject/ios/Podfile.lock
rename to examples/react-native/develop/AwesomeTSProject/ios/Podfile.lock
diff --git a/examples/react-native/AwesomeTSProject/metro.config.js b/examples/react-native/develop/AwesomeTSProject/metro.config.js
similarity index 100%
rename from examples/react-native/AwesomeTSProject/metro.config.js
rename to examples/react-native/develop/AwesomeTSProject/metro.config.js
diff --git a/examples/react-native/AwesomeTSProject/package.json b/examples/react-native/develop/AwesomeTSProject/package.json
similarity index 100%
rename from examples/react-native/AwesomeTSProject/package.json
rename to examples/react-native/develop/AwesomeTSProject/package.json
diff --git a/examples/react-native/AwesomeTSProject/tsconfig.json b/examples/react-native/develop/AwesomeTSProject/tsconfig.json
similarity index 100%
rename from examples/react-native/AwesomeTSProject/tsconfig.json
rename to examples/react-native/develop/AwesomeTSProject/tsconfig.json
diff --git a/examples/react-native/AwesomeTSProject/yarn.lock b/examples/react-native/develop/AwesomeTSProject/yarn.lock
similarity index 100%
rename from examples/react-native/AwesomeTSProject/yarn.lock
rename to examples/react-native/develop/AwesomeTSProject/yarn.lock
diff --git a/examples/react/README.md b/examples/react/README.md
index 1e94b92a..d47d87b7 100644
--- a/examples/react/README.md
+++ b/examples/react/README.md
@@ -1,6 +1,30 @@
# `react` Examples
-Welcome, React Developers, here you find all `react` related examples, which will hopefully take you a step further.
-To get an idea about each example, checkout our
-[examples](https://agile-ts.org/docs/examples/react) documentation page,
-which describes what the individual examples roughly do.
\ No newline at end of file
+Welcome, **React Developers**,
+here you find all `react` related examples, which hopefully will take you one step further.
+As you surely noticed, there are two sub-folders called `develop` and `release`.
+Each of these two folders contains examples aimed at different target groups.
+
+### `develop`
+
+The `develop` examples are primarily intended for AgileTs contributors
+to test new features and bug fixes in a production-like environment.
+Therefore, we can see this section more as a playground for contributors.
+In these examples, AgileTs is imported using [`yalc`](https://github.com/wclr/yalc).
+`Yalc` is like a local npm store on your engine, which can be set up by following the guide on their [website](https://github.com/wclr/yalc).
+
+### `release`
+
+The `release` examples target people who want to see how AgileTs work in production-like environments.
+In these examples, AgileTs is imported as a release version.
+Therefore, you can simply run them on your local machine without further thinking.
+
+## 🛤 More
+
+Can't get enough of AgileTs?
+You can find even more examples in the [Example Section](https://agile-ts.org/docs/examples/react) on the AgileTs documentation.
+
+## ❓ Help
+
+If you have any further questions about these examples or AgileTs in general,
+don't hesitate to join our [Community Discord](https://discord.gg/T9GzreAwPH).
diff --git a/examples/react/class-component-ts/.env b/examples/react/develop/class-component-ts/.env
similarity index 100%
rename from examples/react/class-component-ts/.env
rename to examples/react/develop/class-component-ts/.env
diff --git a/examples/react/class-component-ts/.gitignore b/examples/react/develop/class-component-ts/.gitignore
similarity index 100%
rename from examples/react/class-component-ts/.gitignore
rename to examples/react/develop/class-component-ts/.gitignore
diff --git a/examples/react/class-component-ts/README.md b/examples/react/develop/class-component-ts/README.md
similarity index 100%
rename from examples/react/class-component-ts/README.md
rename to examples/react/develop/class-component-ts/README.md
diff --git a/examples/react/class-component-ts/package.json b/examples/react/develop/class-component-ts/package.json
similarity index 100%
rename from examples/react/class-component-ts/package.json
rename to examples/react/develop/class-component-ts/package.json
diff --git a/examples/react/class-component-ts/public/favicon.ico b/examples/react/develop/class-component-ts/public/favicon.ico
similarity index 100%
rename from examples/react/class-component-ts/public/favicon.ico
rename to examples/react/develop/class-component-ts/public/favicon.ico
diff --git a/examples/react/class-component-ts/public/index.html b/examples/react/develop/class-component-ts/public/index.html
similarity index 100%
rename from examples/react/class-component-ts/public/index.html
rename to examples/react/develop/class-component-ts/public/index.html
diff --git a/examples/react/class-component-ts/public/logo192.png b/examples/react/develop/class-component-ts/public/logo192.png
similarity index 100%
rename from examples/react/class-component-ts/public/logo192.png
rename to examples/react/develop/class-component-ts/public/logo192.png
diff --git a/examples/react/class-component-ts/public/logo512.png b/examples/react/develop/class-component-ts/public/logo512.png
similarity index 100%
rename from examples/react/class-component-ts/public/logo512.png
rename to examples/react/develop/class-component-ts/public/logo512.png
diff --git a/examples/react/class-component-ts/public/manifest.json b/examples/react/develop/class-component-ts/public/manifest.json
similarity index 100%
rename from examples/react/class-component-ts/public/manifest.json
rename to examples/react/develop/class-component-ts/public/manifest.json
diff --git a/examples/react/class-component-ts/public/robots.txt b/examples/react/develop/class-component-ts/public/robots.txt
similarity index 100%
rename from examples/react/class-component-ts/public/robots.txt
rename to examples/react/develop/class-component-ts/public/robots.txt
diff --git a/examples/react/class-component-ts/src/App.css b/examples/react/develop/class-component-ts/src/App.css
similarity index 100%
rename from examples/react/class-component-ts/src/App.css
rename to examples/react/develop/class-component-ts/src/App.css
diff --git a/examples/react/class-component-ts/src/App.tsx b/examples/react/develop/class-component-ts/src/App.tsx
similarity index 100%
rename from examples/react/class-component-ts/src/App.tsx
rename to examples/react/develop/class-component-ts/src/App.tsx
diff --git a/examples/react/class-component-ts/src/core/index.ts b/examples/react/develop/class-component-ts/src/core/index.ts
similarity index 100%
rename from examples/react/class-component-ts/src/core/index.ts
rename to examples/react/develop/class-component-ts/src/core/index.ts
diff --git a/examples/react/class-component-ts/src/index.css b/examples/react/develop/class-component-ts/src/index.css
similarity index 100%
rename from examples/react/class-component-ts/src/index.css
rename to examples/react/develop/class-component-ts/src/index.css
diff --git a/examples/react/class-component-ts/src/index.tsx b/examples/react/develop/class-component-ts/src/index.tsx
similarity index 100%
rename from examples/react/class-component-ts/src/index.tsx
rename to examples/react/develop/class-component-ts/src/index.tsx
diff --git a/examples/react/class-component-ts/src/react-app-env.d.ts b/examples/react/develop/class-component-ts/src/react-app-env.d.ts
similarity index 100%
rename from examples/react/class-component-ts/src/react-app-env.d.ts
rename to examples/react/develop/class-component-ts/src/react-app-env.d.ts
diff --git a/examples/react/class-component-ts/tsconfig.json b/examples/react/develop/class-component-ts/tsconfig.json
similarity index 100%
rename from examples/react/class-component-ts/tsconfig.json
rename to examples/react/develop/class-component-ts/tsconfig.json
diff --git a/examples/react/class-component-ts/yarn.lock b/examples/react/develop/class-component-ts/yarn.lock
similarity index 100%
rename from examples/react/class-component-ts/yarn.lock
rename to examples/react/develop/class-component-ts/yarn.lock
diff --git a/examples/react/functional-component-ts/.env b/examples/react/develop/functional-component-ts/.env
similarity index 100%
rename from examples/react/functional-component-ts/.env
rename to examples/react/develop/functional-component-ts/.env
diff --git a/examples/react/functional-component-ts/.gitignore b/examples/react/develop/functional-component-ts/.gitignore
similarity index 100%
rename from examples/react/functional-component-ts/.gitignore
rename to examples/react/develop/functional-component-ts/.gitignore
diff --git a/examples/react/functional-component-ts/README.md b/examples/react/develop/functional-component-ts/README.md
similarity index 100%
rename from examples/react/functional-component-ts/README.md
rename to examples/react/develop/functional-component-ts/README.md
diff --git a/examples/react/functional-component-ts/package.json b/examples/react/develop/functional-component-ts/package.json
similarity index 100%
rename from examples/react/functional-component-ts/package.json
rename to examples/react/develop/functional-component-ts/package.json
diff --git a/examples/react/functional-component-ts/public/favicon.ico b/examples/react/develop/functional-component-ts/public/favicon.ico
similarity index 100%
rename from examples/react/functional-component-ts/public/favicon.ico
rename to examples/react/develop/functional-component-ts/public/favicon.ico
diff --git a/examples/react/functional-component-ts/public/index.html b/examples/react/develop/functional-component-ts/public/index.html
similarity index 100%
rename from examples/react/functional-component-ts/public/index.html
rename to examples/react/develop/functional-component-ts/public/index.html
diff --git a/examples/react/functional-component-ts/public/logo192.png b/examples/react/develop/functional-component-ts/public/logo192.png
similarity index 100%
rename from examples/react/functional-component-ts/public/logo192.png
rename to examples/react/develop/functional-component-ts/public/logo192.png
diff --git a/examples/react/functional-component-ts/public/logo512.png b/examples/react/develop/functional-component-ts/public/logo512.png
similarity index 100%
rename from examples/react/functional-component-ts/public/logo512.png
rename to examples/react/develop/functional-component-ts/public/logo512.png
diff --git a/examples/react/functional-component-ts/public/manifest.json b/examples/react/develop/functional-component-ts/public/manifest.json
similarity index 100%
rename from examples/react/functional-component-ts/public/manifest.json
rename to examples/react/develop/functional-component-ts/public/manifest.json
diff --git a/examples/react/functional-component-ts/public/robots.txt b/examples/react/develop/functional-component-ts/public/robots.txt
similarity index 100%
rename from examples/react/functional-component-ts/public/robots.txt
rename to examples/react/develop/functional-component-ts/public/robots.txt
diff --git a/examples/react/functional-component-ts/src/App.css b/examples/react/develop/functional-component-ts/src/App.css
similarity index 100%
rename from examples/react/functional-component-ts/src/App.css
rename to examples/react/develop/functional-component-ts/src/App.css
diff --git a/examples/react/functional-component-ts/src/App.tsx b/examples/react/develop/functional-component-ts/src/App.tsx
similarity index 100%
rename from examples/react/functional-component-ts/src/App.tsx
rename to examples/react/develop/functional-component-ts/src/App.tsx
diff --git a/examples/react/functional-component-ts/src/core/index.ts b/examples/react/develop/functional-component-ts/src/core/index.ts
similarity index 100%
rename from examples/react/functional-component-ts/src/core/index.ts
rename to examples/react/develop/functional-component-ts/src/core/index.ts
diff --git a/examples/react/functional-component-ts/src/index.css b/examples/react/develop/functional-component-ts/src/index.css
similarity index 100%
rename from examples/react/functional-component-ts/src/index.css
rename to examples/react/develop/functional-component-ts/src/index.css
diff --git a/examples/react/functional-component-ts/src/index.tsx b/examples/react/develop/functional-component-ts/src/index.tsx
similarity index 100%
rename from examples/react/functional-component-ts/src/index.tsx
rename to examples/react/develop/functional-component-ts/src/index.tsx
diff --git a/examples/react/functional-component-ts/src/react-app-env.d.ts b/examples/react/develop/functional-component-ts/src/react-app-env.d.ts
similarity index 100%
rename from examples/react/functional-component-ts/src/react-app-env.d.ts
rename to examples/react/develop/functional-component-ts/src/react-app-env.d.ts
diff --git a/examples/react/functional-component-ts/tsconfig.json b/examples/react/develop/functional-component-ts/tsconfig.json
similarity index 100%
rename from examples/react/functional-component-ts/tsconfig.json
rename to examples/react/develop/functional-component-ts/tsconfig.json
diff --git a/examples/react/functional-component-ts/yarn.lock b/examples/react/develop/functional-component-ts/yarn.lock
similarity index 99%
rename from examples/react/functional-component-ts/yarn.lock
rename to examples/react/develop/functional-component-ts/yarn.lock
index f8fc9d17..54955758 100644
--- a/examples/react/functional-component-ts/yarn.lock
+++ b/examples/react/develop/functional-component-ts/yarn.lock
@@ -3,22 +3,46 @@
"@agile-ts/api@file:.yalc/@agile-ts/api":
- version "0.0.15"
+ version "0.0.16"
+ dependencies:
+ "@agile-ts/utils" "^0.0.2"
"@agile-ts/core@file:.yalc/@agile-ts/core":
- version "0.0.14"
+ version "0.0.15"
+ dependencies:
+ "@agile-ts/logger" "^0.0.2"
+ "@agile-ts/utils" "^0.0.2"
"@agile-ts/event@file:.yalc/@agile-ts/event":
- version "0.0.4"
+ version "0.0.5"
+
+"@agile-ts/logger@^0.0.2":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/@agile-ts/logger/-/logger-0.0.2.tgz#80a726531dd63ca7d1c9a123383e57b5501efbb0"
+ integrity sha512-rJJ5pqXtOriYxjuZPhHs2J9N1FnIaAZqItCw0MXW9/5od/uhJ28aiG7w9RUBZts9SjDcICYEfjFMcTJ/kYJsMg==
+ dependencies:
+ "@agile-ts/utils" "^0.0.2"
"@agile-ts/multieditor@file:.yalc/@agile-ts/multieditor":
- version "0.0.14"
+ version "0.0.15"
+
+"@agile-ts/proxytree@^0.0.2":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/@agile-ts/proxytree/-/proxytree-0.0.2.tgz#516ed19ee8d58aeecb291788a1e47be3dc23df8c"
+ integrity sha512-PbSiChF0GcUoWnrbnHauzBxZ5r/+4pZSZWpYjkBcIFa48DgTtFzg5DfQzsW3Rc1Y0QSFGYqcZOvCK1xAjLIQ2g==
"@agile-ts/proxytree@file:.yalc/@agile-ts/proxytree":
version "0.0.1"
"@agile-ts/react@file:.yalc/@agile-ts/react":
- version "0.0.15"
+ version "0.0.16"
+ dependencies:
+ "@agile-ts/proxytree" "^0.0.2"
+
+"@agile-ts/utils@^0.0.2":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/@agile-ts/utils/-/utils-0.0.2.tgz#5f03761ace569b6c9ddd28c22f7b0fbec8b006b1"
+ integrity sha512-LqgQyMdK+zDuTCmOX6FOxTH4JNXhEvGFqIyNqRDoP99BK6MHGrK+n7nOW+1b4x6ZCYe0+VmwtG5CeOPOm3Siow==
"@babel/code-frame@7.8.3":
version "7.8.3"
diff --git a/examples/react/multieditor-ts/.env b/examples/react/develop/multieditor-ts/.env
similarity index 100%
rename from examples/react/multieditor-ts/.env
rename to examples/react/develop/multieditor-ts/.env
diff --git a/examples/react/multieditor-ts/.gitignore b/examples/react/develop/multieditor-ts/.gitignore
similarity index 100%
rename from examples/react/multieditor-ts/.gitignore
rename to examples/react/develop/multieditor-ts/.gitignore
diff --git a/examples/react/multieditor-ts/README.md b/examples/react/develop/multieditor-ts/README.md
similarity index 100%
rename from examples/react/multieditor-ts/README.md
rename to examples/react/develop/multieditor-ts/README.md
diff --git a/examples/react/multieditor-ts/package.json b/examples/react/develop/multieditor-ts/package.json
similarity index 100%
rename from examples/react/multieditor-ts/package.json
rename to examples/react/develop/multieditor-ts/package.json
diff --git a/examples/react/multieditor-ts/public/favicon.ico b/examples/react/develop/multieditor-ts/public/favicon.ico
similarity index 100%
rename from examples/react/multieditor-ts/public/favicon.ico
rename to examples/react/develop/multieditor-ts/public/favicon.ico
diff --git a/examples/react/multieditor-ts/public/index.html b/examples/react/develop/multieditor-ts/public/index.html
similarity index 100%
rename from examples/react/multieditor-ts/public/index.html
rename to examples/react/develop/multieditor-ts/public/index.html
diff --git a/examples/react/multieditor-ts/public/logo192.png b/examples/react/develop/multieditor-ts/public/logo192.png
similarity index 100%
rename from examples/react/multieditor-ts/public/logo192.png
rename to examples/react/develop/multieditor-ts/public/logo192.png
diff --git a/examples/react/multieditor-ts/public/logo512.png b/examples/react/develop/multieditor-ts/public/logo512.png
similarity index 100%
rename from examples/react/multieditor-ts/public/logo512.png
rename to examples/react/develop/multieditor-ts/public/logo512.png
diff --git a/examples/react/multieditor-ts/public/manifest.json b/examples/react/develop/multieditor-ts/public/manifest.json
similarity index 100%
rename from examples/react/multieditor-ts/public/manifest.json
rename to examples/react/develop/multieditor-ts/public/manifest.json
diff --git a/examples/react/multieditor-ts/public/robots.txt b/examples/react/develop/multieditor-ts/public/robots.txt
similarity index 100%
rename from examples/react/multieditor-ts/public/robots.txt
rename to examples/react/develop/multieditor-ts/public/robots.txt
diff --git a/examples/react/multieditor-ts/src/App.css b/examples/react/develop/multieditor-ts/src/App.css
similarity index 100%
rename from examples/react/multieditor-ts/src/App.css
rename to examples/react/develop/multieditor-ts/src/App.css
diff --git a/examples/react/multieditor-ts/src/App.tsx b/examples/react/develop/multieditor-ts/src/App.tsx
similarity index 100%
rename from examples/react/multieditor-ts/src/App.tsx
rename to examples/react/develop/multieditor-ts/src/App.tsx
diff --git a/examples/react/multieditor-ts/src/components/ErrorMessage.tsx b/examples/react/develop/multieditor-ts/src/components/ErrorMessage.tsx
similarity index 100%
rename from examples/react/multieditor-ts/src/components/ErrorMessage.tsx
rename to examples/react/develop/multieditor-ts/src/components/ErrorMessage.tsx
diff --git a/examples/react/multieditor-ts/src/core/agile.ts b/examples/react/develop/multieditor-ts/src/core/agile.ts
similarity index 100%
rename from examples/react/multieditor-ts/src/core/agile.ts
rename to examples/react/develop/multieditor-ts/src/core/agile.ts
diff --git a/examples/react/multieditor-ts/src/core/signUpEditor.ts b/examples/react/develop/multieditor-ts/src/core/signUpEditor.ts
similarity index 100%
rename from examples/react/multieditor-ts/src/core/signUpEditor.ts
rename to examples/react/develop/multieditor-ts/src/core/signUpEditor.ts
diff --git a/examples/react/multieditor-ts/src/core/utils.ts b/examples/react/develop/multieditor-ts/src/core/utils.ts
similarity index 100%
rename from examples/react/multieditor-ts/src/core/utils.ts
rename to examples/react/develop/multieditor-ts/src/core/utils.ts
diff --git a/examples/react/multieditor-ts/src/index.css b/examples/react/develop/multieditor-ts/src/index.css
similarity index 100%
rename from examples/react/multieditor-ts/src/index.css
rename to examples/react/develop/multieditor-ts/src/index.css
diff --git a/examples/react/multieditor-ts/src/index.tsx b/examples/react/develop/multieditor-ts/src/index.tsx
similarity index 100%
rename from examples/react/multieditor-ts/src/index.tsx
rename to examples/react/develop/multieditor-ts/src/index.tsx
diff --git a/examples/react/multieditor-ts/src/react-app-env.d.ts b/examples/react/develop/multieditor-ts/src/react-app-env.d.ts
similarity index 100%
rename from examples/react/multieditor-ts/src/react-app-env.d.ts
rename to examples/react/develop/multieditor-ts/src/react-app-env.d.ts
diff --git a/examples/react/multieditor-ts/tsconfig.json b/examples/react/develop/multieditor-ts/tsconfig.json
similarity index 100%
rename from examples/react/multieditor-ts/tsconfig.json
rename to examples/react/develop/multieditor-ts/tsconfig.json
diff --git a/examples/react/multieditor-ts/yarn.lock b/examples/react/develop/multieditor-ts/yarn.lock
similarity index 100%
rename from examples/react/multieditor-ts/yarn.lock
rename to examples/react/develop/multieditor-ts/yarn.lock
diff --git a/packages/core/src/collection/collection.persistent.ts b/packages/core/src/collection/collection.persistent.ts
index 1a95e082..be9be6f1 100644
--- a/packages/core/src/collection/collection.persistent.ts
+++ b/packages/core/src/collection/collection.persistent.ts
@@ -258,12 +258,12 @@ export class CollectionPersistent<
const collection = this.collection();
// Get key from Collection
- if (!key && collection._key) return collection._key;
+ if (key == null && collection._key) return collection._key;
- if (!key) return;
+ if (key == null) return;
// Set Storage Key to Collection Key if Collection has no key
- if (!collection._key) collection._key = key;
+ if (collection._key == null) collection._key = key;
return key;
}
@@ -322,10 +322,10 @@ export class CollectionPersistent<
itemKey?: ItemKey,
collectionKey?: CollectionKey
): string {
- if (!itemKey || !collectionKey)
+ if (itemKey == null || collectionKey == null)
Agile.logger.warn('Failed to build unique Item StorageKey!');
- if (!itemKey) itemKey = 'unknown';
- if (!collectionKey) collectionKey = 'unknown';
+ if (itemKey == null) itemKey = 'unknown';
+ if (collectionKey == null) collectionKey = 'unknown';
return this.storageItemKeyPattern
.replace('${collectionKey}', collectionKey.toString())
.replace('${itemKey}', itemKey.toString());
@@ -344,10 +344,10 @@ export class CollectionPersistent<
groupKey?: GroupKey,
collectionKey?: CollectionKey
): string {
- if (!groupKey || !collectionKey)
+ if (groupKey == null || collectionKey == null)
Agile.logger.warn('Failed to build unique Group StorageKey!');
- if (!groupKey) groupKey = 'unknown';
- if (!collectionKey) collectionKey = 'unknown';
+ if (groupKey == null) groupKey = 'unknown';
+ if (collectionKey == null) collectionKey = 'unknown';
return this.storageGroupKeyPattern
.replace('${collectionKey}', collectionKey.toString())
diff --git a/packages/core/src/collection/group.ts b/packages/core/src/collection/group.ts
index 2863cf16..25895404 100644
--- a/packages/core/src/collection/group.ts
+++ b/packages/core/src/collection/group.ts
@@ -22,7 +22,7 @@ export class Group extends State<
Array
> {
static rebuildGroupSideEffectKey = 'rebuildGroup';
- collection: () => Collection;
+ collection: () => Collection; // Collection the Group belongs to
_output: Array = []; // Output of Group
_items: Array<() => Item> = []; // Items of Group
diff --git a/packages/core/src/collection/index.ts b/packages/core/src/collection/index.ts
index 36c557b6..9b7c096f 100644
--- a/packages/core/src/collection/index.ts
+++ b/packages/core/src/collection/index.ts
@@ -17,6 +17,7 @@ import {
generateId,
SideEffectConfigInterface,
SelectorConfigInterface,
+ removeProperties,
} from '../internal';
export class Collection {
@@ -129,7 +130,7 @@ export class Collection {
Agile.logger.warn(
"After the instantiation we recommend using 'MY_COLLECTION.createGroup' instead of 'MY_COLLECTION.Group'"
);
- if (!config?.key)
+ if (config?.key == null)
Agile.logger.warn(
`Failed to find key for creation of Group. Group with random key '${key}' got created!`
);
@@ -157,7 +158,7 @@ export class Collection {
Agile.logger.warn(
"After the instantiation we recommend using 'MY_COLLECTION.createSelector' instead of 'MY_COLLECTION.Selector'"
);
- if (!config?.key)
+ if (config?.key == null)
Agile.logger.warn(
`Failed to find key for creation of Selector. Selector with random key '${key}' got created!`
);
@@ -194,7 +195,7 @@ export class Collection {
// Set Key/Name of Group to property Name
for (const key in groupsObject)
- if (!groupsObject[key]._key) groupsObject[key].setKey(key);
+ if (groupsObject[key]._key == null) groupsObject[key].setKey(key);
this.groups = groupsObject;
}
@@ -225,7 +226,7 @@ export class Collection {
// Set Key/Name of Selector to property Name
for (const key in selectorsObject)
- if (!selectorsObject[key]._key) selectorsObject[key].setKey(key);
+ if (selectorsObject[key]._key == null) selectorsObject[key].setKey(key);
this.selectors = selectorsObject;
}
@@ -452,6 +453,17 @@ export class Collection {
return group;
}
+ //=========================================================================================================
+ // Get Default Group
+ //=========================================================================================================
+ /**
+ * @public
+ * Get default Group of Collection
+ */
+ public getDefaultGroup(): Group | undefined {
+ return this.getGroup(this.config.defaultGroupKey);
+ }
+
//=========================================================================================================
// Get Group With Reference
//=========================================================================================================
@@ -672,7 +684,7 @@ export class Collection {
});
// Get Item
- const item = itemKey ? this.data[itemKey] : undefined;
+ const item = itemKey != null ? this.data[itemKey] : undefined;
// Check if Item exists
if (!item || (!config.notExisting && !item.exists)) return undefined;
@@ -739,13 +751,17 @@ export class Collection {
notExisting: false,
});
- // Get Items
- const items: Array- > = [];
- for (const key in this.data) {
- const item = this.data[key];
- if ((!config.notExisting && item.exists) || config.notExisting) {
- items.push(item);
- }
+ const defaultGroup = this.getDefaultGroup();
+ let items: Array
- > = [];
+
+ // If config.notExisting transform this.data into array, otherwise return the default Group items
+ if (config.notExisting) {
+ for (const key in this.data) items.push(this.data[key]);
+ } else {
+ // Why defaultGroup Items and not all .exists === true Items?
+ // Because the default Group keeps track of all existing Items
+ // It also does control the Collection output in useAgile() and should do it here too
+ items = defaultGroup?.items || [];
}
return items;
@@ -916,6 +932,37 @@ export class Collection {
return this;
}
+ //=========================================================================================================
+ // Move
+ //=========================================================================================================
+ /**
+ * @public
+ * Move ItemKey/s from one Group to another
+ * @param itemKeys - ItemKey/s that are moved
+ * @param oldGroupKey - GroupKey of the Group that currently keeps the Items
+ * @param newGroupKey - GroupKey of the Group into which the Items should be moved
+ * @param config - Config
+ */
+ public move(
+ itemKeys: ItemKey | Array,
+ oldGroupKey: GroupKey,
+ newGroupKey: GroupKey,
+ config: GroupAddConfigInterface = {}
+ ): this {
+ const _itemKeys = normalizeArray(itemKeys);
+
+ // Remove itemKeys from old Group
+ this.getGroup(oldGroupKey)?.remove(
+ _itemKeys,
+ removeProperties(config, ['method', 'overwrite'])
+ );
+
+ // Add itemKeys to new Group
+ this.getGroup(newGroupKey)?.add(_itemKeys, config);
+
+ return this;
+ }
+
//=========================================================================================================
// Update Item Key
//=========================================================================================================
diff --git a/packages/core/src/collection/item.ts b/packages/core/src/collection/item.ts
index 7411c8c2..0930064e 100644
--- a/packages/core/src/collection/item.ts
+++ b/packages/core/src/collection/item.ts
@@ -33,7 +33,9 @@ export class Item extends State<
this.collection = () => collection;
// Add rebuildGroupsThatIncludeItemKey to sideEffects to rebuild Groups that include this Item if it mutates
- this.addRebuildGroupThatIncludeItemKeySideEffect(this._key || 'unknown');
+ this.addRebuildGroupThatIncludeItemKeySideEffect(
+ this._key != null ? this._key : 'unknown'
+ );
}
//=========================================================================================================
@@ -60,7 +62,7 @@ export class Item extends State<
storage: true,
overwrite: false,
});
- if (!value) return this;
+ if (value == null) return this;
// Remove old rebuildGroupsThatIncludeItemKey sideEffect
this.removeSideEffect(Item.updateGroupSideEffectKey);
diff --git a/packages/core/src/runtime/index.ts b/packages/core/src/runtime/index.ts
index d59bc7ff..9da95968 100644
--- a/packages/core/src/runtime/index.ts
+++ b/packages/core/src/runtime/index.ts
@@ -274,7 +274,7 @@ export class Runtime {
let newValue = job.observer.value;
let newValueDeepness = 0;
for (const branch of path) {
- if (!isValidObject(newValue)) break;
+ if (!isValidObject(newValue, true)) break;
newValue = newValue[branch];
newValueDeepness++;
}
@@ -283,7 +283,7 @@ export class Runtime {
let previousValue = job.observer.previousValue;
let previousValueDeepness = 0;
for (const branch of path) {
- if (!isValidObject(previousValue)) break;
+ if (!isValidObject(previousValue, true)) break;
previousValue = previousValue[branch];
previousValueDeepness++;
}
diff --git a/packages/core/src/runtime/observer.ts b/packages/core/src/runtime/observer.ts
index 85262bc8..b54d65e1 100644
--- a/packages/core/src/runtime/observer.ts
+++ b/packages/core/src/runtime/observer.ts
@@ -15,7 +15,7 @@ export class Observer {
public _key?: ObserverKey;
public dependents: Set = new Set(); // Observers that depend on this Observer
- public subs: Set = new Set(); // SubscriptionContainers (Components) that this Observer has subscribed
+ public subscribedTo: Set = new Set(); // SubscriptionContainers (Components) that this Observer is subscribed to
public value?: ValueType; // Value of Observer
public previousValue?: ValueType; // Previous Value of Observer
@@ -127,11 +127,11 @@ export class Observer {
* @param subscriptionContainer - SubscriptionContainer(Component) that gets subscribed by this Observer
*/
public subscribe(subscriptionContainer: SubscriptionContainer): void {
- if (!this.subs.has(subscriptionContainer)) {
- this.subs.add(subscriptionContainer);
+ if (!this.subscribedTo.has(subscriptionContainer)) {
+ this.subscribedTo.add(subscriptionContainer);
// Add this to subscriptionContainer to keep track of the Observers the subscriptionContainer hold
- subscriptionContainer.subs.add(this);
+ subscriptionContainer.subscribers.add(this);
}
}
@@ -144,9 +144,9 @@ export class Observer {
* @param subscriptionContainer - SubscriptionContainer(Component) that gets unsubscribed by this Observer
*/
public unsubscribe(subscriptionContainer: SubscriptionContainer): void {
- if (this.subs.has(subscriptionContainer)) {
- this.subs.delete(subscriptionContainer);
- subscriptionContainer.subs.delete(this);
+ if (this.subscribedTo.has(subscriptionContainer)) {
+ this.subscribedTo.delete(subscriptionContainer);
+ subscriptionContainer.subscribers.delete(this);
}
}
}
diff --git a/packages/core/src/runtime/runtime.job.ts b/packages/core/src/runtime/runtime.job.ts
index fda25478..a3e559ea 100644
--- a/packages/core/src/runtime/runtime.job.ts
+++ b/packages/core/src/runtime/runtime.job.ts
@@ -39,7 +39,7 @@ export class RuntimeJob {
!config.background &&
this.observer.agileInstance().integrations.hasIntegration();
this._key = config.key;
- this.subscriptionContainersToUpdate = new Set(observer.subs);
+ this.subscriptionContainersToUpdate = new Set(observer.subscribedTo);
}
public get key(): RuntimeJobKey | undefined {
diff --git a/packages/core/src/runtime/subscription/container/SubscriptionContainer.ts b/packages/core/src/runtime/subscription/container/SubscriptionContainer.ts
index 3a4c5b7f..ef7c7bb5 100644
--- a/packages/core/src/runtime/subscription/container/SubscriptionContainer.ts
+++ b/packages/core/src/runtime/subscription/container/SubscriptionContainer.ts
@@ -8,7 +8,8 @@ import {
export class SubscriptionContainer {
public key?: SubscriptionContainerKeyType;
public ready = false;
- public subs: Set; // Observers that are Subscribed to this SubscriptionContainer (Component)
+
+ public subscribers: Set; // Observers that are Subscribed to this SubscriptionContainer (Component)
// Represents the paths to the accessed properties of the State/s this SubscriptionContainer represents
public proxyKeyMap: ProxyKeyMapInterface;
@@ -35,7 +36,7 @@ export class SubscriptionContainer {
key: generateId(),
});
- this.subs = new Set(subs);
+ this.subscribers = new Set(subs);
this.key = config.key;
this.proxyKeyMap = config.proxyKeyMap as any;
this.proxyBased = notEqual(this.proxyKeyMap, {});
diff --git a/packages/core/src/runtime/subscription/sub.controller.ts b/packages/core/src/runtime/subscription/sub.controller.ts
index ba3e0318..2cd6ba17 100644
--- a/packages/core/src/runtime/subscription/sub.controller.ts
+++ b/packages/core/src/runtime/subscription/sub.controller.ts
@@ -116,7 +116,7 @@ export class SubController {
subscriptionContainer.ready = false;
// Remove SubscriptionContainers from Observer
- subscriptionContainer.subs.forEach((observer) => {
+ subscriptionContainer.subscribers.forEach((observer) => {
observer.unsubscribe(subscriptionContainer);
});
};
diff --git a/packages/core/src/state/index.ts b/packages/core/src/state/index.ts
index 9a057357..d708183a 100644
--- a/packages/core/src/state/index.ts
+++ b/packages/core/src/state/index.ts
@@ -253,14 +253,14 @@ export class State {
addNewProperties: true,
});
- if (!isValidObject(this.nextStateValue)) {
+ if (!isValidObject(this.nextStateValue, true)) {
Agile.logger.error(
"You can't use the patch method on a non object based States!"
);
return this;
}
- if (!isValidObject(targetWithChanges)) {
+ if (!isValidObject(targetWithChanges, true)) {
Agile.logger.error('TargetWithChanges has to be an Object!');
return this;
}
@@ -674,7 +674,7 @@ export class State {
* Returns public Value of State
*/
public getPublicValue(): ValueType {
- // If State Value is used internal and output represents the real state value (for instance in Group)
+ // If State Value is used internally and output represents the real state value (for instance in Group)
if (this['output'] !== undefined) return this['output'];
return this._value;
diff --git a/packages/core/tests/unit/collection/collection.test.ts b/packages/core/tests/unit/collection/collection.test.ts
index 1bb68db5..cfced39f 100644
--- a/packages/core/tests/unit/collection/collection.test.ts
+++ b/packages/core/tests/unit/collection/collection.test.ts
@@ -1046,6 +1046,20 @@ describe('Collection Tests', () => {
});
});
+ describe('getDefaultGroup function tests', () => {
+ it('should return default Group', () => {
+ jest
+ .spyOn(collection, 'getGroup')
+ .mockReturnValueOnce('fakeGroup' as any);
+ const response = collection.getDefaultGroup();
+
+ expect(collection.getGroup).toHaveBeenCalledWith(
+ collection.config.defaultGroupKey
+ );
+ expect(response).toBe('fakeGroup');
+ });
+ });
+
describe('getGroupWithReference function tests', () => {
let dummyGroup: Group;
@@ -1515,6 +1529,8 @@ describe('Collection Tests', () => {
['2']: dummyItem2,
['3']: dummyItem3,
};
+
+ collection.getDefaultGroup()?.add(['1', '2', '3']);
});
it('should return all existing Items (default config)', () => {
@@ -1552,6 +1568,8 @@ describe('Collection Tests', () => {
['3']: dummyItem3,
};
+ collection.getDefaultGroup()?.add(['1', '2', '3']);
+
jest.spyOn(collection, 'getAllItems');
});
@@ -1798,6 +1816,55 @@ describe('Collection Tests', () => {
});
});
+ describe('move function tests', () => {
+ let dummyGroup1: Group;
+ let dummyGroup2: Group;
+
+ beforeEach(() => {
+ dummyGroup1 = new Group(collection, [], { key: 'dummyGroup1' });
+ dummyGroup2 = new Group(collection, ['1', '2', '3'], {
+ key: 'dummyGroup2',
+ });
+ collection.groups = {
+ dummyGroup1: dummyGroup1,
+ dummyGroup2: dummyGroup2,
+ };
+
+ dummyGroup1.add = jest.fn();
+ dummyGroup1.remove = jest.fn();
+ dummyGroup2.add = jest.fn();
+ dummyGroup2.remove = jest.fn();
+ });
+
+ it('should remove passed itemKey/s from old Group and add it to the new one (default config)', () => {
+ collection.move('1', 'dummyGroup2', 'dummyGroup1');
+
+ expect(dummyGroup1.add).toHaveBeenCalledWith(['1'], {});
+ expect(dummyGroup1.remove).not.toHaveBeenCalled();
+ expect(dummyGroup2.add).not.toHaveBeenCalled();
+ expect(dummyGroup2.remove).toHaveBeenCalledWith(['1'], {});
+ });
+
+ it('should remove passed itemKey/s from old Group and add it to the new one (specific config)', () => {
+ collection.move('1', 'dummyGroup2', 'dummyGroup1', {
+ background: true,
+ overwrite: true,
+ method: 'push',
+ });
+
+ expect(dummyGroup1.add).toHaveBeenCalledWith(['1'], {
+ background: true,
+ overwrite: true,
+ method: 'push',
+ });
+ expect(dummyGroup1.remove).not.toHaveBeenCalled();
+ expect(dummyGroup2.add).not.toHaveBeenCalled();
+ expect(dummyGroup2.remove).toHaveBeenCalledWith(['1'], {
+ background: true,
+ });
+ });
+ });
+
describe('updateItemKey function tests', () => {
let dummySelector1: Selector;
let dummySelector2: Selector;
diff --git a/packages/core/tests/unit/runtime/observer.test.ts b/packages/core/tests/unit/runtime/observer.test.ts
index cffcf09e..47b6bdf0 100644
--- a/packages/core/tests/unit/runtime/observer.test.ts
+++ b/packages/core/tests/unit/runtime/observer.test.ts
@@ -34,7 +34,7 @@ describe('Observer Tests', () => {
expect(observer.value).toBeUndefined();
expect(observer.previousValue).toBeUndefined();
expect(observer.dependents.size).toBe(0);
- expect(observer.subs.size).toBe(0);
+ expect(observer.subscribedTo.size).toBe(0);
});
it('should create Observer (specific config)', () => {
@@ -51,9 +51,9 @@ describe('Observer Tests', () => {
expect(observer.dependents.size).toBe(2);
expect(observer.dependents.has(dummyObserver2)).toBeTruthy();
expect(observer.dependents.has(dummyObserver1)).toBeTruthy();
- expect(observer.subs.size).toBe(2);
- expect(observer.subs.has(dummySubscription1)).toBeTruthy();
- expect(observer.subs.has(dummySubscription2)).toBeTruthy();
+ expect(observer.subscribedTo.size).toBe(2);
+ expect(observer.subscribedTo.has(dummySubscription1)).toBeTruthy();
+ expect(observer.subscribedTo.has(dummySubscription2)).toBeTruthy();
expect(observer.subscribe).toHaveBeenCalledWith(dummySubscription1);
expect(observer.subscribe).toHaveBeenCalledWith(dummySubscription2);
@@ -187,10 +187,12 @@ describe('Observer Tests', () => {
it('should add subscriptionContainer to subs and this(Observer) to SubscriptionContainer subs', () => {
observer.subscribe(dummySubscriptionContainer1);
- expect(observer.subs.size).toBe(1);
- expect(observer.subs.has(dummySubscriptionContainer1));
- expect(dummySubscriptionContainer1.subs.size).toBe(1);
- expect(dummySubscriptionContainer1.subs.has(observer)).toBeTruthy();
+ expect(observer.subscribedTo.size).toBe(1);
+ expect(observer.subscribedTo.has(dummySubscriptionContainer1));
+ expect(dummySubscriptionContainer1.subscribers.size).toBe(1);
+ expect(
+ dummySubscriptionContainer1.subscribers.has(observer)
+ ).toBeTruthy();
});
it("shouldn't add same subscriptionContainer twice to subs", () => {
@@ -198,10 +200,12 @@ describe('Observer Tests', () => {
observer.subscribe(dummySubscriptionContainer1);
- expect(observer.subs.size).toBe(1);
- expect(observer.subs.has(dummySubscriptionContainer1));
- expect(dummySubscriptionContainer1.subs.size).toBe(1);
- expect(dummySubscriptionContainer1.subs.has(observer)).toBeTruthy();
+ expect(observer.subscribedTo.size).toBe(1);
+ expect(observer.subscribedTo.has(dummySubscriptionContainer1));
+ expect(dummySubscriptionContainer1.subscribers.size).toBe(1);
+ expect(
+ dummySubscriptionContainer1.subscribers.has(observer)
+ ).toBeTruthy();
});
});
@@ -219,11 +223,13 @@ describe('Observer Tests', () => {
it('should remove subscriptionContainer from subs and this(Observer) from SubscriptionContainer subs', () => {
observer.unsubscribe(dummySubscriptionContainer1);
- expect(observer.subs.size).toBe(1);
- expect(observer.subs.has(dummySubscriptionContainer1));
- expect(dummySubscriptionContainer1.subs.size).toBe(0);
- expect(dummySubscriptionContainer2.subs.size).toBe(1);
- expect(dummySubscriptionContainer2.subs.has(observer)).toBeTruthy();
+ expect(observer.subscribedTo.size).toBe(1);
+ expect(observer.subscribedTo.has(dummySubscriptionContainer1));
+ expect(dummySubscriptionContainer1.subscribers.size).toBe(0);
+ expect(dummySubscriptionContainer2.subscribers.size).toBe(1);
+ expect(
+ dummySubscriptionContainer2.subscribers.has(observer)
+ ).toBeTruthy();
});
});
});
diff --git a/packages/core/tests/unit/runtime/runtime.test.ts b/packages/core/tests/unit/runtime/runtime.test.ts
index 7e58ff0f..8e51cb0b 100644
--- a/packages/core/tests/unit/runtime/runtime.test.ts
+++ b/packages/core/tests/unit/runtime/runtime.test.ts
@@ -284,7 +284,7 @@ describe('Runtime Tests', () => {
rComponentSubJob
);
expect(rComponentSubJob.subscriptionContainersToUpdate.size).toBe(0);
- expect(dummyObserver3.subs.size).toBe(1);
+ expect(dummyObserver3.subscribedTo.size).toBe(1);
expect(response).toBeTruthy();
});
@@ -301,7 +301,7 @@ describe('Runtime Tests', () => {
expect(rCallbackSubContainer.callback).toHaveBeenCalledTimes(1);
expect(rCallbackSubJob.subscriptionContainersToUpdate.size).toBe(0);
- expect(dummyObserver1.subs.size).toBe(1);
+ expect(dummyObserver1.subscribedTo.size).toBe(1);
expect(response).toBeTruthy();
});
@@ -326,7 +326,7 @@ describe('Runtime Tests', () => {
expect(rCallbackSubContainer.callback).toHaveBeenCalledTimes(1);
expect(rCallbackSubJob.subscriptionContainersToUpdate.size).toBe(0);
- expect(dummyObserver1.subs.size).toBe(1);
+ expect(dummyObserver1.subscribedTo.size).toBe(1);
expect(response).toBeTruthy();
});
@@ -351,7 +351,7 @@ describe('Runtime Tests', () => {
expect(rCallbackSubContainer.callback).not.toHaveBeenCalled();
expect(rCallbackSubJob.subscriptionContainersToUpdate.size).toBe(0);
- expect(dummyObserver1.subs.size).toBe(1);
+ expect(dummyObserver1.subscribedTo.size).toBe(1);
expect(response).toBeFalsy();
});
@@ -402,8 +402,8 @@ describe('Runtime Tests', () => {
}
);
- expect(dummyObserver2.subs.size).toBe(2);
- expect(dummyObserver4.subs.size).toBe(2);
+ expect(dummyObserver2.subscribedTo.size).toBe(2);
+ expect(dummyObserver4.subscribedTo.size).toBe(2);
expect(runtime.handleObjectBasedSubscription).toHaveBeenCalledWith(
rComponentSubContainer,
@@ -440,7 +440,7 @@ describe('Runtime Tests', () => {
expect(rCallbackSubContainer.callback).toHaveBeenCalled();
expect(rCallbackSubJob.subscriptionContainersToUpdate.size).toBe(0);
- expect(dummyObserver1.subs.size).toBe(1);
+ expect(dummyObserver1.subscribedTo.size).toBe(1);
expect(response).toBeTruthy();
});
@@ -467,7 +467,7 @@ describe('Runtime Tests', () => {
rCallbackSubContainer
)
).toBeTruthy();
- expect(dummyObserver1.subs.size).toBe(1);
+ expect(dummyObserver1.subscribedTo.size).toBe(1);
expect(rCallbackSubJob.triesToUpdate).toBe(2);
expect(console.warn).toHaveBeenCalledWith(
@@ -504,7 +504,7 @@ describe('Runtime Tests', () => {
rCallbackSubContainer
)
).toBeTruthy();
- expect(dummyObserver1.subs.size).toBe(1);
+ expect(dummyObserver1.subscribedTo.size).toBe(1);
expect(rCallbackSubJob.triesToUpdate).toBe(3);
expect(console.warn).toHaveBeenCalledWith(
@@ -608,14 +608,21 @@ describe('Runtime Tests', () => {
});
describe('handleProxyBasedSubscription function tests', () => {
- let subscriptionContainer: SubscriptionContainer;
+ let objectSubscriptionContainer: SubscriptionContainer;
const dummyFunction = () => {
/* empty function */
};
- let dummyJob: RuntimeJob;
+ let objectJob: RuntimeJob;
+
+ let arraySubscriptionContainer: SubscriptionContainer;
+ const dummyFunction2 = () => {
+ /* empty function */
+ };
+ let arrayJob: RuntimeJob;
beforeEach(() => {
- subscriptionContainer = dummyAgile.subController.subscribeWithSubsObject(
+ // Create Job with Object value
+ objectSubscriptionContainer = dummyAgile.subController.subscribeWithSubsObject(
dummyFunction,
{ observer1: dummyObserver1 }
).subscriptionContainer;
@@ -627,12 +634,46 @@ describe('Runtime Tests', () => {
key: 'dummyObserverValue1',
data: { name: 'jeff' },
};
- subscriptionContainer.proxyBased = true;
- subscriptionContainer.proxyKeyMap = {
+ objectSubscriptionContainer.proxyBased = true;
+ objectSubscriptionContainer.proxyKeyMap = {
[dummyObserver1._key || 'unknown']: { paths: [['data', 'name']] },
};
- dummyJob = new RuntimeJob(dummyObserver1, { key: 'dummyObjectJob1' });
+ objectJob = new RuntimeJob(dummyObserver1, { key: 'dummyObjectJob1' });
+
+ // Create Job with Array value
+ arraySubscriptionContainer = dummyAgile.subController.subscribeWithSubsObject(
+ dummyFunction2,
+ { observer2: dummyObserver2 }
+ ).subscriptionContainer;
+ dummyObserver2.value = [
+ {
+ key: 'dummyObserver2Value1',
+ data: { name: 'jeff' },
+ },
+ {
+ key: 'dummyObserver2Value2',
+ data: { name: 'hans' },
+ },
+ ];
+ dummyObserver2.previousValue = [
+ {
+ key: 'dummyObserver2Value1',
+ data: { name: 'jeff' },
+ },
+ {
+ key: 'dummyObserver2Value2',
+ data: { name: 'hans' },
+ },
+ ];
+ arraySubscriptionContainer.proxyBased = true;
+ arraySubscriptionContainer.proxyKeyMap = {
+ [dummyObserver2._key || 'unknown']: {
+ paths: [['0', 'data', 'name']],
+ },
+ };
+
+ arrayJob = new RuntimeJob(dummyObserver2, { key: 'dummyObjectJob2' });
jest.spyOn(Utils, 'notEqual');
@@ -641,11 +682,11 @@ describe('Runtime Tests', () => {
});
it("should return true if subscriptionContainer isn't proxy based", () => {
- subscriptionContainer.proxyBased = false;
+ objectSubscriptionContainer.proxyBased = false;
const response = runtime.handleProxyBasedSubscription(
- subscriptionContainer,
- dummyJob
+ objectSubscriptionContainer,
+ objectJob
);
expect(response).toBeTruthy();
@@ -653,11 +694,11 @@ describe('Runtime Tests', () => {
});
it('should return true if observer the job represents has no key', () => {
- dummyJob.observer._key = undefined;
+ objectJob.observer._key = undefined;
const response = runtime.handleProxyBasedSubscription(
- subscriptionContainer,
- dummyJob
+ objectSubscriptionContainer,
+ objectJob
);
expect(response).toBeTruthy();
@@ -665,28 +706,28 @@ describe('Runtime Tests', () => {
});
it("should return true if the observer key isn't represented in the proxyKeyMap", () => {
- subscriptionContainer.proxyKeyMap = {
+ objectSubscriptionContainer.proxyKeyMap = {
unknownKey: { paths: [['a', 'b']] },
};
const response = runtime.handleProxyBasedSubscription(
- subscriptionContainer,
- dummyJob
+ objectSubscriptionContainer,
+ objectJob
);
expect(response).toBeTruthy();
expect(Utils.notEqual).not.toHaveBeenCalled();
});
- it('should return true if used property has changed', () => {
+ it('should return true if used property has changed (object value)', () => {
dummyObserver1.value = {
key: 'dummyObserverValue1',
data: { name: 'hans' },
};
const response = runtime.handleProxyBasedSubscription(
- subscriptionContainer,
- dummyJob
+ objectSubscriptionContainer,
+ objectJob
);
expect(response).toBeTruthy();
@@ -696,10 +737,10 @@ describe('Runtime Tests', () => {
);
});
- it("should return false if used property hasn't changed", () => {
+ it("should return false if used property hasn't changed (object value)", () => {
const response = runtime.handleProxyBasedSubscription(
- subscriptionContainer,
- dummyJob
+ objectSubscriptionContainer,
+ objectJob
);
expect(response).toBeFalsy();
@@ -709,7 +750,7 @@ describe('Runtime Tests', () => {
);
});
- it('should return true if used property has changed in the deepness', () => {
+ it('should return true if used property has changed in the deepness (object value)', () => {
dummyObserver1.value = {
key: 'dummyObserverValue1',
};
@@ -719,13 +760,50 @@ describe('Runtime Tests', () => {
};
const response = runtime.handleProxyBasedSubscription(
- subscriptionContainer,
- dummyJob
+ objectSubscriptionContainer,
+ objectJob
);
expect(response).toBeTruthy();
expect(Utils.notEqual).toHaveBeenCalledWith(undefined, undefined);
});
+
+ it('should return true if used property has changed (array value)', () => {
+ dummyObserver2.value = [
+ {
+ key: 'dummyObserver2Value1',
+ data: { name: 'frank' },
+ },
+ {
+ key: 'dummyObserver2Value2',
+ data: { name: 'hans' },
+ },
+ ];
+
+ const response = runtime.handleProxyBasedSubscription(
+ arraySubscriptionContainer,
+ arrayJob
+ );
+
+ expect(response).toBeTruthy();
+ expect(Utils.notEqual).toHaveBeenCalledWith(
+ dummyObserver2.value['0'].data.name,
+ dummyObserver2.previousValue['0'].data.name
+ );
+ });
+
+ it("should return false if used property hasn't changed (array value)", () => {
+ const response = runtime.handleProxyBasedSubscription(
+ arraySubscriptionContainer,
+ arrayJob
+ );
+
+ expect(response).toBeFalsy();
+ expect(Utils.notEqual).toHaveBeenCalledWith(
+ dummyObserver2.value['0'].data.name,
+ dummyObserver2.previousValue['0'].data.name
+ );
+ });
});
});
});
diff --git a/packages/core/tests/unit/runtime/subscription/container/CallbackSubscriptionContainer.test.ts b/packages/core/tests/unit/runtime/subscription/container/CallbackSubscriptionContainer.test.ts
index 8d90bdcf..21347250 100644
--- a/packages/core/tests/unit/runtime/subscription/container/CallbackSubscriptionContainer.test.ts
+++ b/packages/core/tests/unit/runtime/subscription/container/CallbackSubscriptionContainer.test.ts
@@ -34,9 +34,9 @@ describe('CallbackSubscriptionContainer Tests', () => {
expect(subscriptionContainer.key).toBe('dummyKey');
expect(subscriptionContainer.ready).toBeFalsy();
- expect(subscriptionContainer.subs.size).toBe(2);
- expect(subscriptionContainer.subs.has(dummyObserver1)).toBeTruthy();
- expect(subscriptionContainer.subs.has(dummyObserver2)).toBeTruthy();
+ expect(subscriptionContainer.subscribers.size).toBe(2);
+ expect(subscriptionContainer.subscribers.has(dummyObserver1)).toBeTruthy();
+ expect(subscriptionContainer.subscribers.has(dummyObserver2)).toBeTruthy();
expect(subscriptionContainer.isObjectBased).toBeFalsy();
expect(subscriptionContainer.observerKeysToUpdate).toStrictEqual([]);
expect(subscriptionContainer.subsObject).toBeUndefined();
diff --git a/packages/core/tests/unit/runtime/subscription/container/ComponentSubscriptionContainer.test.ts b/packages/core/tests/unit/runtime/subscription/container/ComponentSubscriptionContainer.test.ts
index 457a97c5..0422f265 100644
--- a/packages/core/tests/unit/runtime/subscription/container/ComponentSubscriptionContainer.test.ts
+++ b/packages/core/tests/unit/runtime/subscription/container/ComponentSubscriptionContainer.test.ts
@@ -32,9 +32,9 @@ describe('ComponentSubscriptionContainer Tests', () => {
expect(subscriptionContainer.key).toBe('dummyKey');
expect(subscriptionContainer.ready).toBeFalsy();
- expect(subscriptionContainer.subs.size).toBe(2);
- expect(subscriptionContainer.subs.has(dummyObserver1)).toBeTruthy();
- expect(subscriptionContainer.subs.has(dummyObserver2)).toBeTruthy();
+ expect(subscriptionContainer.subscribers.size).toBe(2);
+ expect(subscriptionContainer.subscribers.has(dummyObserver1)).toBeTruthy();
+ expect(subscriptionContainer.subscribers.has(dummyObserver2)).toBeTruthy();
expect(subscriptionContainer.isObjectBased).toBeFalsy();
expect(subscriptionContainer.observerKeysToUpdate).toStrictEqual([]);
expect(subscriptionContainer.subsObject).toBeUndefined();
diff --git a/packages/core/tests/unit/runtime/subscription/container/SubscriptionContainer.test.ts b/packages/core/tests/unit/runtime/subscription/container/SubscriptionContainer.test.ts
index 59e05152..f0cb899e 100644
--- a/packages/core/tests/unit/runtime/subscription/container/SubscriptionContainer.test.ts
+++ b/packages/core/tests/unit/runtime/subscription/container/SubscriptionContainer.test.ts
@@ -23,7 +23,7 @@ describe('SubscriptionContainer Tests', () => {
expect(subscriptionContainer.key).toBe('generatedId');
expect(subscriptionContainer.ready).toBeFalsy();
- expect(subscriptionContainer.subs.size).toBe(0);
+ expect(subscriptionContainer.subscribers.size).toBe(0);
expect(subscriptionContainer.isObjectBased).toBeFalsy();
expect(subscriptionContainer.observerKeysToUpdate).toStrictEqual([]);
expect(subscriptionContainer.subsObject).toBeUndefined();
@@ -39,9 +39,9 @@ describe('SubscriptionContainer Tests', () => {
expect(subscriptionContainer.key).toBe('dummyKey');
expect(subscriptionContainer.ready).toBeFalsy();
- expect(subscriptionContainer.subs.size).toBe(2);
- expect(subscriptionContainer.subs.has(dummyObserver1)).toBeTruthy();
- expect(subscriptionContainer.subs.has(dummyObserver2)).toBeTruthy();
+ expect(subscriptionContainer.subscribers.size).toBe(2);
+ expect(subscriptionContainer.subscribers.has(dummyObserver1)).toBeTruthy();
+ expect(subscriptionContainer.subscribers.has(dummyObserver2)).toBeTruthy();
expect(subscriptionContainer.isObjectBased).toBeFalsy();
expect(subscriptionContainer.observerKeysToUpdate).toStrictEqual([]);
expect(subscriptionContainer.subsObject).toBeUndefined();
diff --git a/packages/core/tests/unit/runtime/subscription/sub.controller.test.ts b/packages/core/tests/unit/runtime/subscription/sub.controller.test.ts
index b7027ac6..d0234195 100644
--- a/packages/core/tests/unit/runtime/subscription/sub.controller.test.ts
+++ b/packages/core/tests/unit/runtime/subscription/sub.controller.test.ts
@@ -82,12 +82,12 @@ describe('SubController Tests', () => {
dummyObserver2: dummyObserver2,
});
- expect(dummySubscriptionContainer.subs.size).toBe(2);
+ expect(dummySubscriptionContainer.subscribers.size).toBe(2);
expect(
- dummySubscriptionContainer.subs.has(dummyObserver1)
+ dummySubscriptionContainer.subscribers.has(dummyObserver1)
).toBeTruthy();
expect(
- dummySubscriptionContainer.subs.has(dummyObserver2)
+ dummySubscriptionContainer.subscribers.has(dummyObserver2)
).toBeTruthy();
expect(dummyObserver1.subscribe).toHaveBeenCalledWith(
@@ -133,12 +133,12 @@ describe('SubController Tests', () => {
expect(dummySubscriptionContainer.isObjectBased).toBeFalsy();
expect(dummySubscriptionContainer.subsObject).toBeUndefined();
- expect(dummySubscriptionContainer.subs.size).toBe(2);
+ expect(dummySubscriptionContainer.subscribers.size).toBe(2);
expect(
- dummySubscriptionContainer.subs.has(dummyObserver1)
+ dummySubscriptionContainer.subscribers.has(dummyObserver1)
).toBeTruthy();
expect(
- dummySubscriptionContainer.subs.has(dummyObserver2)
+ dummySubscriptionContainer.subscribers.has(dummyObserver2)
).toBeTruthy();
expect(dummyObserver1.subscribe).toHaveBeenCalledWith(
@@ -334,12 +334,12 @@ describe('SubController Tests', () => {
);
expect(componentSubscriptionContainer.ready).toBeTruthy();
- expect(componentSubscriptionContainer.subs.size).toBe(2);
+ expect(componentSubscriptionContainer.subscribers.size).toBe(2);
expect(
- componentSubscriptionContainer.subs.has(dummyObserver1)
+ componentSubscriptionContainer.subscribers.has(dummyObserver1)
).toBeTruthy();
expect(
- componentSubscriptionContainer.subs.has(dummyObserver2)
+ componentSubscriptionContainer.subscribers.has(dummyObserver2)
).toBeTruthy();
expect(subController.componentSubs.size).toBe(1);
@@ -372,12 +372,12 @@ describe('SubController Tests', () => {
);
expect(componentSubscriptionContainer.ready).toBeTruthy();
- expect(componentSubscriptionContainer.subs.size).toBe(2);
+ expect(componentSubscriptionContainer.subscribers.size).toBe(2);
expect(
- componentSubscriptionContainer.subs.has(dummyObserver1)
+ componentSubscriptionContainer.subscribers.has(dummyObserver1)
).toBeTruthy();
expect(
- componentSubscriptionContainer.subs.has(dummyObserver2)
+ componentSubscriptionContainer.subscribers.has(dummyObserver2)
).toBeTruthy();
expect(subController.componentSubs.size).toBe(1);
@@ -445,12 +445,12 @@ describe('SubController Tests', () => {
expect(callbackSubscriptionContainer.callback).toBe(dummyIntegration);
expect(callbackSubscriptionContainer.ready).toBeTruthy();
- expect(callbackSubscriptionContainer.subs.size).toBe(2);
+ expect(callbackSubscriptionContainer.subscribers.size).toBe(2);
expect(
- callbackSubscriptionContainer.subs.has(dummyObserver1)
+ callbackSubscriptionContainer.subscribers.has(dummyObserver1)
).toBeTruthy();
expect(
- callbackSubscriptionContainer.subs.has(dummyObserver2)
+ callbackSubscriptionContainer.subscribers.has(dummyObserver2)
).toBeTruthy();
expect(subController.callbackSubs.size).toBe(1);
diff --git a/packages/core/tests/unit/state/state.observer.test.ts b/packages/core/tests/unit/state/state.observer.test.ts
index 36a5db35..9bab6b28 100644
--- a/packages/core/tests/unit/state/state.observer.test.ts
+++ b/packages/core/tests/unit/state/state.observer.test.ts
@@ -32,7 +32,7 @@ describe('StateObserver Tests', () => {
expect(stateObserver.previousValue).toBe('dummyValue');
expect(stateObserver._key).toBeUndefined();
expect(stateObserver.dependents.size).toBe(0);
- expect(stateObserver.subs.size).toBe(0);
+ expect(stateObserver.subscribedTo.size).toBe(0);
});
it('should create StateObserver (specific config)', () => {
@@ -56,9 +56,9 @@ describe('StateObserver Tests', () => {
expect(stateObserver.dependents.size).toBe(2);
expect(stateObserver.dependents.has(dummyObserver2)).toBeTruthy();
expect(stateObserver.dependents.has(dummyObserver1)).toBeTruthy();
- expect(stateObserver.subs.size).toBe(2);
- expect(stateObserver.subs.has(dummySubscription1)).toBeTruthy();
- expect(stateObserver.subs.has(dummySubscription2)).toBeTruthy();
+ expect(stateObserver.subscribedTo.size).toBe(2);
+ expect(stateObserver.subscribedTo.has(dummySubscription1)).toBeTruthy();
+ expect(stateObserver.subscribedTo.has(dummySubscription2)).toBeTruthy();
});
describe('StateObserver Function Tests', () => {
diff --git a/packages/event/tests/unit/event.observer.test.ts b/packages/event/tests/unit/event.observer.test.ts
index b4afa6ea..be77973c 100644
--- a/packages/event/tests/unit/event.observer.test.ts
+++ b/packages/event/tests/unit/event.observer.test.ts
@@ -22,7 +22,7 @@ describe('EventObserver Tests', () => {
expect(eventObserver.value).toBeUndefined();
expect(eventObserver._key).toBeUndefined();
expect(eventObserver.dependents.size).toBe(0);
- expect(eventObserver.subs.size).toBe(0);
+ expect(eventObserver.subscribedTo.size).toBe(0);
});
it('should create EventObserver (specific config)', () => {
@@ -44,9 +44,9 @@ describe('EventObserver Tests', () => {
expect(eventObserver.dependents.size).toBe(2);
expect(eventObserver.dependents.has(dummyObserver2)).toBeTruthy();
expect(eventObserver.dependents.has(dummyObserver1)).toBeTruthy();
- expect(eventObserver.subs.size).toBe(2);
- expect(eventObserver.subs.has(dummySubscription1)).toBeTruthy();
- expect(eventObserver.subs.has(dummySubscription2)).toBeTruthy();
+ expect(eventObserver.subscribedTo.size).toBe(2);
+ expect(eventObserver.subscribedTo.has(dummySubscription1)).toBeTruthy();
+ expect(eventObserver.subscribedTo.has(dummySubscription2)).toBeTruthy();
});
describe('EventObserver Function Tests', () => {
diff --git a/packages/react/src/hooks/useAgile.ts b/packages/react/src/hooks/useAgile.ts
index ef424538..d8b4d210 100644
--- a/packages/react/src/hooks/useAgile.ts
+++ b/packages/react/src/hooks/useAgile.ts
@@ -65,10 +65,16 @@ export function useAgile<
const depKey = dep?.key;
// If proxyBased and value is object wrap Proxy around it to track used properties
- if (config.proxyBased && isValidObject(value, true) && depKey) {
- const proxyTree = new ProxyTree(value);
- proxyTreeMap[depKey] = proxyTree;
- return proxyTree.proxy;
+ if (config.proxyBased && isValidObject(value, true)) {
+ if (depKey) {
+ const proxyTree = new ProxyTree(value);
+ proxyTreeMap[depKey] = proxyTree;
+ return proxyTree.proxy;
+ }
+ Agile.logger.warn(
+ 'Keep in mind that without a key no Proxy can be wrapped around the dependency value!',
+ dep
+ );
}
return dep?.value;
diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts
index 175c8eaf..4746c07c 100644
--- a/packages/utils/src/index.ts
+++ b/packages/utils/src/index.ts
@@ -89,7 +89,7 @@ export function normalizeArray(
config = defineConfig(config, {
createUndefinedArray: false, // If it should return [] or [undefined] if the passed Item is undefined
});
- if (!items && !config.createUndefinedArray) return [];
+ if (items == null && !config.createUndefinedArray) return [];
return Array.isArray(items) ? items : [items as DataType];
}
diff --git a/packages/utils/tests/unit/utils.test.ts b/packages/utils/tests/unit/utils.test.ts
index 6156551c..8206d311 100644
--- a/packages/utils/tests/unit/utils.test.ts
+++ b/packages/utils/tests/unit/utils.test.ts
@@ -178,6 +178,10 @@ describe('Utils Tests', () => {
expect(normalizeArray(1)).toStrictEqual([1]);
});
+ it('should normalize single 0 Item (default config)', () => {
+ expect(normalizeArray(0)).toStrictEqual([0]);
+ });
+
it("shouldn't normalize undefined (default config)", () => {
expect(normalizeArray(undefined)).toStrictEqual([]);
});