Repository navigation
Releases: sideeffffect/dapr4s
Release list
v3.0.0 — Typed Dapr errors, invokeHttp, sbt build
Every sidecar error is now a dapr4s exception, service invocation exposes HTTP status and headers, and the build moved to sbt.
Breaking
-
Typed Dapr errors. Every sidecar error now arrives as a subclass of the sealed
dapr4s.DaprException. Java SDK exceptions andjs.JavaScriptExceptionno longer reach your code. The subclasses:ComponentNotFoundException(componentKind, name)PermissionDeniedExceptionAppUnreachableException(appId)InvokeHttpException(appId, method, status, body)DaprApiException(errorCode)
Update any
catchofio.dapr.exceptions.DaprException. The mapping table is inwiki/dapr/dapr-error-codes.md. -
Typed
invokethrows on non-2xx. It throwsInvokeHttpException, the same on JVM and JS. 3xx counts as non-2xx. -
UnlockStatus.LockBelongsToOthers. Unlocking a lock that another owner holds returns this new case. Before, it returnedInternalError. Exhaustivematches need the new case. -
Scala.js 1.22.
dapr4s_sjs1_3is built with Scala.js 1.22, so consumers need a 1.22 linker.
Features
InvokeCapability.invokeHttp. It returnsInvokeResponse(status, headers, body)and never throws on status. It takes headers and query parameters.
Build
- dapr4s builds with sbt instead of scala-cli (PR #42).
- ScalablyTyped facades are generated inside the build.
- The scala-cli 1.14.0 pin and the facade and Wasm workaround scripts are gone.
- Published coordinates are unchanged:
com.github.sideeffffect:dapr4s_3anddapr4s_sjs1_3.
Docs
- Wasm component proposal.
docs/WASM-COMPONENTS-PROPOSAL.mddescribes how to target WASI components through dapr-wasm-components v0.7.0. - Wiki. New articles on the WIT overlap and on Dapr error codes.
v2.0.0 — Capability tiers: universal XCapability + Instance + ReadOnly
Highlights
A new capability API: universal XCapability + Instance + ReadOnly tiers. This is a breaking change (#40).
- Universal capability per building block.
DaprCapability.statereturnsStateCapability, which reaches any store:StateCapability.save(storeName, key, value). The same holds for publish, invoke (appIdper call), secrets, configuration, bindings, lock, crypto, workflow, actor, and, on the JVM, jobs and conversation. - Narrow by name with
instance(name). It returnsXCapability.Instance, bound to one resource:dapr.state.instance(store).get[T](key). - Narrow by authority with
ReadOnly. State, Secrets, Configuration, Jobs and Workflow haveX.ReadOnlyandX.Instance.ReadOnly. Narrowing a read-only capability by name stays read-only, which the compiler checks. - Actor has two levels:
ActorCapability.forType(actorType).instance(actorId). - Companion forwarders and accessors on every interface. For example,
StateCapability.Instance.save(key, v)uses the capability inusingscope, andStateCapability.ReadOnly.instance(store)returns the narrowed capability. - Handle-style sugar that respects the tiers:
WorkflowInstanceId:id.waitForCompletion(timeout)andid.getStatusneed onlyWorkflowCapability.ReadOnly;id.suspend(),id.terminate()and the other mutations needWorkflowCapability.JobName(JVM):name.get,name.scheduleOnce(...)andname.delete().
- One package per family:
dapr4s.state,dapr4s.invoke,dapr4s.workflowand so on. Cross-cutting types stay indapr4s.
Migrating from 1.x
- Add family imports, e.g.
import dapr4s.state.*, dapr4s.workflow.*. - Code that is bound to one store, inside a
DaprCapability.state(name) { ... }block, now usesStateCapability.Instance. For example,(using StateCapability)becomes(using StateCapability.Instance), andStateCapability.get(key)becomesStateCapability.Instance.get(key). dapr.state(name)becomesdapr.state.instance(name).dapr.actor(t)(id)becomesdapr.actor.forType(t).instance(id).- These types were removed:
Access*Capability,WorkflowInstanceCapability,ActorTypeCapabilityandJobCapability. - dapr4s-examples shows the full migration.
Features
- Universal /
Instance/ReadOnlycapability tiers for all building blocks; derivation macros require the narrowest tier (#40). - Tier-aware handle sugar on
WorkflowInstanceIdandJobName(#40). - One package per capability family (#40).
Fixes
- Scaladoc: 94 unresolved links fixed. JVM and Scala.js scaladoc now report 0 warnings.
Build / CI
- Fixed a silent hang in the Scala.js integration tests. scala-cli chose
__loader.jsinstead ofmain.jsas the Wasm test entry when its temp dir was on ext4. The test harness now runs scala-cli with its temp dir on tmpfs. Upstream fix: VirtusLab/scala-cli#4548. - scala-cli is pinned to 1.14.0, because newer versions with the Scala.js 1.22 linker cannot link
js.asyncon Wasm without a JSPI switch. The integration step now has a 20-minute timeout. - Publishes of the same version are serialized with a concurrency group.
Docs
- New
docs/CAPABILITY-HIERARCHY.md: one Mermaid class diagram per capability family. docs/CAPABILITY-SPLITS.md§11 describes the implemented design. DESIGN.md, README and SPEC.allium are updated, andallium checkreports 0 errors.
v1.0.0
First stable release of dapr4s — a cross-platform (JVM + Scala.js/Wasm) Scala 3 library for Dapr.
Library fixes
- Actor & workflow clients now honour the configured sidecar endpoint.
ActorClient/DaprWorkflowClientwere built with no-arg constructors that defaulted tolocalhost:3500/50001, ignoringDaprConfig.sidecar— so actors and workflows broke against any non-default sidecar port. They now receive the endpoint/TLS/token overrides viaDapr.sidecarProperties. bulkPublishencoding fixed. Events were double-encoded (JSONStringthrough the wrongpublishEventsoverload, which also dropped per-entry ids), leaving them undeliverable. Now usesBulkPublishRequest<byte[]>with raw bytes and explicit entry ids.- Workflow gRPC channel no longer leaks on shutdown. The
DurableTaskGrpcWorkerchannel is now closed on the server'sInterruptedExceptionpath (removes theManagedChannel allocation sitewarning at teardown).
Testing
- Actor / PubSub / Invoke / Workflow integration suites are now single cross-platform classes in
test/shared— JVM and Scala.js run the same test bodies, with only setup coming from per-platform fixtures. Each platform gained the other's previously-missing cases (real server-delivery coverage, not raw-HTTP shortcuts). - JVM and JS test-infrastructure files and types now mirror each other (
ServerDaprItSuite/ServerDaprItEnv/SharedDaprItSuite/TestCodecs), so the two trees read as twins.
Full Changelog: v0.20.1...v1.0.0
v0.20.0
Cross-compile dapr4s to Scala.js — ScalablyTyped facades over the Dapr JS SDK, Wasm+JSPI direct style (#38).
Highlights:
- New
dapr4s_sjs1_3Scala.js artifact (self-contained: the ScalablyTyped facade is embedded; the POM references Maven Central only). - Shared/JVM/JS source layout with platform traits; Jobs and Conversation remain JVM-only.
- Unified integration-test harness: one shared Dapr component set (redis everywhere) and shared scenario traits driving both platforms.
v0.19.0 — caller/callee dual derivations (deriveChecked)
Each Dapr building block is a dual pair (app→Dapr caller ↔ Dapr→app callee). This release lets one shared trait bind and type-check both sides.
Highlights
deriveChecked[Contract, Impl]added (alongside the unchangedderive) onInvokeRoutes,Subscriptions,ActorDefinitions,JobRoutes,WorkflowActivities, andWorkflowActivityCalls: the macro verifies the impl answers every contract method with matching request/response types, matched by method name or wire name (topic / job / actor) as appropriate.- New server-route engines
BindingRoutes.deriveandJobRoutes.derive— filling the previously-asymmetric Bindings and Jobs pairs. Actor.derivenow also schedules reminders/timers: a@reminder/@timermethod forwards toActorContext.registerReminder/registerTimer;ActorDefinitions.deriveCheckedverifies them against the actor's@reminder/@timerroutes.- Dual cross-reference docs on the capability traits and route types.
Additive over v0.18.0 (no breaking changes). Bindings has no deriveChecked — output operations vs input payload-delivery are independent directions, not a request/response contract.
v0.18.0 — Unified capability nomenclature
This release unifies the naming of every Dapr building block around the short name Dapr uses in its HTTP path, keeping Scala conventions (UpperCamel, *Capability suffixes). One concept, one stem — no more ServiceInvocation vs Invoker vs Invocation for the same thing.
⚠️ Breaking change. Public capability traits, op-types, companion accessors, theDaprApproute field, and several model types are renamed. Mechanical find-and-replace upgrades most code; see the mapping below.
Highlights
ServiceInvocationCapability/Invoker*/Invocation*→Invoke*(matches/v1.0/invoke)PubSubCapability→PublishCapability(the client capability is publish-only;PubSubNamekept — it is Dapr's literalpubsubname)DistributedLockCapability→LockCapability(matches/v1.0-alpha1/lock)Config*→Configuration*(matches/v1.0/configuration)- Conversation value types singularised to match their cardinality
Refactors
Service invocation → Invoke
ServiceInvocationCapability→InvokeCapabilityInvocationRoute→InvokeRoute,InvocationRequest→InvokeRequest,InvocationMethodName→InvokeMethodName- Derivations
ServiceInvocation/InvocationRoutes/ServiceInvocationDerivationRuntime→Invoke/InvokeRoutes/InvokeDerivationRuntime - Accessor
DaprCapability.invoker→DaprCapability.invoke;DaprApp.invocationsfield →DaprApp.invokeRoutes
Pub/Sub → Publish
PubSubCapability→PublishCapability; accessorDaprCapability.pubsub(...)→DaprCapability.publish(...)PubSubNameunchanged (Dapr's component identifier)
Lock
DistributedLockCapability→LockCapability
Configuration
ConfigKey/ConfigStoreName/ConfigValue/ConfigVersion/ConfigItem/ConfigUpdate→Configuration*- Accessor
DaprCapability.config(...)→DaprCapability.configuration(...)
Conversation
ConversationTools→ConversationTool,ConversationToolCalls→ConversationToolCall,ConversationResultChoices→ConversationResultChoice
Bindings
- Accessor
DaprCapability.binding(...)→DaprCapability.bindings(...)
Docs
DESIGN.md,SPEC.allium,derivation.md,validation.md, andAGENTS.mdupdated to the new nomenclature.
No behavioural changes — renames only. Verified with the full unit (33) and integration (90) suites green.
v0.17.0 — Configurable derive overloads
Highlights
The three name-bound derivations now each offer two derive overloads — pass the name explicitly, or let it be derived from the type's simple name (honouring @name):
| Derivation | Explicit | Name-derived |
|---|---|---|
ActorDefinitions |
derive[C](actorType: ActorType) (new) |
derive[C] → ActorType from the class name |
ServiceInvocation |
derive[T](appId: AppId) |
derive[T] → AppId from the trait name (new) |
Subscriptions |
derive[T](pubsubName: PubSubName) |
derive[T] → PubSubName from the type name (new) |
// explicit
val svc = ServiceInvocation.derive[GreetingService](AppId("greeting-service"))
// name-derived — AppId("GreetingService")
val svc = ServiceInvocation.derive[GreetingService]ActorDefinitions gains the explicit-ActorType form (it previously only derived from the class name); ServiceInvocation and Subscriptions gain the name-derived form (they previously required the name). All additions are backward compatible.
Features
- Add name-deriving
deriveoverloads forActorDefinitions,ServiceInvocationandSubscriptions. Name resolution goes through a newMacroSupport.derivedTypeName, which honours@nameon the type and strips a module's trailing$soFoo.typeyieldsFoo.
Docs
- Mandate auto-commit/push and curated GitHub Releases in
AGENTS.md.
Full Changelog: v0.16.0...v0.17.0
v0.9.0
Breaking changes
Each Dapr building block now gets its own name/key opaque type — one can no longer be passed where another is expected.
MethodName→InvocationMethodName(service invocation) /ActorMethodName(actors).StoreName→StateStoreName(.state) /LockStoreName(.lock).StateKey→StateStoreKey(app state) /ActorStateKey(per-actor state).
Migration
Replace MethodName with InvocationMethodName or ActorMethodName; StoreName with StateStoreName/LockStoreName; StateKey with StateStoreKey/ActorStateKey. See dapr4s-examples for the upgraded usage.
Other
- Docs reorganized under
docs/; CI and Maven Central badges added to the README.
Full Changelog: v0.8.1...v0.9.0
v0.8.1
- Fix: stop double-encoding binding payloads (
invokeBindingbyte[]in/out).
Full Changelog: v0.8.0...v0.8.1
v0.8.0
Breaking: inject ActorContext into ActorDefinition build via a context function.
Full Changelog: v0.7.0...v0.8.0