This release introduces Kobweb Workers, a wrapper around the standard web workers technology.
Note
Web workers are a way to create an isolated script that your website can run and communicate with. Web workers run on their own thread, so it's a useful place to put computationally expensive background logic (i.e. stuff that calculates things or manages complicated state and doesn't need to interact with the UI), to avoid affecting the responsiveness and performance of your main site.
Planning to upgrade? Review instructions in the README.
Getting web workers working in vanilla Kotlin/JS can be a bit of a pain (example project here), but if you are writing a Kobweb site, it couldn't be much easier.
You just create a module that applies the Kobweb Worker Gradle plugin and then implement a single interface which provides your worker logic, and Kobweb takes care of the rest. As a bonus, you can also specify rich types for your input and output messages, which we recommend using Kotlinx Serialization to help with:
@Serializable
class CalculatePiInput(val numDigits: Int)
@Serializable
class CalculatePiOutput(val digits: List<Int>)
private fun calculatePi(numDigits: Int): List<Int> { /* ... */ }
internal class CalculatePiWorkerFactory
: WorkerFactory<CalculatePiInput, CalculatePiOutput> {
override fun createStrategy(postOutput: (CalculatePiOutput) -> Unit) =
WorkerStrategy<CalculatePiInput> { input ->
postOutput(calculatePi(input.numDigits))
}
override fun createIOSerializer() = Json.createIOSerializer()
}and after writing that, a CalculatePiWorker class will be automatically generated, easy to use in your Kobweb site:
val worker = rememberWorker {
CalculatePiWorker { output -> println("Pi is 3.${output.digits.joinToString("")}") }
}
// Later, say in response to some input being entered or a button being pressed
worker.postInput(31415)Please check out the official documentation for more details.
Frontend
- Kobweb Worker support 🎉 🎉 🎉
- Refactor non-Compose utility methods and classes out of
compose-html-ext- ⚠️ This could cause a bunch of compile warnings in your project. See notes section for more information.
- ⚠️ This might cause an error if you are using
IntersectionObserver.See notes section for more information.
- Removed "And" from some parameter names for consistency and simplicity.
- ⚠️ Renamed parameters might cause an error in your project. See notes section for more information.
- A bunch of Modifier additions and improvements
- New
accent-colorModifier - New
appearanceModifier - New
caption-sideModifier - New
clearModifier - New
column-ruleModifier - New top-level
fontModifier- Font modifiers have existed for a long time, but now you can do this:
Modifier.font { style(...); size(...) }
- Font modifiers have existed for a long time, but now you can do this:
- New top-level
borderRadiusModifier- Makes it easy to set just the corners you need, e.g.
Modifier.borderRadius { topLeft(5.px) } - Additional support to make it easy to set elliptical border radii
- Makes it easy to set just the corners you need, e.g.
- More methods for configuring color and style added to the top-level
borderModifier
- New
- Removed the requirement for the
cssRuleAPI to start with a space for Descendant selectors- In other words, before:
cssRule(" h1"), after:cssRule("h1") - You can leave the space in if you'd like, e.g. for symmetry with
cssRule(">h1"), but in my opinion, the code reads fine without it.
- In other words, before:
Backend
ApiContext(the context value passed into@Apimethods) improvements- Now includes all headers sent with the request.
- Added a bunch of connection details to the request (so you can know where the request came from, for example)
Gradle
- Fixed an issue with my logic that could sometimes cause Gradle to issue you a spurious demand to add an explicit dependency on ":kobwebGenSiteIndexTask"
Notes
compose-html-ext non-Compose bits refactored into browser-ext
We deprecated quite a bit of code as part of a code migration in this release. You may see a warning with this latest version of Kobweb, something that looks like:
We are migrating non-Compose utilities to a new artifact. Please change your imports to use `com.varabyte.kobweb.browser.example.stuff` instead (that is, `compose` → `browser`).
Unfortunately, the sort of migration we're doing here is not one that we could easily provide instructions to the IDE so it could automatically replace old code with new. You'd end up with code like:
import com.varabyte.kobweb.browser.example.stuff
import com.varabyte.kobweb.compose.example.stuffwhich replaces your easy to understand deprecation warning with an opaque "ambiguity" warning.
If you run into this, the best recommendation I can give you is to manually change the import statement, changing the "compose" part to "browser". For example, com.varabyte.kobweb. to compose.example.stuffcom.varabyte.kobweb.browser.example.stuff.
Rationale for this migration
When we first started working on Kobweb, we needed a place to put utility methods and classes that didn't exist in Compose HTML but wish they did. So we created an artifact that even users who did not use Kobweb could pull into their Compose HTML projects and benefit from.
But we recently realized we could have gone further -- some of these utilities don't depend on Compose! But apply to Kotlin/JS browser projects more generally.
Especially with the introduction of workers (which are modules that don't depend on Compose), we decided to do the migration now.
topAndBottom to topBottom, etc.
As we get closer to 1.0, we're reviewing some of our old code and trying to come up with consistent rules. We made the decision that "and" should not be included when it's obvious from context.
So we decided that some of our original naming was a mistake. This can cause compile errors in projects which reference parameter names like topAndBottom or leftAndRight directly. If that happens, please rename them.
IntersectionObserver API changes
As part of the browser-ext migration discussed above, a minor scar was that the IntersectionObserver class obviously belonged in the non-Compose part, but the API provided by compose-html-ext did use a nice, rich CSSMargin type that ultimately requires Compose HTML.
Therefore, we moved the class into browser-ext but added a new extension constructor in compose-html-ext. If you happened to be using this constructor, you'll get a compile error. You can fix this by importing the extension constructor (which is implemented as an invoke operator on the Option class).
import com.varabyte.kobweb.browser.dom.observers.IntersectionObserver
import com.varabyte.kobweb.compose.dom.observers.invoke // !!! Add this!
// Later
IntersectionObserver(
IntersectionObserver.Options(
rootMargin = margin(leftRight = 10.px) // to allow using `margin`
)
)You could of course consider doing the following, which sidesteps importing "invoke":
import com.varabyte.kobweb.browser.dom.observers.IntersectionObserver
// Later
IntersectionObserver(
IntersectionObserver.Options(
rootMargin = margin(leftRight = 10.px).toString()
)
)Thanks!
We had some new contributors in this release.
- @ellet0 helped us fill out some of the CSS gaps in our APIs (most of the new modifiers in this release)! They also improved site process by adding a new PR testing workflow. I really appreciate their interest in Kobweb -- it's clear they have a lot of ideas for improvements.
- @dieter115 suggested APIs for improving our file loading utilities, allowing loading multiple files at once.
Thanks so much for taking your time to help Kobweb be a better project!!
And perhaps more than usual, thanks to @DennisTsar for helping me navigate myself out of countless dead ends for poor approaches I took with the Worker feature.
Full Changelog: v0.15.3...v0.15.4