All notable changes to this project are documented here. The format follows Keep a Changelog, and this project adheres to Semantic Versioning.

[v0.1.0] — 2026-08-16

Added

  • First release. Reads and writes RFC 8984 JSCalendar — Event, Task and Group, with the Location, VirtualLocation, Link, Relation, Participant, RecurrenceRule, NDay and Alert sub-objects. JSCalendar.decode/1 dispatches on @type; JSCalendar.encode/1 writes it back.

  • No dependencies. Erlang's :json and Elixir's Duration are both standard library, so values map to standard types — LocalDateTime to NaiveDateTime, UTCDateTime to DateTime, and a String[Boolean] set to a MapSet. Requires Elixir 1.17 and OTP 27.

  • Unknown properties round-trip. Anything the specification does not name is kept in each object's extra and written back untouched, and a group entry of an unrecognised type is ignored rather than rejected or dropped, as RFC 8984 §5.3.1 requires.

  • Properties equal to their RFC default are omitted on encode, so a document does not grow each time it is read and rewritten and encoding is idempotent.

  • JSCalendar.Patch implements RFC 8984 §1.4.9 PatchObjects with apply/3 and validate/1. An invalid pointer rejects the whole patch rather than applying part of it, and :ignore and :only express the prefixes and suffixes the specification restricts particular properties to.

  • JSCalendar.Occurrence.at/2 builds one instance of a recurring object from its recurrence id, applying any override. It answers :excluded distinctly from {:error, _}, and overridden/1 lists the ids an object varies.

  • recurrenceOverrides and localizations are typed as patch maps — keyed by recurrence id and language tag respectively — and timeZones as JSCalendar.TimeZone with JSCalendar.TimeZoneRule standard and daylight rules.