Skip to content

Releases: pathosDev/actor-ts

v0.9.1

15 May 00:32
11b4c15

Choose a tag to compare

Docs-only patch — the first round of post-v0.9.0 publish feedback. No code changes; bumping for the README rendering fix on the npm package page.

🐛 Fixed

  • README logo no longer 404s on npmjs.com — relative ./docs/public/logo.png switched to an absolute raw.githubusercontent.com/pathosDev/actor-ts/main/... URL. Relative paths inside raw <img> tags aren't rewritten by npm's README renderer; only Markdown image syntax is.
  • License badge link — relative ./LICENSE switched to an absolute github.com/.../LICENSE URL.
  • License section text — said "MIT" left over from the original metadata-only declaration; corrected to "Apache 2.0" matching the v0.9.0 relicense.
  • Sub-package READMEs (benchmarks/, examples/chat/, examples/voice/) referenced a non-existent assets/logo.svg path. Switched to the same absolute raw.githubusercontent.com/.../docs/public/logo.svg URL — consistent across every README and robust under any rendering target.

v0.9.0

14 May 21:57
8e2627b

Choose a tag to compare

v0.9.0 Pre-release
Pre-release

The "public-launch readiness" release. The framework gets its own website (actor-ts.dev) with 199+ pages and full German translation; the cluster bootstrap shrinks from 15–30 lines to a single Cluster.bootstrap({ name }); eight latent security weaknesses get patched; and a code-quality sprint closes 17 audit-catalog issues.

🚀 New features

