@axion-io/core
v0.1.0
Published
Framework-agnostic TypeScript core for Axion Systems event-driven backend architecture.
Maintainers
Readme
@axion-io/core
Framework-agnostic TypeScript core for the Axion Systems event-driven backend architecture.
Exposes the complete contract layer, port interfaces for all architecture components, use-case and handler base classes, lifecycle guards, schema validation, and in-memory fakes in @axion-io/core/testing. All APIs are stable and production-ready.
Contract layer
- JSON-compatible identity aliases for operations, messages, correlation, ordering, schema versions, and tenants.
- Durable domain-event envelopes and Task envelopes.
- Operation readiness and requirement unions.
- Actor references, capability requests, authorization evidence, and capability decisions.
- Adapter result normalization contracts.
AxionContractErrorfor durable diagnostics.
Port interfaces
PolicyValidator<TContext>andAuthorizationResolver<TContext>for capability decisions.CommandUseCase,QueryUseCase,SystemUseCase, andTaskUseCasefor all UseCase categories.CommandService,QueryService,SystemService, andTaskServicefor command, read, system, and task service boundaries.ProjectionHandler,TaskHandler, andSystemTriggerHandlerfor mapping triggers to domain logic.ProjectionMaterializerfor projection write materializers that return discriminatedProjectionReportvalues from explicit materialization methods.Adapter<TInput, TValue>for normalized external side-effect results.OperationManagerwith typed input DTOs for all readiness lifecycle transitions.OutboxWriterfor durable domain-event and task publication.MutationResponse<TResult>for standard CommandUseCase return shapes with operation tracking.
Testing harnesses (@axion-io/core/testing)
TestClockinterface andcreateFixedClock(timestamp)for deterministic time in tests.InMemoryOperationManagerimplementingOperationManagerwith full readiness lifecycle, terminal state protection, and idempotent duplicate handling.InMemoryOutboxWriterimplementingOutboxWriterwith inspectabledomainEventsandtasksarrays.FakePolicyValidator<TContext>implementingPolicyValidatorwith configurable allow/deny and call recording.FakeAdapter<TInput, TValue>implementingAdapterwith configurable response and call recording.buildDomainEventEnvelopeandbuildTaskEnvelopebuilders with stable defaults and per-field overrides.
Runtime utilities (@axion-io/core)
AbstractPolicyValidator<TContext>— base class that composesAuthorizationResolverevidence in parallel and delegates the final allow/deny decision to the abstractauthorize(evidence, request)method.buildMutationResponse(operation, result, requiredProjectionNames?)— constructsMutationResponse<TResult>from an acceptedOperation, computingrequiresRefresh,requiredProjections, andcorrelationIdautomatically.
Projection testing tools (@axion-io/core/testing)
FakeProjectionMaterializer<TInput>— implementsProjectionMaterializerand exposesexecute(input)with a configurableProjectionReportresponse.setReport(report)switches to a new report (also clears failure);failWith(error)switches to rejection mode;reset()clears calls and failure;callCount/callsinspection.buildProjectionCompletedReport(overrides?)— constructsProjectionCompletedReportwith stable defaults; every field overridable.buildProjectionFailedReport(overrides?)— constructsProjectionFailedReportwith stable defaults includingfailureCodeandfailureMessage.
AbstractAuthorizationResolver (@axion-io/core)
AbstractAuthorizationResolver<TContext>— base class implementingAuthorizationResolver<TContext>. Constructor receives areadonly ActorCategory[]supported-categories list;supports()returnstrueiff the request's actor category is in that set. Subclasses implement onlyresolve(). Enforces the architecture convention that each resolver is scoped to one or more actor categories (user, system, admin, group, role).
Schema validation and authorization testing tools
assertSchemaVersion(actual, expected)(@axion-io/core) — throwsAxionContractError("unsupported_schema_version")with{ actual, expected }metadata when versions differ. The standard tool forvalidateEnvelopeimplementations inAbstractProjectionHandlerandAbstractTaskHandlersubclasses.FakeAuthorizationResolver<TContext>(@axion-io/core/testing) — implementsAuthorizationResolver<TContext>with configurablesupportsresult and evidence array, call recording for bothsupportsandresolve, andreset(). The primary tool for unit-testingAbstractPolicyValidatorsubclasses.buildAuthorizationEvidence(overrides?)(@axion-io/core/testing) — constructsAuthorizationEvidencewith stable defaults and per-field overrides, for use inFakeAuthorizationResolverconfiguration and assertion code.
Service fakes (@axion-io/core/testing)
FakeCommandService<TInput, TResult>— implementingCommandService<TInput, TResult>with configurable result and call recording.setResult(result)switches to success mode;failWith(error)switches to rejection mode;reset()clears calls and reverts to success.FakeQueryService<TInput, TResult>— same API asFakeCommandService, implementingQueryService<TInput, TResult>.FakeSystemServiceandFakeTaskServiceprovide the same inspection API forSystemServiceandTaskServicedependencies.
Handler base classes (@axion-io/core)
AbstractProjectionHandler<TPayload>— base class for projection handlers. Requires aProjectionMaterializer, callsvalidateEnvelope(event)(synchronous, throws on invalid category/schema version), then delegates toproject(event, materializer). Never mutates Canonical Entities or calls CommandService.AbstractTaskHandler<TPayload>— base class for task handlers. Requires exactly oneTaskUseCase, callsvalidateEnvelope(task)(synchronous, throws on invalid task type/schema), then delegates totaskUseCase.execute(task)in the base class.
System and task use-case base classes (@axion-io/core)
AbstractSystemUseCase<TInput, TResult>— base class for system-actor use cases. Requires anOperationManagerandSystemService, callsvalidateInvariants(input)(subclass throws on invalid preconditions), creates anOperationviaOperationManagerusingbuildOperationInput(input), then delegates toexecuteSystem(input, operation, systemService). No PolicyValidator — system actors have authority by definition.AbstractTaskUseCase<TPayload, TResult>— base class for task use cases driven byTaskEnvelope. Requires aTaskService, callsvalidateInvariants(envelope)(throws on invalid task metadata), then delegates toexecuteTask(envelope, taskService). No operation creation — task use cases operate within an already-accepted operation.
Use-case orchestration base classes (@axion-io/core)
AbstractCommandUseCase<TInput, TResult, TContext>— base class for command use cases. Requires aCommandService, callsbuildCapabilityRequest(input), validates viaPolicyValidator, throwsAxionContractError("policy_denied")on denial, creates anOperationviaOperationManagerusingbuildOperationInput(input, request), then delegates toexecuteCommand(input, operation, commandService).AbstractQueryUseCase<TInput, TResult, TContext>— base class for query use cases. Requires aQueryService; after the same policy-validation guard, delegates toexecuteQuery(input, request, queryService)with no operation creation.
Service base classes (@axion-io/core)
AbstractCommandService<TInput, TResult, TRepository, TLifecycle, TTransactionContext>— base class for concrete command-side mutation services. Requiresrepository,repositoryFactory,transactionRunner,outboxWriterFactory,clock, andidGenerator; accepts optionallifecycle.AbstractQueryService<TInput, TResult, TRepository>— base class for concrete read-only services. Accepts an optionalrepository.AbstractSystemServiceandAbstractTaskServicemirror command-service transactional dependencies for system-owned and task-owned mutation services.AbstractProjectionMaterializer<TInput, TRepository>— base class for concrete projection-write services. Requiresrepository,operationManager,projectionName, andrequirementId.
Lifecycle and transaction abstractions (@axion-io/core + @axion-io/core/testing)
AbstractLifecycleStateManager<TState>— base class for entities with controlled business states. Subclasses pass anAllowedTransition<TState>[]table to the constructor and callguardTransition(from, to)before mutating; throwsAxionContractError("terminal_state_transition_conflict")for non-configured transitions.AllowedTransition<TState>— typed{ from, to }pair for declaring the lifecycle transition table.TransactionRunner<TContext>— port interface forCommandServicetransaction abstractions; injected as a constructor dependency.FakeTransactionRunner<TContext>(testing) — executes the transaction function immediately with a pre-configured context; inspection API:callCount,reset().
