cap-nodejs

CAP Node.js and DotNetCore.CAP

Revision-specific comparison. This comparison reflects the repository revisions in Verification revisions. Both projects continue to evolve, so a capability status may change after those revisions.

Relationship and attribution

CAP Node.js is inspired by the architecture and operating model of DotNetCore.CAP, including durable outbox/inbox persistence, broker-based publish/subscribe, consumer groups, background retries, and operational message management.

CAP Node.js is an independent TypeScript implementation for the Node.js ecosystem. It is not an official DotNetCore.CAP port, is not affiliated with or endorsed by the DotNetCore.CAP maintainers, and does not guarantee API, database-schema, wire-format, or behavioral compatibility. It is not a drop-in replacement and is not described as feature-complete with DotNetCore.CAP.

Shared architectural model

Both projects use durable records to bridge an application database and a broker: application transaction, published/outbox record, background dispatch, broker consumer group, received/inbox record, subscriber execution, then success, retry, or terminal failure. Similar architecture does not make record schemas, status names, transport bodies, or public APIs interoperable.

Delivery semantics

Messaging and subscriber processing use at-least-once semantics. Under failures, retries, broker redelivery, stale-message recovery, or process crashes, application work may execute more than once. Neither project provides general end-to-end exactly-once delivery.

Subscriber work must be idempotent. Applications can use unique business constraints, set-to-value updates, processed-operation IDs, and external API idempotency keys; CAP Node.js does not automatically provide these mechanisms. CAP Node.js intentionally does not atomically commit subscriber business state and received/inbox processed state. This nontransactional consume/retry design is not a DotNetCore.CAP compatibility guarantee.

Subscriber and consumer-group behavior

A logical subscription is scoped by topic and consumer group. Groups are independent. For order.created with billing, inventory, email, and analytics, a failure in email yields this conceptual outcome:

billing    processed
inventory  processed
email      failed / retried
analytics  processed

Only email retries; no global transaction rolls successful groups back. Instances consuming the same topic and group are competing consumers/load balanced according to their broker. CAP Node.js also rejects duplicate local (topic, group) handler registration in one engine process; that is not a broker-wide uniqueness guarantee.

Retry and recovery model

CAP Node.js retries durable failed inbox/outbox rows and recovers stale inbox pending rows older than scheduler.inboxFallbackWindowMs (four minutes by default). A too-short window can duplicate slow/backlogged handler work. DotNetCore.CAP documents recovery of Scheduled and Failed records via FallbackWindowLookbackSeconds. CAP Node.js pending/failed terminology and schemas are independent.

DotNetCore.CAP has an optional database retry-scanner lock (UseStorageLock). CAP Node.js instead has fenced claim/lease ownership for first-party outbox dispatch where storage supports it. Inbox retry has no transaction-held, per-message claim through handler completion, so CAP Node.js does not guarantee exactly one inbox retry across a cluster. Scanner coordination and handler ownership are different concerns.

Feature-status methodology

Label Meaning
Supported Implemented and backed by current code plus tests or current first-party documentation.
Partial Implemented with meaningful provider, framework, concurrency, or operational limits.
Different model Both projects address it with materially different APIs or semantics.
Not supported No implementation exists in current code.
Planned Explicitly on the current CAP Node.js roadmap but absent from implementation.
Not verified Evidence is insufficient to make a responsible claim.

CAP Node.js entries prioritize implementation and tests, then first-party docs. Roadmap evidence supports only Planned. DotNetCore.CAP entries use only the official sources linked below.

Side-by-side capability matrix

Foundation and publishing

Capability CAP Node.js DotNetCore.CAP Important difference
Language/runtime Supported — TypeScript/Node.js. Supported — .NET. Separate ecosystems.
Framework-neutral core Supportedcap-core ports. Supported — standalone event-bus use. APIs differ.
Primary framework integration Supported — NestJS; Express too. Supported — ASP.NET Core DI/middleware. Framework APIs differ.
Modular package architecture Supported — independent npm packages. Supported — NuGet providers. Versions are not comparable.
Durable outbox/published storage Supported. Supported. Schemas differ.
Durable inbox/received storage Supported. Supported. CAP Node.js uses (group, dedupeKey).
At-least-once processing Supported. Supported. Idempotency remains required.
Exactly-once end-to-end Not supported. Not supported. Never claimed.
Custom headers Supported — primitive headers. Supported. Header mappings differ.
Message version isolation Not verified — no comparable public application-version isolation option was verified. SupportedCapOptions.Version isolates messages across service versions. This is not evidence of a shared wire envelope.
Portable CAP body envelope Partial — versioned v1 envelope only where a transport lacks a portable native-header channel. Different model — raw application body plus CAP metadata headers. No wire compatibility claim.
Publish outside transaction Supported. Supported. Durable record precedes broker work.
Transaction-aware outbox Supportedtx/ctx. Supported. Provider APIs differ.
Explicit transaction handle Supportedtx/ctx.tx. Supported — ADO.NET/EF integration. Adapter-owned types in Node.js.
Ambient transaction integration Supported — optional manager/context. Supported. Semantics are unrelated.
Immediate broker attempt Supportedimmediate: true, non-atomic. Supported. DB+broker atomicity is not claimed.
Deferred/background dispatch Supported. Supported. Scheduler implementation differs.
Delayed/scheduled messages Not supported. SupportedPublishDelayAsync. CAP Node.js public ports omit this.
Bulk publish Not supported. Not supported. Neither reviewed public API supports bulk messaging.
Callback/response/compensation Not supported — no portable request/reply/callback port. Supported — official messaging docs cover compensating/callback fields. CAP Node.js makes no shared request/reply guarantee.