Persistence

  • eventDispatcher<S, E>() — typed builder for PersistentActor.onEvent that the compiler refuses to complete until every variant of the event union has a handler. Missing variants surface as EventDispatcherIncomplete<missing> type errors at the build site (#239).

Chat sample feature sweep

  • User-created rooms at runtimeChatRoomDirectoryActor wraps a cluster-wide DistributedData ORSet; protocol gains create-room / room-added / room-removed; six frontends grow a "+ new room" input (#98).
  • Private direct messages — DMs ride existing protocol frames as virtual @<username> rooms; sharded DmChannelActor keyed on the canonical pair-id; each user subscribes once to their inbox topic (#100).
  • Typing indicators — ephemeral TypingBroadcast via the room's PubSub topic; clients debounce at 1/2 s and auto-clear after 3 s (#103 slice 1).
  • Read receipts — per-room read-up-to.<room> DistributedData LWWMap; ReadReceiptsActor enforces a monotonic guard at the boundary; frontends render ✓ / ✓✓ on own messages (#103 slice 2).
  • Production-realistic auth — scrypt-hashed passwords (N=16384/r=8/p=1, constant-time verify); HMAC-SHA256-signed JWT-style session tokens self-validate without a DD read; revocation set in DD-LWWMap (#99).

⚠️ Security

Eight latent security weaknesses patched. All defenses are at the deserialisation / boundary layer with regression tests pinning both the attack vector and the legitimate path.

  • Wire-frame size capcluster/protocol rejects frames claiming gigabyte+ lengths before allocation; defeats a 4-GiB-claim memory-exhaustion DoS. Configurable; Infinity cap remains the escape hatch.
  • Path-traversal block in FilesystemObjectStorageBackend — keys containing .. or absolute-path patterns rejected at the boundary instead of being resolved through to disk.
  • Memcached protocol injectionMemcachedCache keys validated against the 250-byte / printable-ASCII rule before being placed on the wire; defeats injection via attacker-controlled keys.
  • Gossip-version cap against permanent-down exploit — versions more than 24 h above the local wall-clock are rejected on the spot; previously a malicious peer could send version: MAX_SAFE_INTEGER to pin a healed node as down forever.
  • Snapshot-seq validation on recoveryPersistentActor rejects snapshots whose seqNr is non-monotonic with the journal; defeats tampered-snapshot replay.
  • WebSocket inbound frame size capWebSocketActor rejects oversized inbound frames before assembly; defeats memory-exhaustion DoS via fragmented frames.
  • Duplicate-identity hello rejectioncluster/transport refuses a second hello frame claiming an already-connected identity; defeats peer-hijack where an attacker rebinds to a victim's from address. Legitimate reconnect (after clean close) unaffected.
  • Idempotency-key cache bindinghttp/cache/idempotency ties each cached response to the request fingerprint (method + path + body hash) so a poisoned key can't replay one response across different requests.

✨ Quality of life

API shortcuts

  • Cluster.bootstrap({ name }) — one-call setup that builds the ActorSystem, joins the cluster, starts the Receptionist, and wires SIGTERM / SIGINT shutdown. Discovery defaults to an env-driven chain (CLUSTER_SEEDS → Kubernetes API → DNS) so the same code runs single-node in dev and joins an existing cluster in production without a config change.
  • cluster.sharding.start('cart', CartActor, { extractEntityId }) — getter on Cluster plus class-shorthand on ClusterSharding.start(); replaces the previous ClusterSharding.get(system, cluster) + Props.create(() => new CartActor()) ritual.
  • ref.ask<TRes>(msg, timeoutMs?) — method form of the ask pattern with auto-injected replyTo. The free ask(ref, msg) function is removed (pre-1.0, no compat shim).
  • system.spawnTyped(behavior, name) + system.spawnTypedAnonymous(behavior) — method form symmetric to spawn / spawnAnonymous; same pair lands on ActorContext for typed-child creation from untyped parents. The free spawnTyped() + spawnTypedChild() functions are removed.
  • await system.http(8080).bind(routes) — Fastify-default HTTP shortcut. system.extension(HttpExtensionId).newServerAt(...) still works for non-default backends.
  • ActorSystem.create('app', { persistence: { journal, snapshotStore } }) — wire real persistence backends at creation time instead of poking the extension after the fact.

Code hygiene

  • Pattern-match exhaustiveness pass — 9 discriminator-union dispatch sites converted from if/else-or-switch to match(...).exhaustive(); adding a new union variant without a matching arm now fails the typecheck. Touches BrokerActor.enqueueOutbound, JetStreamActor / MqttActor / KafkaActor cmd dispatch, BackoffSupervisor, HoconParser, Compression, BodyCodec, PersistentActor (#230, #232, #233, #234, #239, #240, #241, #243, #244).
  • DRY helperssrc/util/Constants.ts centralises duplicated defaults (gossip interval, ask timeout, tombstone TTL, seed-retry); src/util/LazyImport.ts is the uniform peer-dep import + "missing package" error; src/util/WrapError.ts is the typed-error wrap helper with double-wrap prevention (#257, #252, #254).
  • Typed namessrc/config/ConfigKeys.ts is the typed const-tree for every HOCON path; src/persistence/storage/KeyValidator.ts is a declarative rule-based factory replacing hand-rolled key-safety checks (#265, #251).
  • Naming consistency — every message union now uses kind as discriminator (not a mix of type / op / cmd); ActorSystem.actorOf is gone in favour of spawn / spawnAnonymous; the redundant actor-ts. prefix on worker message kinds is dropped.

📚 Documentation

  • Public website at actor-ts.dev — Astro Starlight site under docs/, 199+ pages across the 12-Part IA, full Quickstart + fundamentals + per-subsystem deep-dives + migration guides + API reference (TypeDoc).
  • Full German translation — every page mirrored under /de/. Seven additional UI locales (fr, es, ja, ko, pt-BR, ru, zh-CN) staged with sidebar labels translated; full content translations tracked as open issues (#300#306).
  • Mermaid diagrams throughout — replaces ASCII art across all subsystem pages (cluster, sharding, distributed-data, persistence, observability, operations, testing, IO, delivery).
  • Landing-page polish — animated particle-network hero, prose-driven "What is actor-ts" cards, See-it-in-action status grid, custom-domain redirect, mobile-responsive splash.
  • Issue templates + security disclosure flow.github/ISSUE_TEMPLATE/ gains security_report.yml; bug template gets a security-flag checkbox.

v0.8.0

14 May 21:31

Choose a tag to compare

v0.8.0 Pre-release
Pre-release

🚀 New features

  • DistributedData quorum writes + readsupdateAsync(key, factory, fn, { consistency }) + getAsync(key, { consistency }); levels 'local' / 'majority' / 'all' / { from: K }. Reads merge incoming responses before resolving; timeouts reject writes (local apply stands) (#81).
  • Outside-in cluster connectivity (ClusterClient) — lightweight handle for REST frontends / batch jobs / operator scripts: send(path, msg) + ask(path, msg, ms?) with round-robin failover across contact-points (#86).
  • reEncryptObjectStorage(backend, opts) — re-encrypt every body under a prefix to the active master key; idempotent on already-current versions; If-Match CAS internally. Closes v0.7.0's rolling-migration Phase-3 (#70).
  • migrateBetweenJournals / migrateBetweenSnapshotStores — copy-with-transform for backend swaps and schema piggybacks; per-pid resume + optional progress store (#87).
  • Extended cluster-management HTTP endpointsGET /cluster/shards?type=<typeName>, POST /cluster/down { address }, GET /metrics (Prometheus); all opt-in (#56).
  • Cluster.down(addr) — public API for operator force-down of a remote peer; backs POST /cluster/down (#56).

v0.7.0

14 May 21:31

Choose a tag to compare

v0.7.0 Pre-release
Pre-release

🚀 New features

  • MQTT 5.0 user properties + reason codes — opt in via protocolVersion: 5; inbound/outbound carry optional userProperties and reasonCode (silently dropped on v3.1.1) (#13).
  • JetStream pull-consumer mode — opt in via consumer.mode: 'pull'; app drives batches via { kind: 'fetch'; batch; expiresMs? } cmds (#62).
  • Cache bulk operationsCache.mget + Cache.mset across all three backends; Redis pipelines SET ... PX for TTL'd msets (#14).
  • ReplicatedEventSourcedActor.lease() — protected hook; when it returns a Lease, the actor enforces single-writer per persistenceId (non-holders observe + throw on persist). onLeaseLost(reason) companion hook (#89).

📚 Documentation

  • docs/operations/rolling-migration.md — four-phase rolling-deploy walkthrough with master-key rotation interleaved (#91).
  • docs/persistence/migration-recipes.md — decision-tree guide across five overlapping migration tools with worked examples + pitfalls section (#93).
  • ClusterEvents.MemberRemoved — JSDoc + README clarify definitive (tombstoned) vs. FD-driven removal paths (#79).

v0.6.0

14 May 21:31

Choose a tag to compare

v0.6.0 Pre-release
Pre-release

🚀 New features

  • Two sample apps with six frontends eachexamples/chat/ (clustered chat: sharded persistent rooms, DD-backed online users, singleton HTTP front door) and examples/voice/ (PTT / group / Teams-style rooms over WebSocket binary frames). Plain / Lit / Svelte / React / Next.js / Angular clients (#94, #95, #96, #97).
  • CRDTs + replicated event sourcing — full CRDT family (GCounter, PNCounter, GSet, ORSet, LWWRegister, LWWMap, ORMap, MVRegister, GCounterMap); DistributedData with gossip replication; ReplicatedEventSourcedActor with vector-clock snapshots and pluggable resolvers (#37, #45, #41).
  • Durable DistributedData — CRDT state survives full cluster restart via per-replica state-store records (#40).
  • Persistence query + projectionsPersistenceQuery (eventsByPersistenceId / eventsByTag), ProjectionActor with at-least-once delivery + offset persistence; push via JournalEventBus; SQLite tag join table; multi-tag all/any/not filter (#36, #42, #43, #44, #90).
  • Cluster sharding hardening — rebalance + daemon failover hardening; persistent ShardCoordinator allocation state; persistent Remember-Entities; maxEntities + LRU passivation; Cassandra-backed RememberEntitiesStore; member-tombstone pruning (#35, #39, #49, #82, #84, #75).
  • Split-brain-safe handovers via Lease — real KubernetesLease (replaces v0.2.0 stub); optional Lease on ClusterSingleton + ShardCoordinator; DowningProvider wired into FD; LeaseMajority resolver (#33, #38, #60, #61, #51).
  • MultiNodeSpec + ParallelMultiNodeSpec — in-process and worker-thread cluster test harnesses with partition / heal helpers and awaitMembers / awaitLeader (#34, #46).
  • Observability stack — Prometheus export + OTel-style tracing (W3C traceparent) + LogContext MDC; bridges to prom-client and @opentelemetry/api keep both SDKs optional (#11, #10, #53, #64, #63).
  • PersistentFSM — FSM + event sourcing; guard checks, replay-driven rebuild, per-state stateTimeout, multi-event transitions via persistAll (#52, #65, #66).
  • BackoffSupervisor — exponential backoff with optional stash; triggerOn: 'failure' | 'stop' | 'any'; opt-in strict post-respawn message gating (#48, #68, #67).
  • ClusterRouter — cluster-aware router with role filter and round-robin / random / consistent-hashing / broadcast strategies (#50).
  • context.throttle({ qps, burst, onExcess }) — per-actor token-bucket rate limiter (#83).
  • Schema migration toolkit — chain upcasters + downcasters; writeVersion for rolling deploys; bulk migrators; pluggable codec + InMemorySchemaRegistry with compatibility checks (#6, #7, #9).
  • Master-key rotation for AES-256-GCM snapshotsMasterKeyRing with key-version byte in body manifest; legacy single-key bodies still readable (#8).
  • Production broker integrations — Kafka exactly-once via commitMode: 'manual'; NATS JetStream actor; server-side WebSocket with Bun-native handler bindings (#2, #3, #1).

🐛 Bug fixes

  • DistributedPubSubMediator gossip size + race window — frame size proportional to topic count; eager broadcast closes the ~3 % publish-after-subscribe gap (#80).
  • FilesystemObjectStorageBackend multi-process safety — disk-canonical FNV-1a etag; per-key lock files; atomic temp-rename writes; NTFS-quirk retries (#19).
  • Batched correctness items — eager peer-dep validation at plugin-init; ORSet / GSet identity for non-JSON values; single-actor-per-pid in ReplicatedEventSourcedActor (#18, #59, #57, #58).

v0.5.0

14 May 21:31

Choose a tag to compare

v0.5.0 Pre-release
Pre-release

🚀 New features

  • BrokerActor base — reconnect-with-backoff (optional CircuitBreaker), outbound buffer, subscriber fan-out, EventStream lifecycle events.
  • Broker actorsTcpSocketActor, UdpSocketActor, MqttActor, WebSocketActor, KafkaActor, AmqpActor, GrpcClientActor, GrpcServerActor, NatsActor, RedisStreamsActor, SseActor.
  • Examplesmqtt-temperature.ts, websocket-feed.ts, grpc-sensor.ts under examples/io/.

v0.4.0

14 May 21:31

Choose a tag to compare

v0.4.0 Pre-release
Pre-release

🚀 New features

  • Object-storage persistenceObjectStorageBackend + Filesystem (built-in) + S3 (lazy AWS SDK; works with AWS, MinIO, R2, Backblaze B2, Wasabi).
  • BodyCodec — manifest header with gzip / zstd compression and AES-256-GCM encryption (HKDF per-pid subkeys, compress-then-encrypt).
  • Snapshot/state stores on object storageObjectStorageSnapshotStore + ObjectStorageDurableStateStore with per-prefix codec resolvers.
  • Schema migrationEventAdapter / SnapshotAdapter / StateAdapter interfaces + versioned envelope wire format + MigrationChain upcasters + defaultsAdapter for code-free additive evolution.
  • Cache abstractionCache interface with InMemory / Redis / Memcached backends; CacheExtension for named registration.
  • HTTP middlewarerateLimit, idempotent (Stripe-style), cached (stampede-protected response cache).

✨ Quality of life

  • CachedSnapshotStore decorator — absorbs cold-start storms after sharding rebalance.

v0.3.0

14 May 21:31

Choose a tag to compare

v0.3.0 Pre-release
Pre-release

🚀 New features

  • Persistence stackJournal / SnapshotStore / DurableStateStore interfaces; PersistentActor (event sourcing with snapshotPolicy) and DurableStateActor (snapshot-only with strict CAS).
  • Persistence backends — InMemory (default), SQLite (Bun via bun:sqlite, Node via better-sqlite3, abstracted by a SqliteDriver), Cassandra (lazy cassandra-driver).
  • HTTP service stack — directive-style DSL compiling to a backend-agnostic CompiledRoute; Fastify (default) / Express / Hono backends, each auto-detecting the right serve primitive per runtime.
  • HttpClient — outbound HTTP via the same backend abstraction.

v0.2.0

14 May 21:31

Choose a tag to compare

v0.2.0 Pre-release
Pre-release

🚀 New features

  • Configuration — HOCON parser with ENV interpolation, Duration / Size types.
  • Serialization — JSON + CBOR via Serializer<T> (manifest tagging) + SerializationExtension.
  • Coordinated shutdown — 12-phase dependency-ordered runner; Lease abstraction with in-memory + Kubernetes impls.
  • Cluster fabric — TCP / in-memory / worker-thread transports, gossip membership, Phi-Accrual failure detection.
  • Cluster shardingShardCoordinator, ShardRegion, hash + least-shard allocation, Passivate, ShardedDaemonProcess.
  • Pub-sub + service registryDistributedPubSubMediator, Receptionist, ClusterSingleton, ReliableDelivery.
  • Split-brain resolversKeepMajority, KeepOldest, StaticQuorum, KeepReferee.
  • Seed providers — Config, DNS (with TTL cache), Kubernetes API, Aggregate.
  • Management HTTP endpoints/health, /ready, /cluster/state.

v0.1.0

14 May 21:31

Choose a tag to compare

v0.1.0 Pre-release
Pre-release

🚀 New features

  • Actor coreActor base with lifecycle hooks + ActorRef / ActorContext / ActorPath / ActorSelection.
  • System primitivesActorSystem, Props, Extension registry, internal SystemMessages control protocol.
  • SupervisionOneForOneStrategy / AllForOneStrategy with Resume / Restart / Stop / Escalate directives.
  • Mailbox variants — unbounded, bounded (three overflow policies), priority, per-actor stash.
  • Lifecycle plumbingActorCell, Guardian, DeadLetterRef; death watch, ReceiveTimeout, become / unbecome, per-actor TimerScheduler.
  • Runtime — real-timer + manual schedulers, dispatcher variants, leveled Logger, system-wide EventStream.
  • Typed Behaviors DSL — functional facade over the OO API (receive, same, stopped, setup, supervise).
  • TestKitTestProbe + ManualScheduler (virtual clock).
  • Patternsask, retry, CircuitBreaker, Router, after, pipeTo.
  • FSM DSL — named-state finite-state-machine actor base.
  • Utility primitivesOption<T>, Lazy<T>, Try<T>, Either<L,R>.