Skip to content

Releases: camcima/finita

Release 4.1.0

Choose a tag to compare

@camcima camcima released this 10 Jul 01:12
  • Merge pull request #38 from camcima/fix/architecture-review-remediation (1b39bbc)
  • test: pin chained-enqueue queue-limit rejection; clarify docs (9afdf94)
  • test: cover checkTransitions branch of QueueLimitExceededError (3a92827)
  • feat: add onReleaseError diagnostic hook for lock release failures (f6058bc)
  • feat: add maxQueueLength back-pressure option (83a425b)
  • feat: add onChainedOperationError sink and document completion boundary (0d94ddf)
  • feat: add Statemachine.whenIdle() to await full queue drain (14d601b)
  • fix: make Statemachine observer attach idempotent (aeba9db)
  • fix: keep ProcessBuilder reusable after a failed build (457da0c)
  • fix: restrict graph rankdir/direction options to valid values (6607d81)
  • fix: freeze State and Transition to match documented immutability (d466c7d)
  • fix: validate transition weights and WeightTransition epsilon (98b07b2)
  • docs: fix unsafe Redis lock example, document mutex ownership contract (08cd042)
  • Merge pull request #31 from camcima/dependabot/github_actions/actions/checkout-7 (01ee42f)
  • build(deps): bump actions/checkout from 6 to 7 (b7b45e0)
  • Merge pull request #27 from camcima/dependabot/github_actions/codecov/codecov-action-7 (ecbd461)
  • build(deps): bump codecov/codecov-action from 6 to 7 (3588652)
  • Merge pull request #34 from camcima/ci/codecov-test-results-action (d076565)
  • ci(codecov): upload test results via codecov-action (drop deprecated action) (f17bbc0)
  • Merge pull request #33 from camcima/ci/codecov-tokenless-oidc (cdbb369)
  • ci(codecov): switch to tokenless OIDC upload (bc56248)

Release 4.0.0

Choose a tag to compare

@camcima camcima released this 23 Jun 08:42
  • Merge pull request #29 from camcima/fix/code-review-v3.0.1 (b53efe3)
  • ci(osv-scanner): filter dev-only undici/esbuild/js-yaml advisories (e7f48e0)
  • fix(statemachine): guard every event observer and transition condition against re-entrancy (cb80489)
  • build(deps-dev): bump vitest to 3.2.6 to fix GHSA-5xrq-8626-4rwp (8911c05)
  • test: close remaining coverage gaps to 100% across all metrics (b71d0fe)
  • docs: document ReentrancyError; correct and complete migration notes (c9d0cf7)
  • fix(statemachine): surface lock-release failures; guard selector; restore zero-arg callback (129280b)
  • fix(statemachine): reject empty initialStateName instead of silently restarting (36272aa)
  • docs: update observer/event/builder docs and migration notes for review fixes (1064703)
  • refactor(condition): extract CompositeCondition base for And/OrComposite (8ff3365)
  • refactor: share isNamed/nameOrString via src/util (ba9178b)
  • fix(condition): timeout throws InvalidSubjectError; allocation-free time check (4ab8a8e)
  • fix(graph): escape backslashes in DOT/mermaid output; guard event lookup in labels (2f3fd72)
  • test(event): replace stale getInvokeArgs assertions with new args-delivery contract (b42f843)
  • fix(event): pass invoke args to observers; drop racy invokeArgs field; inline Dispatcher (8bb6581)
  • fix(statemachine): validate maxAutomaticHops is a positive integer (e9a4001)
  • fix(statemachine): bound automatic loops with maxAutomaticHops instead of first-revisit detection (16cc1b5)
  • fix(statemachine): reject (not throw) on re-entrancy; broaden re-entrancy tests (5ad2514)
  • fix(statemachine): throw ReentrancyError on re-entrant trigger instead of deadlocking (3655026)
  • docs(observer): clarify onEnter ifStateName contract and test intent (847b363)
  • test(observer): add pre-fix-failing regression for stale onEnter lock acquisition (0fb4b83)
  • fix(observer): onEnter fires only for rest states via enqueue ifStateName guard (726024a)
  • test(observer): prove StatefulStatusChanger isolation with two machines; pin precedence (0332853)
  • fix(observer): statefulStatusChanger writes to frame.subject; correct factory docs (d72ce2b)
  • test(observer): assert frame.subject referential identity; document logger omission (1a65fc2)
  • feat(observer): expose subject on TransitionFrame; share one frame per transition (44ae06c)
  • fix(statemachine): snapshot observer lists before notifying (eed53a7)
  • fix(statemachine): settle caller promise only after mutex release completes (7501123)
  • fix(statemachine): kick runner from EnqueueContext.enqueue; single enqueue path (7e84451)
  • refactor(builder): capture condition name once; assert padded-condition error code (67b07ff)
  • fix(builder): validate state names; unify name rule across state/event/condition (ac7b38d)
  • test(builder): assert weight-conflict payload and message (9f6cfb5)
  • fix(builder): detect conflicting weights on duplicate transitions, unify identity key (fbd571d)
  • fix(selector): make WeightTransition epsilon ties order-independent (44f30d2)
  • docs: add code review report for v3.0.1 (39d4459)