Subscribers and recovery

Capability CAP Node.js DotNetCore.CAP Important difference
Topic subscriptions Supported. Supported. APIs differ.
Consumer groups Supported. Supported. Independent group outcomes.
Fan-out across groups Supported. Supported. No cross-group transaction.
Competing consumers in one group Partial — broker-specific implementation. Supported. No portable broker uniformity claim.
Local duplicate handlers Supported — duplicate (topic, group) throws. Not verified. CAP Node.js process-local constraint.
Subscriber concurrency controls Partial — transport prefetch/client behavior varies; no common core knob. Supported — documented thread/parallel controls. No CAP Node.js equivalent.
Subscriber filters/middleware Not supported. Supported. No shared Node.js filter port.
Wildcard subscriptions Not supported as a common transport capability. Partial — NATS JetStream wildcard-topic support is documented; no portable cross-transport contract is claimed. Explicit topics in CAP Node.js.
Immediate retry Partial — scheduler-oriented retry, no general same-call policy. Supported. Timing models differ.
Background retry Supported. Supported. Both persist failure state.
Stale pending/scheduled recovery Partial — stale pending recovery, slow-subscriber caveat. SupportedScheduled/Failed lookback. Status terms differ.
Dead-letter/terminal failure Supporteddead_letter. Supported. Retention differs.
Idempotency responsibility Supported — documented. Supported — official guidance. No exactly-once claim.
Transactional inbox atomicity Not supported. Not verified as a business-state-plus-inbox atomic contract. CAP Node.js intentionally lacks it.
Configurable retry count Supported. Supported. Defaults differ.
Configurable retry interval Partial — scheduler policy, no same named interval option. SupportedFailedRetryInterval. CAP Node.js uses backoff.
Retry backoff Supported — exponential. Not verified. Do not infer .NET algorithm.
Retry jitter Supported. Not verified. CAP Node.js policy is explicit.
Fallback/stale window SupportedinboxFallbackWindowMs. SupportedFallbackWindowLookbackSeconds. Same default duration is not compatibility.
Multi-instance retry coordination Partial — inbox lacks per-message ownership. Supported — optional DB scanner lock. Coordination is not handler ownership.
Outbox per-message claim ownership Partial — fenced leases with PostgreSQL/MySQL real-DB coverage. Not verified as equivalent fencing. CAP Node.js explicit ownership boundary.
Inbox per-message claim ownership Not supported. Not verified. No equivalence claim.
Failure threshold callback Not supported. SupportedFailedThresholdCallback. Diagnostics are not threshold callbacks.
Manual inbox retry/requeue SupportedrequeueInbox(id). Supported — dashboard/manual retry. CAP Node.js API is dashboard-independent.
Manual outbox retry/requeue SupportedrequeueOutbox(id). Supported — dashboard/manual retry. Semantics not assumed identical.
Successful-message cleanup Not supported. Supported — expiry/collector cleanup. Storage lifecycle differs.
Failed-message retention/cleanup Not supported. Supported. No shared retention policy.

Administration, storage, and transports

