Skip to content

CalendaryInstance

CalendaryInstance class - the main instance

// Default usage
const cal = calendary();
// With typed metadata
interface LiturgicalMetadata { rank: string; vestmentColor: string; }
const cal = calendary<LiturgicalMetadata>();
const day = cal.getDay("2025-12-25");
day.events[0].metadata?.rank; // TypeScript knows this exists

TMetadata extends Record<string, unknown> = Record<string, unknown>

Custom metadata type for events

TCategory extends string = string

Category type for events

new CalendaryInstance<TMetadata, TCategory>(cfg?): CalendaryInstance<TMetadata, TCategory>

Record<string, unknown>

CalendaryInstance<TMetadata, TCategory>

$isCalendary: boolean = true

add(…events): this

Add events without the group ceremony — they land in a shared "events" group. Repeated calls accumulate; pass builders or plain configs.

…(Buildable | EventConfig)[]

this

cal.add(
weekly("monday").title("Gym"),
yearly(12, 25).title("Christmas"),
);

addGroup(config): this

GroupInput

this


clone(): CalendaryInstance<TMetadata, TCategory>

Clone this instance

CalendaryInstance<TMetadata, TCategory>


getDay(date): CalendarDay<TMetadata, TCategory>

Get a single calendar day

string | DateComponents

CalendarDay<TMetadata, TCategory>


getDays(options): CalendarDay<TMetadata, TCategory>[]

Get calendar days for a date range

GetDaysOptions

CalendarDay<TMetadata, TCategory>[]


getEvents(date): CalendarEvent<TMetadata, TCategory>[]

string

CalendarEvent<TMetadata, TCategory>[]


getEventsByGroup(groupId, from, to): CalendarEvent<TMetadata, TCategory>[]

string

string

string

CalendarEvent<TMetadata, TCategory>[]


getEventsInRange(from, to): CalendarEvent<TMetadata, TCategory>[]

All occurrences in [from, to] (both inclusive), globally sorted: date ascending, then priority descending (higher = on top), across every year in the range — not just within a year. Ties keep generation order (stable). A consumer can render the list directly without re-sorting.

string

string

CalendarEvent<TMetadata, TCategory>[]


getGroup(groupId): Group | undefined

string

Group | undefined


getGroups(): Group[]

Group[]


getSkipped(range): SkippedOccurrence<TMetadata>[]

Occurrences that WOULD have fallen in the range but were removed by an exceptions skip (ICS EXDATE) — so a consumer can render them (e.g. a struck-through “ghost”) without re-reading the event store. Moved occurrences carry CalendarEvent.movedFrom on the normal output instead.

string

string

SkippedOccurrence<TMetadata>[]


getUpcomingEvents(days): CalendarEvent<TMetadata, TCategory>[]

number

CalendarEvent<TMetadata, TCategory>[]


hasDayEnricher(name): boolean

Check if a day enricher is registered

string

boolean


hasPlugin(name): boolean

string

boolean


invalidateCache(): this

this


load(input, options?): this

Load a Collection — a portable bundle of events (a .cdy document is its JSON form) — or a CollectionBundle carrying several named collections, expanded into one group each (id/priority/color preserved). Pass an object or a JSON string. Declared plugins must already be registered (cal.use(...)); a clear error lists any that aren’t. Nothing is fetched or executed behind your back.

options.priority overrides the priority of a single collection; for a bundle each collection keeps its own (that’s the point of a bundle).

string | Collection | CollectionBundle

number

this


registerAnchor(name, fn): this

Register a named anchor — a year → Date resolver that relative events (the builder’s from(anchor).plus(...)) offset from. Anchors share the formula registry; this is the anchor-flavoured name for the same call.

string

FormulaFn

this


registerDayEnricher(enricher): this

Register a day enricher to add custom data to CalendarDay objects

DayEnricher

this


registerFormula(name, fn): this

string

FormulaFn

this


removeGroup(groupId): this

string

this


requiredPlugins(events?): string[]

The npm names of the registered plugins whose event types appear in events — the minimal manifest a consumer must install + use(). Defaults to every loaded event. This is the derivation toCollection uses, exposed so you don’t re-implement a “plugins for these events” helper.

EventConfig[]

events to inspect (default: all loaded events, across groups).

string[]


search(): SearchBuilder<TMetadata, TCategory>

Create a search builder for advanced event queries. Supports text search, metadata search, categories, and more.

Every search needs a bounded window — recurrences are infinite, so “search everything” has no meaning. Set it with .range(from, to), .date(date), .year(y), or .month(y, m).

SearchBuilder<TMetadata, TCategory>

// Search by text (case-insensitive), within a year
cal.search().text('christmas').year(2026).getEvents();
// Search by metadata
cal.search().metadata({ season: 'advent' }).year(2026).getEvents();
// Combined search
cal.search()
.text('easter')
.categories(['liturgical'])
.range('2025-01-01', '2025-12-31')
.sortBy('date', 'asc')
.getEvents();

setGroupEnabled(groupId, enabled): this

string

boolean

this


toBundle(options?): SerializedCollectionBundle

Export every group as a SerializedCollectionBundle — one collection per group, each keeping its id / name / priority / color and its own plugin manifest. The inverse of load() on a bundle; round-trips several named, independently-styled collections through a single .cdy file (unlike toCollection, which flattens every group’s events into one collection).

string

string

SerializedCollectionBundle


toCollection(options?): SerializedCollection

Export events as a portable Collection — the inverse of load. Serializes the plain event configs plus a manifest of the plugins their event types need, so the result round-trips back through load(). Pass it to JSON.stringify for a .cdy document.

string

export a single group; omit to export every group’s events.

string

the collection name (also the default group id on re-load).

string

an informational version stamp.

SerializedCollection


use(plugin): this

Register a plugin (use/extend)

CalendaryPlugin

this