Breaking
@Actoris renamed to@RemoteActor— a clean break, no deprecation alias. The wrapper names the authoring-model perspective: from the client island's point of view, the injected actor lives across the web boundary. (@ServerActorwas rejected for its one-edit distance from@ServerAction.)
New
ActorScope — identity as a small algebra
Declare where a virtual actor's identity key comes from, instead of enumerating scope cases:
.derived(_:_:)— the server derives the key from the trusted invocation context; authorization is identity-match, automatic. Presets:.application,.user,.tenant,.session..addressed(authorization:)— the caller names the key (rooms, documents); an authorization policy is required by the type system..transient— no durable identity.- Scopes compose with
+into composite identities (contract:user:<uid>:<entity>) with segment rules AND-ed.
ActorGroup(scope:) registers the scope's implied authorization; external invocations addressed outside the caller's derived prefix are denied.
Passivation and lifecycle hooks
ActorGroup.passivation(.afterIdle(.minutes(5)))— per-contract idle passivation override.WebActorLifecycle: optionalactivated()(runs after grain state restore — cold start and resume are the same path) andpassivating()(last work before hibernation; mutated state is persisted).- Combining
.transientwith a passivation policy is a scene configuration error.
Durable reminders (Orleans-style)
reminders.set(_:in:/at:),cancel,pendingon anyWebActorSystemactor.- Reminders fire while the actor is passivated and re-activate it: state restore →
activated()→WebActorRemindable.reminder(_:)→ state save. WebActorReminderStoreis the durable backend contract (Cloudflare host lowers onto Durable Object Alarms);InProcessActorReminderStoreships for native hosts and tests. Scheduling without a store throws.
@RemoteState (server core)
@RemoteState("key")on a server actor publishes JSON-encodedRemoteStateChangevalues through the installedWebActorStatePublisheron every write, bound to the actor's identity at activation. The WebSocket host fans changes out to observing client islands.
Notes
WebActorInvocationContextgainstenantID.- 218 tests passing (205 Swift Testing + 13 XCTest macro tests).