Release 3.0.1

Choose a tag to compare

@camcima camcima released this 30 May 21:42
  • build(deps): bump dev-dependencies and github-actions (#25) (c9b640a)
  • build(deps-dev): bump the dev-dependencies group with 4 updates (#18) (a13a97a)

v3.0.0 — execution engine rewrite, typed errors, hardened builder

Choose a tag to compare

@camcima camcima released this 01 May 10:27
d7c9e8b

First v3 release. Major rewrite landed across 55 commits in PR #17 plus follow-up fixes.

Highlights

Graph + execution rewrite

  • New ProcessBuilder with two-phase build: every Transition targets a real State instance, even under cycles and self-loops.
  • Statemachine execution engine rewritten to pump operations through a FIFO queue, separating the active-transition filter from the transition selector and properly modeling lifecycle phases (proposed → before-observers → commit → after-observers → optional auto-chain).
  • New observer surfaces: BeforeTransitionObserver and AfterTransitionObserver with TransitionFrame / ProposedTransitionFrame immutable payloads.

Typed error hierarchy

  • New FinitaError base class with code discriminant.
  • New typed errors: ProcessFinalizedError, GraphValidationError, DuplicateTransitionError, StateNotFoundError, StateEventNotFoundError, ProcessNotFoundError, InvalidSubjectError, AmbiguousTransitionError, AutomaticTransitionCycleError.
  • Stricter input validation: whitespace-padded event names rejected; empty/whitespace condition names rejected.
  • GraphBuilder.addState made idempotent (closes #14).

Packaging and CI

  • prepublishOnly hook + engines.node range tightened (Node ≥20).
  • CI matrix: Node 20, 22, 24.
  • New CI job: npm pack --dry-run verification gate.
  • Codecov configured with project floor at 80%, no per-diff patch threshold.

Review-driven bug fixes folded into 3.0.0

  • runOperation honors an already-held mutex via isAcquired() short-circuit. Manual lock management with autoreleaseLock: false now composes correctly with non-idempotent mutexes (`pg_try_advisory_lock`, redis `SET NX`).
  • Builder treats different condition object instances as conflicts regardless of name. Same reference dedups; different references throw DuplicateTransitionError.
  • Event observers fire on event resolution, not state change. Self-transitions and false-condition matched events now fire event.attach()-style observers, matching the documented Observer Lifecycle.

Breaking changes from v2

  • API: state machines must be built via ProcessBuilder and frozen before use. Direct addState/addTransition on graphs is gone.
  • Observers: before/after observers now operate on immutable TransitionFrame / ProposedTransitionFrame. Event-attached observers fire whenever the event is resolved on the current state.
  • Conditions: dedup is by object identity, not by name. Two CallbackCondition("foo", ...) instances with different bodies now throw DuplicateTransitionError instead of silently merging.
  • Errors: all framework errors now extend FinitaError and carry a code discriminant.
  • Validation: whitespace-padded event names and empty/whitespace condition names now throw GraphValidationError at build time.

See `docs/migration/v2-to-v3.md` for the full migration guide.

Quality gates

  • 278 tests across 19 files
  • Coverage: 98.62% statements, 99.55% functions, 95.57% branches, 98.62% lines
  • `pnpm lint`, `pnpm build`, `pnpm format:check`, `npm pack --dry-run` — all clean
  • 76.6 kB tarball, 9 files

🤖 Generated with Claude Code

Release 2.0.0

Choose a tag to compare

@camcima camcima released this 25 Mar 09:37
  • feat: add TSubject generic parameter for type-safe subject access (d3ffc3c)
  • Update all imports and install commands to @camcima/finita (73a45ae)

Release 1.0.0

Choose a tag to compare

@camcima camcima released this 25 Mar 01:12
  • Scope package as @camcima/finita for npm publishing (6f97c95)
  • Add release-it for automated releases (d62cf61)
  • Initial commit (f5b9f97)