Skip to content

Releases: kaleidot725/PulseDesktop

v3.1.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 01 Nov 12:51
0111ea1

3.1.0 adds a check to the architecture artifact's MVI conventions: under a feature's root, the only packages are content, section and component. mvi and navigation are unchanged.

dependencies {
    implementation("com.github.kaleidot725.PulseDesktop:mvi:v3.1.0")
    implementation("com.github.kaleidot725.PulseDesktop:navigation:v3.1.0")
    testImplementation("com.github.kaleidot725.PulseDesktop:architecture:v3.1.0")
}

Checks

3.0.0 3.1.0
assertViewsHaveARole assertFeaturePackagesHaveARole — every file in a feature, not only composables, is at its root or under content, section or component

assertPulseMviConventions now runs assertFeaturePackagesHaveARole. assertViewsHaveARole is deprecated and still available. Files generated under build/generated, such as the Res class of Compose resources, are not checked.

Migrating from 3.0.0

  • Move packages of your own under a feature, such as text or resource, into component; a pure helper such as a label read with stringResource belongs there
  • Replace calls to assertViewsHaveARole with assertFeaturePackagesHaveARole

See Architecture checks for the details.

v3.0.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 01 Nov 04:48
cf4a5f4

3.0.0 changes how the architecture artifact's MVI conventions lay out a feature. mvi and navigation are unchanged.

dependencies {
    implementation("com.github.kaleidot725.PulseDesktop:mvi:v3.0.0")
    implementation("com.github.kaleidot725.PulseDesktop:navigation:v3.0.0")
    testImplementation("com.github.kaleidot725.PulseDesktop:architecture:v3.0.0")
}

The new layout

counter/
├── CounterHost.kt          # host: creates the ViewModels and the Container, lays out the contents
├── CounterContainer.kt
├── CounterContracts.kt     # the Container's broadcasts and unicasts
├── content/
│   └── total/
│       ├── TotalContent.kt     # binds TotalViewModel with PulseContent
│       ├── TotalViewModel.kt
│       ├── TotalContracts.kt   # the ViewModel's state, actions and events
│       ├── section/            # pure composables only this content draws with
│       └── component/
├── section/                # pure: a part of the screen, drawn from a state and callbacks
└── component/              # pure: a small building block

The root of a feature is the package a content package sits in. A composable that returns a value, such as a label read with stringResource, is not a view and may live anywhere.

Checks

2.x 3.0.0
assertStatesAndMessagesLiveInTheStatePackage assertStatesAndMessagesLiveInContracts — states and messages live in a …Contracts.kt file beside their ViewModel or Container
assertSectionsBindOneViewModel assertContentsBindAViewModel — a content calls PulseContent
assertComponentsAreStateless assertSectionsAndComponentsArePure — sections and components take no ViewModel or Container and bind nothing
assertScreensComposeSections assertHostsComposeContents — a composable at the feature root is in a …Host file and does not call PulseContent
assertComponentsHavePreviews assertSectionsAndComponentsHavePreviews — sections and components have <Name>_Preview
— assertViewModelsLiveInContents — a ViewModel lives under content
— assertContainersLiveAtTheFeatureRoot — a Container lives at the feature root
— assertViewsHaveARole — a composable in a feature is a host, a content, a section or a component

Queries: pulseFeatureRoots, pulseHosts and pulseContents are added; pulseScreens is removed.

Migrating from 2.x

  • Move the states and messages of each ViewModel or Container into a …Contracts.kt file in its package, and remove the state packages
  • Name the screen file …Host and keep it at the feature root beside the Container
  • Move each ViewModel and the composable that binds it into content/<name>; what used to be a section that bound a ViewModel is now a content
  • Move the stateless overloads that sat beside a binding into a section package, with a <Name>_Preview
  • Replace calls to the renamed assertions and to pulseScreens

See Architecture checks for the details.

v2.2.1

Choose a tag to compare

@kaleidot725 kaleidot725 released this 01 Nov 04:20
d6a6b22

2.2.1 changes how the artifacts are built, not what they contain. The public API and the checks in architecture are the same as 2.2.0.

dependencies {
    implementation("com.github.kaleidot725.PulseDesktop:mvi:v2.2.1")
    implementation("com.github.kaleidot725.PulseDesktop:navigation:v2.2.1")
    testImplementation("com.github.kaleidot725.PulseDesktop:architecture:v2.2.1")
}