Capability CAP Node.js DotNetCore.CAP Important difference
Message lookup Supported — first-party administration capability. Supported — dashboard/runtime. CAP Node.js core-facing API.
Inbox/outbox counts and oldest timestamps SupportedgetMessagingSnapshot(). Supported — dashboard statistics. Node snapshot is not a cross-table transaction.
Framework-neutral administration API Supported — requeue/snapshot methods. Different model — dashboard/runtime-led operations. CAP Node.js works without dashboard.
Manual dashboard retry Supported. Supported. Application owns authorization.
Force replay successful records Not supported. Not verified. CAP Node.js excludes processed/published.
Bulk retry/requeue Not supported. Not verified. No public API claim.
In-memory storage Supported. Supported. Not durable production storage.
PostgreSQL Supported — all current storage styles; real claim tests. Supported. Adapter/use-case dependent.
MySQL/MariaDB Supported — first-party providers; MySQL claim tests. Supported — MySQL. MariaDB is provider-specific.
SQLite Partial — local/test, not safe multi-instance outbox claim. Not verified built-in; official docs name community extension. Never infer cluster safety.
SQL Server Partial — no first-party safe multi-instance claim path. Supported. Provider support is not claim guarantee.
MongoDB Not supported. Supported. Mongoose is only future candidate.
MikroORM Supported — first-party ORM adapter. Not supported as reviewed provider style. Abstraction layer, not DB.
Knex Supported — first-party query-builder adapter. Not supported. Does not imply every DB guarantee.
TypeORM Supported — first-party ORM adapter. Not supported. Not EF Core.
Prisma Supported — first-party raw-SQL adapter. Not supported. No CAP model requirement.
EF Core Not supported. Supported. .NET integration style.
ADO.NET/native transaction integration Not supported as Node API. Supported. Node uses adapter transaction objects.
In-memory transport Supported. Supported. Not distributed/durable broker.
RabbitMQ Supported — package, contract, broker integration test. Supported. No topology/wire equivalence.
Kafka Supported — package, contract, broker integration test. Supported. Not exactly-once processing.
Azure Service Bus Supported — package, contract, integration path. Supported. Settlement/provisioning adapter-specific.
AWS SNS + SQS transport topology Supported — SNS publishing with SQS consumer-group queues. Supported — its AmazonSQS provider uses SNS topics plus SQS queues. Package, configuration, and provisioning semantics differ.
Plain SQS-only pub/sub Not supported — not the first-party adapter model. Not supported — its documented AmazonSQS model also requires SNS. Neither is documented as SQS-only topic pub/sub.
NestJS microservices bridge Supported. Not supported. ClientProxy acceptance is not portable broker ack.
NATS Planned — NATS JetStream v2.5 candidate. Supported. No CAP Node.js package.
Redis Streams Planned — later/optional candidate. Supported. No CAP Node.js package.
Apache Pulsar Not supported. Supported. No CAP Node.js roadmap commitment found.
Google Pub/Sub Planned — v2.5 candidate. Not supported in reviewed official provider lists. No CAP Node.js implementation.

Frameworks, observability, and extensibility

Capability CAP Node.js DotNetCore.CAP Important difference
Framework-neutral usage Supportedcap-core. Supported. Core APIs differ.
NestJS / Express Supported. Not supported. First-party Node integrations.
ASP.NET Core Not supported. Supported. First-party .NET integration.
Decorator/attribute subscription Supported — Nest decorators. Supported[CapSubscribe]. Metadata systems differ.
Dependency injection/lifecycle Supported — Nest lifecycle, explicit Express start/stop. Supported — .NET DI/hosting. APIs differ.
Health endpoints Supported — Express health router. Not verified as generic feature. Do not infer from dashboard.
Dashboard integration Supported — core/Nest/Express dashboard packages. Supported. Node admin API can be headless.
Framework-neutral typed diagnostics SupportedCapMessagingDiagnosticsPort. Different model — .NET native diagnostics. Semantic port vs native instrumentation.
DiagnosticSource Not supported. Supported. .NET API.
EventSource/metrics Planned — metrics/tracing roadmap item. Supported. CAP Node.js has no built-in metrics.
OpenTelemetry Not supported. Supported — first-party package. External sinks are not first-party support.
Dashboard metrics Not verified. Supported. Node dashboard graphs are not claimed.
Logging hooks Supported — logger port and diagnostics failure logging. Supported. APIs differ.
Payload privacy in diagnostics Supported — typed events exclude payload/headers. Not verified equivalent default. Explicit Node privacy boundary.
Service discovery Not supported. Supported — Consul/Kubernetes dashboard integration. No Node package.
Storage adapter extension interface Supported — ports/capabilities. Supported — provider model. Contracts differ.
Transport adapter extension interface Supported — publisher/subscriber ports. Supported — provider model. Contracts differ.
Shared storage contract suite Supported@mikara89/cap-testing. Not verified equivalent public suite. Explicit Node suite.
Shared transport contract suite SupporteddefineTransportContract(). Not verified equivalent public suite. Explicit Node suite.
Real database integration gates Supported — PostgreSQL/MySQL outbox claim gate. Not verified reviewed CI equivalence. Narrow evidence only.
Real broker integration gates Supported — RabbitMQ, Kafka, AWS SNS/SQS, Service Bus scripts/workflows. Not verified reviewed CI equivalence. No reliability equivalence.
Compile-checked examples Supportedexamples:check. Not verified. Repository-script evidence.
Framework-neutral storage roots Supported — Knex/TypeORM/Prisma roots; /nest boundary. Different model. Node package boundary is explicit.
Independent adapter packages Supported — npm independent versions. Supported — provider packages. Milestone is not package version.

Important design differences

Current limitations

CAP Node.js has no transactional inbox, delayed delivery, portable filters or wildcards, automatic cleanup/retention, failure threshold callback, plain Amazon SQS transport, MongoDB storage, service discovery, or first-party OpenTelemetry/metrics. NATS JetStream and Google Pub/Sub are planned, not implemented. SQL Server and SQLite are not safe first-party multi-instance outbox claim implementations merely because an ORM/query builder can target them.

Source references

CAP Node.js

DotNetCore.CAP

Verification revisions

CAP Node.js:

DotNetCore.CAP: