diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml
index fee409487f..b521ac8252 100644
--- a/.github/workflows/build-and-deploy.yml
+++ b/.github/workflows/build-and-deploy.yml
@@ -22,12 +22,12 @@ jobs:
id: ci-preparation
run: echo "build-ref=${{ github.workflow }}-${{ github.event.number || github.ref }}" >> $GITHUB_OUTPUT
- name: Checkout
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Compute the Java version
id: java-version
run: ruby -e 'puts("java-version=#{/^minJavaVersion\s*=\s*(\d+)$/.match(File.read("gradle.properties"))[1]}")' >> $GITHUB_OUTPUT
- name: Install Node
- uses: actions/setup-node@v6.0.0
+ uses: actions/setup-node@v6.1.0
with:
node-version-file: package.json
- name: Compute the next release version
@@ -57,8 +57,8 @@ jobs:
timeout-minutes: 180
steps:
- name: Checkout
- uses: actions/checkout@v6.0.0
- - uses: DanySK/build-check-deploy-gradle-action@3a800c3b221073eeae25f5fb98687e3a40aa1712 # 4.0.12
+ uses: actions/checkout@v6.0.1
+ - uses: DanySK/build-check-deploy-gradle-action@810719541546fff1db1edd1fb858e12654dc1d95 # 4.0.17
with:
pre-build-command: ./gradlew kotlinUpgradeYarnLock
build-command: true
@@ -76,8 +76,8 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout
- uses: danysk/action-checkout@733b8984412e3cc1ea66fcd20281710dc2118187 # 0.2.26
- - uses: DanySK/build-check-deploy-gradle-action@3a800c3b221073eeae25f5fb98687e3a40aa1712 # 4.0.12
+ uses: danysk/action-checkout@7f6ee3cd5bd670cdb3e162894776736254afff1e # 0.2.27
+ - uses: DanySK/build-check-deploy-gradle-action@810719541546fff1db1edd1fb858e12654dc1d95 # 4.0.17
with:
retries-on-failure: 5
wait-between-retries: 120
@@ -91,7 +91,7 @@ jobs:
- name: Tar files
run: tar -cvf website.tar build/website
- name: Upload website
- uses: actions/upload-artifact@v5.0.0
+ uses: actions/upload-artifact@v6.0.0
with:
name: website-${{ github.sha }}
path: website.tar
@@ -131,8 +131,8 @@ jobs:
timeout-minutes: 120
steps:
- name: Checkout with full history
- uses: danysk/action-checkout@733b8984412e3cc1ea66fcd20281710dc2118187 # 0.2.26
- - uses: DanySK/build-check-deploy-gradle-action@3a800c3b221073eeae25f5fb98687e3a40aa1712 # 4.0.12
+ uses: danysk/action-checkout@7f6ee3cd5bd670cdb3e162894776736254afff1e # 0.2.27
+ - uses: DanySK/build-check-deploy-gradle-action@810719541546fff1db1edd1fb858e12654dc1d95 # 4.0.17
with:
signing-key: ${{ secrets.SIGNING_KEY }}
signing-password: ${{ secrets.SIGNING_PASSWORD }}
@@ -151,20 +151,20 @@ jobs:
fi
- name: Upload fatjars built on Linux
if: ${{ runner.os == 'Linux' }}
- uses: actions/upload-artifact@v5.0.0
+ uses: actions/upload-artifact@v6.0.0
with:
name: fat-jars-${{ github.sha }}
path: build/shadow/*
if-no-files-found: error
- name: Upload the PKGBUILD
if: ${{ runner.os == 'Linux' }}
- uses: actions/upload-artifact@v5.0.0
+ uses: actions/upload-artifact@v6.0.0
with:
name: pkgbuild-${{ github.sha }}
path: build/pkgbuild/PKGBUILD
if-no-files-found: error
- name: Upload platform-specific packages
- uses: actions/upload-artifact@v5.0.0
+ uses: actions/upload-artifact@v6.0.0
with:
name: installer-package-${{ github.sha }}-${{ runner.os }}
path: build/package/*
@@ -179,7 +179,7 @@ jobs:
always() && needs.assemble-and-upload.result == 'success'
steps:
- name: Download packages
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
name: installer-package-${{ github.sha }}-${{ runner.os }}
- name: Install packages
@@ -214,7 +214,7 @@ jobs:
always() && needs.assemble-and-upload.result == 'success'
steps:
- name: Download packages
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
name: installer-package-${{ github.sha }}-${{ runner.os }}
- name: Work around xdg bug https://bugs.archlinux.org/task/33316
@@ -242,7 +242,7 @@ jobs:
image: fedora:44
steps:
- name: Download packages
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
name: installer-package-${{ github.sha }}-${{ runner.os }}
- name: Install packages
@@ -275,7 +275,7 @@ jobs:
# Work around https://github.com/actions/checkout/issues/1169
# sudo git config --system --add safe.directory /__w/Alchemist/Alchemist
- name: Download the PKGBUILD
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
pattern: pkgbuild-${{ github.sha }}
merge-multiple: true
@@ -284,7 +284,7 @@ jobs:
namcap PKGBUILD 2>&1
namcap PKGBUILD 2>&1 | awk 'END { exit (NR > 0 ? NR : 0) }'
- name: Download the RPM
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
pattern: installer-package-${{ github.sha }}-${{ runner.os }}
merge-multiple: true
@@ -352,7 +352,7 @@ jobs:
)
steps:
- name: Checkout
- uses: actions/checkout@v6.0.0
+ uses: actions/checkout@v6.0.1
with:
fetch-depth: 0
fetch-tags: 'true'
@@ -360,7 +360,7 @@ jobs:
token: ${{ secrets.DEPLOYMENT_TOKEN }}
- name: Checkout the docs
if: contains(github.repository, 'AlchemistSimulator/Alchemist')
- uses: actions/checkout@v6.0.0
+ uses: DanySK/checkout-classic@f55ca46048a09d13b47f0e80db6b546977327791 # 1.0.0
with:
path: website
fetch-depth: 0
@@ -369,32 +369,32 @@ jobs:
repository: AlchemistSimulator/alchemistsimulator.github.io
token: ${{ secrets.DEPLOYMENT_TOKEN }}
- name: Download website artifact
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
name: website-${{ github.sha }}
- name: Download packages
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
pattern: installer-package-${{ github.sha }}*
path: build/package/
merge-multiple: true
- name: Download fatJars
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
name: fat-jars-${{ github.sha }}
path: build/shadow/
merge-multiple: true
- name: Download the PKGBUILD
- uses: actions/download-artifact@v6.0.0
+ uses: actions/download-artifact@v7.0.0
with:
pattern: pkgbuild-${{ github.sha }}
path: pkgbuild/
merge-multiple: true
- name: Install Node
- uses: actions/setup-node@v6.0.0
+ uses: actions/setup-node@v6.1.0
with:
node-version-file: package.json
- - uses: DanySK/build-check-deploy-gradle-action@3a800c3b221073eeae25f5fb98687e3a40aa1712 # 4.0.12
+ - uses: DanySK/build-check-deploy-gradle-action@810719541546fff1db1edd1fb858e12654dc1d95 # 4.0.17
env:
MAKEPKG_IMAGE: ${{ needs.ci-preparation.outputs.makepkg-image }}
with:
diff --git a/.github/workflows/update-ancillary-files.yml b/.github/workflows/update-ancillary-files.yml
index 853475c9d2..293751a82c 100644
--- a/.github/workflows/update-ancillary-files.yml
+++ b/.github/workflows/update-ancillary-files.yml
@@ -3,6 +3,8 @@ on:
push:
branches:
- master
+ paths:
+ - gradle/libs.versions.toml
workflow_dispatch:
jobs:
@@ -12,14 +14,13 @@ jobs:
group: javadoc-io-${{ github.workflow }}-${{ github.event.number || github.ref }}
steps:
- name: Checkout
- uses: danysk/action-checkout@733b8984412e3cc1ea66fcd20281710dc2118187 # 0.2.26
+ uses: danysk/action-checkout@7f6ee3cd5bd670cdb3e162894776736254afff1e # 0.2.27
with:
token: ${{ secrets.DEPLOYMENT_TOKEN }}
- - uses: DanySK/build-check-deploy-gradle-action@3a800c3b221073eeae25f5fb98687e3a40aa1712 # 4.0.12
+ - uses: DanySK/build-check-deploy-gradle-action@810719541546fff1db1edd1fb858e12654dc1d95 # 4.0.17
with:
pre-build-command: rm -rf dokka-cache
build-command: |
- ./gradlew dokkaGenerateModuleHtml dokkaGeneratePublicationHtml --dry-run
for i in {1..3}; do
rm dokka-cache/no-javadoc.json || true
./gradlew dokkaGenerateModuleHtml dokkaGeneratePublicationHtml --dry-run
diff --git a/.gitignore b/.gitignore
index fc3b089b4e..4257e9f0d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,6 +49,7 @@ buildProfile/
.DS_Store
# Other
+dokka-cache/no-javadoc.json
node_modules/
.kotlintest/
**/*.kotlintest*/*
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 7bee31df84..8dce9e5fbf 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -5,6 +5,10 @@
+
+
+
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9f197fe25d..841cf65a4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,95 @@
+## [42.3.22](https://github.com/AlchemistSimulator/Alchemist/compare/42.3.21...42.3.22) (2025-12-16)
+
+### Dependency updates
+
+* **core-deps:** update protelis to v18.5.2 (patch) ([#5030](https://github.com/AlchemistSimulator/Alchemist/issues/5030)) ([e0503ea](https://github.com/AlchemistSimulator/Alchemist/commit/e0503eac9be54f347b84c759582babded1e69479))
+* **deps:** update plugin gitsemver to v7.0.8 ([#5032](https://github.com/AlchemistSimulator/Alchemist/issues/5032)) ([ca38999](https://github.com/AlchemistSimulator/Alchemist/commit/ca3899992be523ff963d1e1e6309dd23ad897b0f))
+
+### General maintenance
+
+* **build:** update the javadoc.io cache ([809caf9](https://github.com/AlchemistSimulator/Alchemist/commit/809caf9365dd1d7e03dae2fdf42eba0a58a17fb2))
+* **build:** update the javadoc.io cache ([8e82263](https://github.com/AlchemistSimulator/Alchemist/commit/8e822638eaad13e1f487560455dfc94ac8c46998))
+
+## [42.3.21](https://github.com/AlchemistSimulator/Alchemist/compare/42.3.20...42.3.21) (2025-12-16)
+
+### Dependency updates
+
+* **core-deps:** update protelis to v18.5.1 (patch) ([#5027](https://github.com/AlchemistSimulator/Alchemist/issues/5027)) ([e15e840](https://github.com/AlchemistSimulator/Alchemist/commit/e15e8404e3fa4dcb2fc241ca8b535c4a93727c77))
+* **deps:** update plugin hugo to v0.12.0 ([#5026](https://github.com/AlchemistSimulator/Alchemist/issues/5026)) ([1742fe0](https://github.com/AlchemistSimulator/Alchemist/commit/1742fe0adce61ee8236b476ab8157d3b8a1646aa))
+
+### General maintenance
+
+* **build:** update the javadoc.io cache ([964891b](https://github.com/AlchemistSimulator/Alchemist/commit/964891b48a1c6538b1d482af3257af9782396e8f))
+* **build:** update the javadoc.io cache ([3fa575b](https://github.com/AlchemistSimulator/Alchemist/commit/3fa575b92dfe3c39cfb825e363fa8c55dcd680ef))
+
+## [42.3.20](https://github.com/AlchemistSimulator/Alchemist/compare/42.3.19...42.3.20) (2025-12-14)
+
+### Dependency updates
+
+* **deps:** bump tar and npm ([5ca3171](https://github.com/AlchemistSimulator/Alchemist/commit/5ca3171e94cbe45f164c007205ccc256100aefa2))
+* **deps:** update dependency ch.qos.logback:logback-classic to v1.5.22 ([#5017](https://github.com/AlchemistSimulator/Alchemist/issues/5017)) ([4676322](https://github.com/AlchemistSimulator/Alchemist/commit/46763228e3d05381fbaab5a3993099260f781d7f))
+* **deps:** update dependency de.flapdoodle.embed:de.flapdoodle.embed.mongo to v4.22.0 ([#5025](https://github.com/AlchemistSimulator/Alchemist/issues/5025)) ([1ce453e](https://github.com/AlchemistSimulator/Alchemist/commit/1ce453ea1c61bbb5022888eeec5731466dbcd1b3))
+* **deps:** update dependency io.mockk:mockk to v1.14.7 ([#5013](https://github.com/AlchemistSimulator/Alchemist/issues/5013)) ([bfd664c](https://github.com/AlchemistSimulator/Alchemist/commit/bfd664c7cd92b8427815f0900b42c2cecba23119))
+* **deps:** update dependency org.danilopianini.gradle-java-qa:org.danilopianini.gradle-java-qa.gradle.plugin to v1.156.0 ([#4995](https://github.com/AlchemistSimulator/Alchemist/issues/4995)) ([cf765e5](https://github.com/AlchemistSimulator/Alchemist/commit/cf765e57f64a0dc0ed50895bdef5bc72e06bb8a4))
+* **deps:** update dependency org.danilopianini.gradle-java-qa:org.danilopianini.gradle-java-qa.gradle.plugin to v1.157.0 ([#4998](https://github.com/AlchemistSimulator/Alchemist/issues/4998)) ([cc2a338](https://github.com/AlchemistSimulator/Alchemist/commit/cc2a3387ae9ac4ec7509958b9f4d55f876ffb9a8))
+* **deps:** update dependency org.danilopianini.gradle-java-qa:org.danilopianini.gradle-java-qa.gradle.plugin to v1.158.0 ([#5001](https://github.com/AlchemistSimulator/Alchemist/issues/5001)) ([97f298e](https://github.com/AlchemistSimulator/Alchemist/commit/97f298e3e51292e4aec403de075ec9c40e5305f6))
+* **deps:** update dependency org.danilopianini.gradle-java-qa:org.danilopianini.gradle-java-qa.gradle.plugin to v1.159.0 ([#5002](https://github.com/AlchemistSimulator/Alchemist/issues/5002)) ([233fcba](https://github.com/AlchemistSimulator/Alchemist/commit/233fcba3fcfa86ee575ba7009966a375025a537d))
+* **deps:** update dependency org.danilopianini.gradle-java-qa:org.danilopianini.gradle-java-qa.gradle.plugin to v1.161.0 ([#5024](https://github.com/AlchemistSimulator/Alchemist/issues/5024)) ([6852877](https://github.com/AlchemistSimulator/Alchemist/commit/6852877feb06943d4e96df754e63947c5b8ff7aa))
+* **deps:** update dependency org.danilopianini.gradle-kotlin-qa:org.danilopianini.gradle-kotlin-qa.gradle.plugin to v0.99.0 ([#4999](https://github.com/AlchemistSimulator/Alchemist/issues/4999)) ([0383dbf](https://github.com/AlchemistSimulator/Alchemist/commit/0383dbfa9f6342f3e1bd4a029a513b4f68391f3b))
+* **deps:** update dependency org.eclipse.jgit:org.eclipse.jgit to v7.5.0.202512021534-r ([#5022](https://github.com/AlchemistSimulator/Alchemist/issues/5022)) ([3f40d56](https://github.com/AlchemistSimulator/Alchemist/commit/3f40d566126cab5924cc6f589a3774db41ba7555))
+* **deps:** update dependency org.mockito:mockito-core to v5.21.0 ([#5015](https://github.com/AlchemistSimulator/Alchemist/issues/5015)) ([33a28d4](https://github.com/AlchemistSimulator/Alchemist/commit/33a28d42132d1b153c75dfd5974dd7ca1b914fde))
+* **deps:** update dependency org.mongodb:mongodb-driver-sync to v5.6.2 ([#5014](https://github.com/AlchemistSimulator/Alchemist/issues/5014)) ([e37b55b](https://github.com/AlchemistSimulator/Alchemist/commit/e37b55b0bf0569b6aeb50a32aae4f190d7752c70))
+* **deps:** update dependency scalafmt to v3.10.2 ([#4996](https://github.com/AlchemistSimulator/Alchemist/issues/4996)) ([22d9d50](https://github.com/AlchemistSimulator/Alchemist/commit/22d9d506cc40e06b1f2099cb76c5d3def3682425))
+* **deps:** update kotest to v6.0.6 (patch) ([#5000](https://github.com/AlchemistSimulator/Alchemist/issues/5000)) ([5b7ad8b](https://github.com/AlchemistSimulator/Alchemist/commit/5b7ad8b18f8a2bcc897b1278bfafa8e421d93a30))
+* **deps:** update kotest to v6.0.7 (patch) ([#5003](https://github.com/AlchemistSimulator/Alchemist/issues/5003)) ([752f60e](https://github.com/AlchemistSimulator/Alchemist/commit/752f60e90a4a5890caee1ae7836cbb38f7a1c590))
+* **deps:** update ktor monorepo to v3.3.3 (patch) ([#4997](https://github.com/AlchemistSimulator/Alchemist/issues/4997)) ([b2a73df](https://github.com/AlchemistSimulator/Alchemist/commit/b2a73dfee77126e083ffe4aacbf1cd5bf7dbf67f))
+* **deps:** update node.js to 24.12 ([#5021](https://github.com/AlchemistSimulator/Alchemist/issues/5021)) ([65dc0fe](https://github.com/AlchemistSimulator/Alchemist/commit/65dc0fe73df4d8ef49bda9d2d2c4c5e17ad7f7db))
+* **deps:** update plugin com.gradle.develocity to v4.3 ([#5016](https://github.com/AlchemistSimulator/Alchemist/issues/5016)) ([8442fd8](https://github.com/AlchemistSimulator/Alchemist/commit/8442fd829f9f6cb8c863a4a299653907f03e5f20))
+* **deps:** update plugin shadowjar to v9.3.0 ([#5012](https://github.com/AlchemistSimulator/Alchemist/issues/5012)) ([48a098f](https://github.com/AlchemistSimulator/Alchemist/commit/48a098f5ce4f50d8e12ca5661e3d9d4f81dc17cf))
+* **deps:** update react to v2025.12.0-19.2.0 (minor) ([#5004](https://github.com/AlchemistSimulator/Alchemist/issues/5004)) ([004bdb5](https://github.com/AlchemistSimulator/Alchemist/commit/004bdb5639686f5b376537ee2c655c1f0a669dc1))
+* **deps:** update react to v2025.12.5-19.2.1 (patch) ([#5008](https://github.com/AlchemistSimulator/Alchemist/issues/5008)) ([c0ef04b](https://github.com/AlchemistSimulator/Alchemist/commit/c0ef04ba0c6251730bb5b8a46e2da73e36208dab))
+* **deps:** update react to v2025.12.6-19.2.3 (patch) ([#5023](https://github.com/AlchemistSimulator/Alchemist/issues/5023)) ([0056d37](https://github.com/AlchemistSimulator/Alchemist/commit/0056d37edc0a7c49ac50e6bea2b9656a8e22b1ad))
+
+### Bug Fixes
+
+* **release:** checkout the docs using a custom version of the checkout action to work around the new behavior of actions v6 ([f436111](https://github.com/AlchemistSimulator/Alchemist/commit/f436111b2a4865a37ad1544180241fd40441acbd))
+* **release:** rollback actions/checkout to v5 in release ([35d4d12](https://github.com/AlchemistSimulator/Alchemist/commit/35d4d12b169e3e4a9aca67d3c97650e5172780df))
+
+### Build and continuous integration
+
+* **deps:** update actions/checkout action to v6 ([fc702d4](https://github.com/AlchemistSimulator/Alchemist/commit/fc702d41a94e999ffe545d9a15df52d928d07909))
+* **deps:** update actions/checkout action to v6.0.1 ([#5005](https://github.com/AlchemistSimulator/Alchemist/issues/5005)) ([89f9e56](https://github.com/AlchemistSimulator/Alchemist/commit/89f9e56b71c85c3283c9309594f93dc19d5eb0eb))
+* **deps:** update actions/download-artifact action to v7 ([#5019](https://github.com/AlchemistSimulator/Alchemist/issues/5019)) ([41b6775](https://github.com/AlchemistSimulator/Alchemist/commit/41b6775d1763fdb6606638960cf0fb2eef9bf222))
+* **deps:** update actions/setup-node action to v6.1.0 ([#5007](https://github.com/AlchemistSimulator/Alchemist/issues/5007)) ([3ac6f8d](https://github.com/AlchemistSimulator/Alchemist/commit/3ac6f8de740ebfb8a227d50f1fa51aaccf7471e4))
+* **deps:** update actions/upload-artifact action to v6 ([#5020](https://github.com/AlchemistSimulator/Alchemist/issues/5020)) ([9fe74ef](https://github.com/AlchemistSimulator/Alchemist/commit/9fe74efded4fffc1e4196bf2a8bb69e80415bffc))
+* **deps:** update danysk/action-checkout action to v0.2.27 ([#5006](https://github.com/AlchemistSimulator/Alchemist/issues/5006)) ([6b7002c](https://github.com/AlchemistSimulator/Alchemist/commit/6b7002c7cb62dbc0245c8191c4414378a325e059))
+* **deps:** update danysk/build-check-deploy-gradle-action action to v4.0.17 ([#5009](https://github.com/AlchemistSimulator/Alchemist/issues/5009)) ([9d159fe](https://github.com/AlchemistSimulator/Alchemist/commit/9d159fe985f6311b40db111ae1b17d597519780c))
+* **dokka:** update ancillary files only when the dependencies get modified ([88b038a](https://github.com/AlchemistSimulator/Alchemist/commit/88b038a90a7fcda49fb803572c7535353994da91))
+
+### General maintenance
+
+* **build:** actualize the Kotlin JS store ([576fd51](https://github.com/AlchemistSimulator/Alchemist/commit/576fd51c105f9ae801e7b80e31ec51cae685d8cd))
+* **build:** actualize the Kotlin JS store ([f898d26](https://github.com/AlchemistSimulator/Alchemist/commit/f898d2688b57474c2b156f75075dd739500333f0))
+* **build:** update the javadoc.io cache ([0c4aa5b](https://github.com/AlchemistSimulator/Alchemist/commit/0c4aa5b13ba232c400f094b62dab123e412ae1d8))
+* **build:** update the javadoc.io cache ([54aa505](https://github.com/AlchemistSimulator/Alchemist/commit/54aa505defdebe6966b745c13f28e0852bcf59b1))
+* **build:** update the javadoc.io cache ([6e0b7b5](https://github.com/AlchemistSimulator/Alchemist/commit/6e0b7b5eee3260953692ed08d10d6fbf91a66e7c))
+* **build:** update the javadoc.io cache ([f0bb809](https://github.com/AlchemistSimulator/Alchemist/commit/f0bb80938fc2f523d038a275207a80d68fce3d11))
+* **build:** update the javadoc.io cache ([8c6c7fb](https://github.com/AlchemistSimulator/Alchemist/commit/8c6c7fbea20aacc064fcb04ec3aaaf35a54f1ada))
+* **build:** update the javadoc.io cache ([f51b226](https://github.com/AlchemistSimulator/Alchemist/commit/f51b226efa25233488b1f47e1caad25fbb0b5466))
+* **build:** update the javadoc.io cache ([651795a](https://github.com/AlchemistSimulator/Alchemist/commit/651795add9d059b30e28f3f31b4770888ee47d9f))
+* **build:** update the javadoc.io cache ([6e65d79](https://github.com/AlchemistSimulator/Alchemist/commit/6e65d7955ceae757f2becd824ac0c71dc5da8903))
+* **build:** update the javadoc.io cache ([268e511](https://github.com/AlchemistSimulator/Alchemist/commit/268e51140867449f56336c3a2cc92d204fe27667))
+* **build:** update the javadoc.io cache ([3eae6f2](https://github.com/AlchemistSimulator/Alchemist/commit/3eae6f279f839ef3316232b13bd35513ee91a402))
+* **build:** update the javadoc.io cache ([212dfe5](https://github.com/AlchemistSimulator/Alchemist/commit/212dfe5d9b8f48d745be98618662a6b6a0e979de))
+* **build:** update the javadoc.io cache ([38d7f75](https://github.com/AlchemistSimulator/Alchemist/commit/38d7f758f8052b832ef977db89b883f624fc3ce6))
+* **build:** update the javadoc.io cache ([a8f88c5](https://github.com/AlchemistSimulator/Alchemist/commit/a8f88c560acc826f32ed03a9095dbd3ab1a22f02))
+* **build:** update the javadoc.io cache ([e542b8e](https://github.com/AlchemistSimulator/Alchemist/commit/e542b8eea01e41e9bc20a1f3f9fdf5026125d9d2))
+* **build:** update the javadoc.io cache ([f97d652](https://github.com/AlchemistSimulator/Alchemist/commit/f97d652f803b835ff853846e73e060bafacaf29e))
+* **build:** update the javadoc.io cache ([3bead0f](https://github.com/AlchemistSimulator/Alchemist/commit/3bead0feff8b2e6f7192d6d6433b8c1007e4c4dc))
+* **build:** update the javadoc.io cache ([19d8692](https://github.com/AlchemistSimulator/Alchemist/commit/19d869272e7fd310ee55349a68f60220285de58c))
+* **build:** update the javadoc.io cache ([0ddf5eb](https://github.com/AlchemistSimulator/Alchemist/commit/0ddf5eba2f3c3a4564c58a55aa53485bf968f9a3))
+* **build:** update the javadoc.io cache ([a99a02d](https://github.com/AlchemistSimulator/Alchemist/commit/a99a02db879cedcab685069f306314abada9a54b))
+
## [42.3.19](https://github.com/AlchemistSimulator/Alchemist/compare/42.3.18...42.3.19) (2025-11-25)
### Dependency updates
diff --git a/alchemist-api/build.gradle.kts b/alchemist-api/build.gradle.kts
index 8b9292aa9f..b3d9454f1c 100644
--- a/alchemist-api/build.gradle.kts
+++ b/alchemist-api/build.gradle.kts
@@ -16,6 +16,7 @@ dependencies {
api(libs.jool)
api(libs.listset)
implementation(libs.kotlin.reflect)
+ api(libs.arrow.core)
testImplementation(libs.kotlin.test)
}
diff --git a/alchemist-api/src/main/java/it/unibo/alchemist/model/Condition.java b/alchemist-api/src/main/java/it/unibo/alchemist/model/Condition.java
index f4d31ef380..84fa0b2599 100644
--- a/alchemist-api/src/main/java/it/unibo/alchemist/model/Condition.java
+++ b/alchemist-api/src/main/java/it/unibo/alchemist/model/Condition.java
@@ -10,6 +10,9 @@
package it.unibo.alchemist.model;
import it.unibo.alchemist.core.Simulation;
+import it.unibo.alchemist.model.observation.Disposable;
+import it.unibo.alchemist.model.observation.Observable;
+import it.unibo.alchemist.model.observation.ObservableSet;
import org.danilopianini.util.ListSet;
import java.io.Serializable;
@@ -20,7 +23,7 @@
* @param
* The type which describes the concentration of a molecule
*/
-public interface Condition extends Serializable {
+public interface Condition extends Serializable, Disposable {
/**
* This method allows cloning this action on a new node. It may result
@@ -46,6 +49,12 @@ public interface Condition extends Serializable {
*/
ListSet extends Dependency> getInboundDependencies();
+ /**
+ * @return The set of dependencies which may influence the truth value of this
+ * condition, as an {@link ObservableSet} of {@link Observable}
+ */
+ ObservableSet extends Observable>> observeInboundDependencies();
+
/**
* @return the node this Condition belongs to
*/
@@ -61,11 +70,24 @@ public interface Condition extends Serializable {
*/
double getPropensityContribution();
+ /**
+ * An observable and reactive view of the corresponding {@link #getPropensityContribution()}.
+ *
+ * @return an observable view of how this condition may influence the propensity.
+ */
+ Observable observePropensityContribution();
+
/**
* @return true if the condition is satisfied in the current environment.
*/
boolean isValid();
+ /**
+ * @return an observable that emits true if the condition is satisfied in the
+ * current environment.
+ */
+ Observable observeValidity();
+
/**
* This method is called by the {@link Simulation} once the {@link Reaction}
* whose this {@link Condition} belongs to is the next one to be executed, and
diff --git a/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Actionable.kt b/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Actionable.kt
index 3004bfa4b0..da9027f8cd 100644
--- a/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Actionable.kt
+++ b/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Actionable.kt
@@ -9,6 +9,7 @@
package it.unibo.alchemist.model
+import it.unibo.alchemist.model.observation.Observable
import java.io.Serializable
import org.danilopianini.util.ListSet
@@ -24,6 +25,14 @@ sealed interface Actionable :
*/
fun canExecute(): Boolean
+ /**
+ * Observes whether the reaction can be executed. This observable emits updates
+ * to indicate if the conditions required for execution are satisfied.
+ *
+ * @return An [Observable] emitting true if the reaction van be executed, false otherwise.
+ */
+ fun observeCanExecute(): Observable
+
/**
* Executes the reactions.
*/
@@ -88,6 +97,12 @@ sealed interface Actionable :
*/
val timeDistribution: TimeDistribution
+ /**
+ * Emits when this reaction requests the [Scheduler][it.unibo.alchemist.core.Scheduler]
+ * to reschedule this reaction.
+ */
+ val rescheduleRequest: Observable
+
/**
* Updates the scheduling of this reaction.
*
diff --git a/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Environment.kt b/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Environment.kt
index beacb1bff9..d6db5a1dc9 100644
--- a/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Environment.kt
+++ b/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Environment.kt
@@ -10,6 +10,8 @@
package it.unibo.alchemist.model
import it.unibo.alchemist.core.Simulation
+import it.unibo.alchemist.model.observation.Observable
+import it.unibo.alchemist.model.observation.ObservableSet
import java.io.Serializable
import org.danilopianini.util.ListSet
@@ -18,6 +20,7 @@ import org.danilopianini.util.ListSet
* Every environment must implement this specification.
* [T] is the [Concentration] type, [P] is the [Position] type.
*/
+@Suppress("TooManyFunctions")
interface Environment> :
Serializable,
Iterable> {
@@ -95,6 +98,12 @@ interface Environment> :
*/
fun getNeighborhood(node: Node): Neighborhood
+ /**
+ * Given a [node], this method returns an observable view of
+ * its neighborhood.
+ */
+ fun observeNeighborhood(node: Node): Observable>
+
/**
* Allows accessing a [Node] in this [Environment] known its [id].
* Depending on the implementation, this method may or may not be optimized
@@ -107,11 +116,21 @@ interface Environment> :
*/
val nodes: ListSet>
+ /**
+ * An [Observable] view of all the [Node]s that exist in current [Environment].
+ */
+ val observableNodes: ObservableSet>
+
/**
* Returns the number of [Node]s currently in the [Environment].
*/
val nodeCount: Int
+ /**
+ * Returns an [Observable] view of the number of [Node]s currently in the [Environment].
+ */
+ val observeNodeCount: Observable
+
/**
* Given a [node] this method returns a list of all the surrounding
* nodes within the given [range]. Note that this method (depending on the
@@ -122,6 +141,11 @@ interface Environment> :
*/
fun getNodesWithinRange(node: Node, range: Double): ListSet>
+ /**
+ * An [Observable] alternative to [getNodesWithinRange].
+ */
+ fun observeNodesWithinRange(node: Node, range: Double): ObservableSet>
+
/**
* Given a [position] this method returns a list of all the
* surrounding nodes within the given [range].
@@ -130,6 +154,11 @@ interface Environment> :
*/
fun getNodesWithinRange(position: P, range: Double): ListSet>
+ /**
+ * An [Observable] alternative to [getNodesWithinRange].
+ */
+ fun observeNodesWithinRange(position: P, range: Double): ObservableSet>
+
/**
* This method allows to know which are the smallest coordinates represented.
* Return an array of length [dimensions] containing the smallest
@@ -142,6 +171,11 @@ interface Environment> :
*/
fun getPosition(node: Node): P
+ /**
+ * Observe the position of a [node].
+ */
+ fun observePosition(node: Node): Observable
+
/**
* Return the current [Simulation], if present, or throws an [IllegalStateException] otherwise.
*/
diff --git a/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Node.kt b/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Node.kt
index 61a1f03341..2acc820121 100644
--- a/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Node.kt
+++ b/alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Node.kt
@@ -8,6 +8,9 @@
*/
package it.unibo.alchemist.model
+import arrow.core.Option
+import it.unibo.alchemist.model.observation.Observable
+import it.unibo.alchemist.model.observation.ObservableMap
import java.io.Serializable
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
@@ -60,6 +63,14 @@ interface Node :
*/
operator fun contains(molecule: Molecule): Boolean
+ /**
+ * Observes whether a node contains a [Molecule].
+ *
+ * @param molecule * the molecule to check
+ * @return emit true if the molecule is present, false otherwise
+ */
+ fun observeContains(molecule: Molecule): Observable
+
/**
* Calculates the concentration of a molecule.
*
@@ -69,11 +80,26 @@ interface Node :
*/
fun getConcentration(molecule: Molecule): T
+ /**
+ * Observe the concentration calculated with the given molecule.
+ * The result of this computation is wrapped into an [Option] and
+ * [some][arrow.core.Some] if the value is present, otherwise
+ * [none][arrow.core.None].
+ *
+ * @param molecule the molecule whose concentration will be returned
+ */
+ fun observeConcentration(molecule: Molecule): Observable