@bimetal/calendar-data
Calendar-domain event sourcing. Builds on @bimetal/event-sourcing and adds the calendar aggregate, projection, command factories, and createCalendarStore.
Installation
npm install @bimetal/calendar-data
What's Inside
Domain
CalendarEventData — mutable fields of a CalendarEvent (title, timeRange, allDay, metadata, domains, recurrence, exceptions, resourceId)
CalendarReadModel — { events: readonly CalendarEvent[] }. Projection shape: every field is a collection, so it satisfies OnlyCollections from @bimetal/projection. The position is store.version, beside the read model, not in it (until 0.40 the read model carried a scalar version as well).
Domain Events
CalendarEventCreated / Updated / Deleted / Reverted
- Union:
CalendarDomainEvent
Commands
CreateCalendarEvent, UpdateCalendarEvent, DeleteCalendarEvent
UndoLastChange — pops the per-entity undo stack
ModifyInstance, DeleteInstance — recurring-event instance ops
- Union:
CalendarCommand
Command Factories
createEvent, updateEvent, deleteEvent, undoLastChange, modifyInstance, deleteInstance
Facade
CalendarStore — extends DomainStore<AggregateState, CalendarCommand, CalendarDomainEvent, CalendarReadModel> with getEvents() and getEventsInRange(start, end)
createCalendarStore(config?) — main entry point
HydratableCalendarStore — adds hydrate(), rebuild(), serialize()/hydrateFrom() and peekReadModel()/getReadModel(); with the latter two it is a ProjectionAuthorityStore as is, so createProjectionAuthority({ store: createCalendarStore() }) needs no wrapper
createRemoteCalendarStore(remote) — the same calendar façade over a projection store (createRemoteDomainStore/connectLocalProjection from @bimetal/projection). getEvents/peekEvents/getEventsInRange come from the same helper as in createCalendarStore, recurring events expand identically. Whether a command produced anything is read from the receipt, passed through as quittiert on the façade (createCalendarController reads it there, also behind withRules), not from the (always empty) dispatch return
Calendar-flavored generics (with T = CalendarEvent defaults)
AggregateState, AggregateSnapshot, SnapshotStore — aliases of the generic versions in @bimetal/event-sourcing
Convenience Re-exports
For ergonomics, the most commonly used generic primitives from @bimetal/event-sourcing are re-exported: DomainEvent, Command, EventStore, Projection, Aggregate, Unsubscribe, EventMetadataProvider, createInMemoryEventStore, DataValidationError, ConcurrencyError. (The pub/sub EventBus/createEventBus and createInMemorySnapshotStore are available directly from @bimetal/event-sourcing.)
Example
import { createCalendarStore, createEvent, updateEvent, undoLastChange } from '@bimetal/calendar-data';
import { createDateTime, createTimeRange, Month } from '@bimetal/temporal';
const store = createCalendarStore();
const event = {
id: 'e1',
title: 'Standup',
timeRange: createTimeRange(createDateTime(2026, Month.June, 17, 9, 0, 'UTC'), createDateTime(2026, Month.June, 17, 10, 0, 'UTC')),
allDay: false,
metadata: {},
};
await store.dispatch(createEvent(event));
await store.dispatch(updateEvent('e1', { title: 'Daily Standup' }));
await store.dispatch(undoLastChange('e1'));
Replaces
This package contains the calendar-specific portion of the (removed) @bimetal/data. Generic primitives live in @bimetal/event-sourcing.
License
Apache License 2.0