Changed

  • The library and the demo target the JVM only, so their sources move from commonMain into jvmMain, and mvi's tests from commonTest into jvmTest
  • The demo's resource modules set generateResClass = always, since the Compose resources plugin generates Res on its own only for resources in commonMain
  • The pull request check pins the git gem to 5.6.0, as danger 9.6.1 fails to load with git 6

Migrating from 2.2.0

Nothing to change.

v2.2.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 31 Oct 05:38
226aab1

2.2.0 adds one check to the architecture artifact. mvi and navigation are unchanged.

dependencies {
    implementation("com.github.kaleidot725.PulseDesktop:mvi:v2.2.0")
    implementation("com.github.kaleidot725.PulseDesktop:navigation:v2.2.0")
    testImplementation("com.github.kaleidot725.PulseDesktop:architecture:v2.2.0")
}

New checks

Assertion Checks
assertDesignSystemIsSplitByKind every file in core/designsystem sits in a package named after its kind (button, card, theme), not at the module's root or under a catch-all such as component, widget, composable or common (part of assertPulseModuleConventions)

This is a module rule of its own, apart from the MVI components that live in a feature's component package.

Migrating from 2.1.0

  • Move the design system's component package apart by kind, such as button, card, table or pane

v2.1.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 25 Oct 14:01
a2c9369

2.1.0 tightens and extends the conventions in the architecture artifact. mvi and navigation are unchanged.

dependencies {
    implementation("com.github.kaleidot725.PulseDesktop:mvi:v2.1.0")
    implementation("com.github.kaleidot725.PulseDesktop:navigation:v2.1.0")
    testImplementation("com.github.kaleidot725.PulseDesktop:architecture:v2.1.0")
}

Changed checks

Check 2.1.0
assertMessagesAreSealedOrDataTypes A message is a sealed class whose cases are data class / data object, or a single data class / data object. Interfaces, including sealed interfaces, are reported
assertSharedUiDependsOnlyOnTheDomain core/ui may also use the design system
assertDomainIsFrameworkFree Matches only jp.kaleidot725.pulse.mvi / .navigation / .architecture, so an app whose own packages start with jp.kaleidot725.pulse is no longer flagged

New checks

Assertion Checks
assertStatesAndMessagesLiveInTheStatePackage states and messages live in a state package (part of assertPulseMviConventions)
assertUseCasesLiveInTheUseCasePackage a …UseCase lives in a usecase package (part of assertPulseDomainConventions)
assertUseCasesDoMoreThanOneLine no public function of a use case is a single line; a ViewModel may call the repository directly (part of assertPulseDomainConventions)
assertDomainIsSplitIntoItsPackages the domain is split into model / repository / usecase (part of assertPulseModuleConventions)
assertDataIsSplitIntoItsPackages data is split into repository / local (a data source that only persists) / model (part of assertPulseModuleConventions)
assertDesignSystemDependsOnNothing core/designsystem depends on nothing but support modules, not even the domain (part of assertPulseModuleConventions)
assertPulseResourceConventions new group: the domain holds no text, and composables read their text with stringResource

Migrating from 2.0.0

  • PulseModuleLayout gets a designSystem layer (default core/designsystem), and sharedUi now defaults to core/ui only. A layout passed with named arguments keeps compiling
  • The aggregate assertions run the new checks, so an app may need to move its message types to sealed classes, arrange its packages, and move its text into composeResources

See Architecture checks for the details.

v2.0.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 25 Oct 05:36
a923690

PulseMVI is now PulseDesktop — a framework for Compose Desktop apps rather than a single MVI
library. 2.0.0 renames the coordinates, so updating from 1.x is a change to your dependency lines and
to one import package.

Migrating from 1.x

The repository moved to kaleidot725/PulseDesktop, which changes the JitPack group, and the artifacts
drop the prefix that repeated the old name.

