{"id":22867873,"url":"https://github.com/osmerion/quitte","last_synced_at":"2025-10-25T13:32:21.183Z","repository":{"id":57728200,"uuid":"130517767","full_name":"Osmerion/Quitte","owner":"Osmerion","description":"Quitte provides specialized observable properties and expressions with lazy variants and observable collections.","archived":false,"fork":false,"pushed_at":"2024-04-15T12:58:29.000Z","size":2682,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-06T15:42:32.354Z","etag":null,"topics":["observable","observer-pattern","quitte"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Osmerion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-21T22:51:17.000Z","updated_at":"2023-09-18T08:41:28.000Z","dependencies_parsed_at":"2024-12-13T12:32:36.632Z","dependency_job_id":"c9f37e38-fd99-45b8-ba4f-f5704671b970","html_url":"https://github.com/Osmerion/Quitte","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Osmerion%2FQuitte","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Osmerion%2FQuitte/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Osmerion%2FQuitte/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Osmerion%2FQuitte/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Osmerion","download_url":"https://codeload.github.com/Osmerion/Quitte/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246458023,"owners_count":20780675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["observable","observer-pattern","quitte"],"created_at":"2024-12-13T12:29:10.984Z","updated_at":"2025-10-25T13:32:21.100Z","avatar_url":"https://github.com/Osmerion.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Quitte\n\n[![License](https://img.shields.io/badge/license-BSD-blue.svg?style=for-the-badge\u0026label=License)](https://github.com/Osmerion/Quitte/blob/master/LICENSE)\n[![Maven Central](https://img.shields.io/maven-central/v/com.osmerion.quitte/quitte.svg?style=for-the-badge\u0026label=Maven%20Central)](https://maven-badges.herokuapp.com/maven-central/com.osmerion.quitte/quitte)\n[![JavaDoc](https://img.shields.io/maven-central/v/com.osmerion.quitte/quitte.svg?style=for-the-badge\u0026label=JavaDoc\u0026color=blue)](https://javadoc.io/doc/com.osmerion.quitte/quitte)\n![Java](https://img.shields.io/badge/Java-17-green.svg?style=for-the-badge\u0026color=b07219\u0026logo=java)\n\nQuitte provides specialized observable properties and expressions with lazy\nvariants, and observable collections.\n\nQuitte is compatible with Java 17 or later.\n\n\n## Usage\n\n### Quitte\n\nThe core module provides the basic set of observable building blocks.\n\n\n#### Properties\n\nProperties are mutable wrappers for values which support listening for changes.\n_Simple_ properties are the most basic kind of observable. They are simple\nwrappers for values with set- and get-access.\n\n_Lazy_ properties provide setter overloads to support lazy updates of their\nvalues. When, for example, `LazyIntProperty#set(IntSupplier)` is used, the\nproperties value is not updated. Instead, the property is marked as invalid and\nonly invalidation listeners are notified. The new value is only computed when\nthe property's value is queried.\n\n\u003e **Tip:** While properties are fundamentally mutable, it is generally\n\u003e recommended using read-only views of properties to reduce the risk of unwanted\n\u003e modifications. (See `ReadableProperty#asReadOnlyProperty()`)\n\n#### Expressions\n\nExpressions are observables which are derived from one or more observables using\nsome processing step. They do not have a mutable value, but instead _yield_ the\nvalue of the calculation they represent. Similar to properties, expressions come\nin two flavours:\n\n- _Simple_ expressions which recompute their result eagerly when the value of an\n  input is changed, and\n- _Lazy_ expressions which avoid recomputing until their result is queried.\n\n\n#### Observable collections\n\nIn addition to single-value observables, Quitte also supports observable\ncollections. To support a variety of collection implementations, Quitte's\nobservable collections are wrappers that delegate to a concrete implementation.\n\n```java\nList\u003cString\u003e strings = new ArrayList\u003c\u003e();\nObservableList\u003cString\u003e observableStrings = ObservableList.of(strings);\nobservableStrings.addChangeListener(change -\u003e System.out.println(\"The content of observableStrings has been changed.\"));\n\nobservableStrings.add(\"foo\");\n\n/*\n * WARNING: The call below does not notify the listeners since it accesses the\n * list implementation directly. To avoid running into issues, holding a\n * reference to the collection implementation is discouraged. Instead, use:\n * \n * ObservableList\u003cString\u003e observableStrings = ObservableList.of(new ArrayList());\n */\nstrings.add(\"bar\");\n```\n\n\n### Quitte I18n\n\nThe `quitte-i18n` module provides a basic API for using Quitte observables for\nlocalization.\n\n\u003e **Tip:** [Billi](https://github.com/Osmerion/Billi) provides complete\n\u003e localization and pluralization support on top of Quitte.\n\n\n### Quitte extensions for Jetpack Compose\n\nThe `quitte-compose` module provides extensions for better interoperability with\n[Jetpack Compose](https://developer.android.com/jetpack/compose).\n\n```kotlin\ninterface MyModel {\n    val text: ObservableObjectValue\u003cString\u003e\n}\n\n@Composable\nfun MyComposable(model: MyModel) {\n    val text by textFlow.observeAsState()\n    \n    Text(text)\n}\n```\n\n\u003e **Note**: The `quitte-compose` module targets Java 17 bytecode and is\n\u003e currently only supported for [Compose for Desktop](https://www.jetbrains.com/lp/compose-mpp/).\n\n\n### Quitte extensions for kotlinx.coroutines\n\nThe `quitte-kotlinx-coroutines` module provides extensions for better\ninteroperability with [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines).\n\nSimply convert observables to flows using any of the built-in conversion\nfunctions. Flow conversions are available for `ObservableValue`,\n`ObservableList`, `ObservableMap`, and `ObservableSet`.\n\n\n## Building from source\n\n### Setup\n\nThis project uses [Gradle's toolchain support](https://docs.gradle.org/8.1.1/userguide/toolchains.html)\nto detect and select the JDKs required to run the build. Please refer to the\nbuild scripts to find out which toolchains are requested.\n\nAn installed JDK 1.8 (or later) is required to use Gradle.\n\n### Building\n\nOnce the setup is complete, invoke the respective Gradle tasks using the\nfollowing command on Unix/macOS:\n\n    ./gradlew \u003ctasks\u003e\n\nor the following command on Windows:\n\n    gradlew \u003ctasks\u003e\n\nImportant Gradle tasks to remember are:\n- `clean`                   - clean build results\n- `build`                   - assemble and test the Java library\n- `generate`                - generates all code from the templates (see the\n                              \"Editing\" section below for details)\n- `publishToMavenLocal`     - build and install all public artifacts to the\n                              local maven repository\n\nAdditionally `tasks` may be used to print a list of all available tasks.\n\n\n## Editing\n\nTo reduce the amount duplication when generating specialized types, Quitte uses\na simple code-generation mechanism. The templates are simple Gradle Kotlin DSL\nscripts which are located under `src/{module}/{site}-templates` and discovered\nautomatically.\n\nThe generated code is published to the repository to make it easier to follow\nchanges using the git history.\n\n\n## License\n\nQuitte is available under the terms of the [3-Clause BSD license](https://spdx.org/licenses/BSD-3-Clause.html).\n\n```\nCopyright (c) 2018-2023 Leon Linhart,\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its contributors\n   may be used to endorse or promote products derived from this software\n   without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosmerion%2Fquitte","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosmerion%2Fquitte","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosmerion%2Fquitte/lists"}