1.x 2.0.0
Core com.github.kaleidot725.PulseMVI:pulsemvi com.github.kaleidot725.PulseDesktop:mvi
Navigation 3 com.github.kaleidot725.PulseMVI:pulsemvi-navigation3 com.github.kaleidot725.PulseDesktop:navigation
Navigation 3 package jp.kaleidot725.pulse.mvi.navigation3 jp.kaleidot725.pulse.navigation
dependencies {
    implementation("com.github.kaleidot725.PulseDesktop:mvi:v2.0.0")
    implementation("com.github.kaleidot725.PulseDesktop:navigation:v2.0.0")
}

The core package jp.kaleidot725.pulse.mvi and every class name — PulseViewModel, PulseContainer,
PulseContent, PulseHost and the rest — are unchanged. Versions already published keep their old
coordinates.

New: the architecture artifact

The conventions PulseDesktop expects are now Konsist assertions your own test suite runs.

testImplementation("com.github.kaleidot725.PulseDesktop:architecture:v2.0.0")
Assertion Checks
assertPulseMviConventions() state and message types, ViewModel and Container names, the screen / section / component split, and a <Component>_Preview for every component
assertPulseDomainConventions() a repository exposes Flow / StateFlow and returns kotlin-result's Result<V, E> from one-shot calls
assertPulseModuleConventions() modules laid out like Now in Android depend on each other the way Clean Architecture asks; other names through PulseModuleLayout
assertPulseKoinConventions() Koin modules are declared in the app module

See Architecture checks.

Also

  • The demo is a multi-module app — app, feature, and a domain, data and design system under core —
    wired with Koin, keeping its counts in a DataStore, and passing every architecture check
  • Test coverage is measured with Kover, and the pull request check fails below 95% of lines and
    instructions
  • The documentation presents PulseDesktop as a desktop framework, in English and Japanese

What's Changed

🚀 New Features

  • Publish the PulseMVI conventions as Konsist assertions by @kaleidot725 in #26
  • Check a multi-module layout with assertPulseModuleConventions by @kaleidot725 in #32
  • Check how repositories hand out data with assertPulseDomainConventions by @kaleidot725 in #33
  • Require a preview for every component by @kaleidot725 in #34
  • Wire the demo with Koin, and keep Koin modules in the app by @kaleidot725 in #36

🛠 Refactoring

  • Rename the project to PulseDesktop and the artifacts to mvi, navigation and architecture by @kaleidot725 in #28

🐛 Bug Fixes

  • Fix the black text on the dark background in the demo by @kaleidot725 in #35

📝 Documentation

🧹 Maintenance

  • Group documentation PRs in generated release notes by @kaleidot725 in #23
  • Measure test coverage with Kover and gate the pull request check by @kaleidot725 in #24
  • Split the test fixtures out and name each case after the promise it keeps by @kaleidot725 in #25

Full Changelog: v1.0.0...v2.0.0

v1.0.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 13 Sep 04:52
22de4cd

What's Changed

🚀 New Features

  • Hand ViewModel lifetimes to androidx.lifecycle and target the JVM alone by @kaleidot725 in #5
  • Replace the counter demo with a pulse grid, and trim the docs around it by @kaleidot725 in #6

🧹 Maintenance

🪼 Other

  • Add a Japanese translation of the docs site by @kaleidot725 in #8
  • Draw the hero background as a pulse line instead of a photo by @kaleidot725 in #9
  • Keep the Japanese prose ahead of the block it describes by @kaleidot725 in #10
  • Keep the English prose ahead of the block it describes, too by @kaleidot725 in #11
  • Cut the README to what a landing page needs by @kaleidot725 in #12
  • Give Navigation 3 its own section as an extension by @kaleidot725 in #13
  • Draw the diagrams with Mermaid instead of box characters by @kaleidot725 in #14
  • Stop VitePress's paragraph rules from clipping Mermaid labels by @kaleidot725 in #15
  • Make the Navigation 3 guide explain the mechanism, not the setup by @kaleidot725 in #16
  • Shorten the sentences in both locales by @kaleidot725 in #17

Full Changelog: v0.3.0...v1.0.0

v0.3.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 18 May 21:15
838229a

What's Changed

⚡ New Feature

  • Unicast counter values through shared generic types by @kaleidot725 in #1

New Contributors

Full Changelog: v0.2.0...v0.3.0

v0.2.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 14 Mar 03:25

Full Changelog: v0.1.0...v0.2.0

v0.1.0

Choose a tag to compare

@kaleidot725 kaleidot725 released this 14 Mar 03:25