calendaryjs 0.2.1 β†’ 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +109 -131
  2. package/assets/logo.svg +17 -0
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -1,186 +1,164 @@
1
- # calendaryjs
2
-
3
- A lightweight, plugin-based calendar system for managing events in TypeScript.
4
-
5
- ## Features
6
-
7
- - **πŸͺΆ Lightweight** - ~5KB core, tree-shakeable
8
- - **πŸ”Œ Plugin System** - chainable `extend()` API
9
- - **πŸ“… Many Event Types** - const, fixed, monthly, weekly, nth-weekday, formula, relative (+ plugin types)
10
- - **πŸ” Fluent Query API** - Chain methods for filtering
11
- - **πŸ’Ύ Caching** - Memoized event generation
1
+ <p align="center">
2
+ <img src="https://cdn.jsdelivr.net/npm/calendaryjs/assets/logo.svg" alt="calendaryjs" width="380" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ Declare recurring events like a sentence β€” and teach the engine <b>any</b> calendar
7
+ system (lunar, hijri, liturgical… or your own) with a plugin.
8
+ </p>
9
+
10
+ - πŸ” **Recurrence engine** β€” weekly, monthly, nth-weekday, formula, relative
11
+ - πŸ”Œ **Pluggable calendar systems** β€” one engine, every calendar
12
+ - ✍️ **Fluent builder** β€” `every("week").on("mon", "wed", "fri")`
13
+ - πŸ” **Query API** β€” filter events across groups & date ranges
14
+ - 🧩 **Collections** (`.cdy`) + **ICS export** β€” plain, serializable data
15
+ - πŸͺΆ Zero-dependency Β· ~5KB Β· browser Β· Node Β· edge Β· RN
16
+
17
+ ## Overview
18
+
19
+ **calendaryjs turns event _rules_ into dated _occurrences_.** You **declare** events
20
+ (Christmas, every other Tuesday, the 2nd Sunday of May…), the engine **expands** their
21
+ recurrence into concrete dates, and you **read, query, or export** the result. The core
22
+ speaks the Gregorian calendar; **plugins** teach it others β€” lunar, hijri, liturgical,
23
+ or your own.
24
+
25
+ ```text
26
+ declare (builder) β†’ expand (engine) β†’ read Β· query Β· export
27
+ ```
12
28
 
13
- ## Installation
29
+ ## Install
14
30
 
15
31
  ```bash
16
- pnpm add calendaryjs
32
+ npm i calendaryjs
17
33
  ```
18
34
 
19
- ## Quick Start
20
-
21
- ### Factory API (Recommended)
35
+ ## 1 Β· Your first event
22
36
 
23
- Author events with the **builder** β€” it reads like a sentence and compiles to the
24
- plain config shown under [Collections](#collections):
37
+ Group events, then read them back as dated occurrences:
25
38
 
26
- ```typescript
39
+ ```ts
27
40
  import { calendary } from "calendaryjs";
28
41
  import { every, date } from "calendaryjs/builder";
29
42
 
30
43
  const cal = calendary();
31
-
32
44
  cal.addGroup({
33
45
  id: "holidays",
34
- name: "Holidays",
35
- events: [
36
- every("year").on(date(1, 1)).title("New Year"),
37
- every("year").on(date(12, 25)).title("Christmas"),
38
- ],
46
+ events: [every("year").on(date(12, 25)).title("Christmas")],
39
47
  });
40
48
 
41
- // Read events
42
49
  cal.getEvents("2026-12-25");
43
- cal.getEventsInRange("2026-01-01", "2026-12-31");
50
+ // β†’ [{ title: "Christmas", date: "2026-12-25", type: "const", … }]
51
+ ```
44
52
 
45
- // Fluent query
46
- cal.search().group("holidays").range("2026-01-01", "2026-12-31").getEvents();
53
+ ## 2 Β· Recurring events β€” the builder
54
+
55
+ Every declaration reads like a sentence β€” **frequency β†’ position β†’ payload** β€” and
56
+ compiles to a plain, serializable config:
57
+
58
+ ```ts
59
+ import { every, once, date, nth } from "calendaryjs/builder";
60
+
61
+ every("year").on(date(1, 1)).title("New Year"); // Jan 1, every year
62
+ every("year")
63
+ .on(nth(4, "thursday", "november"))
64
+ .title("Thanksgiving");
65
+ every(2, "weeks").on("tuesday").title("Standup"); // every other Tuesday
66
+ every("week").on("monday", "wednesday", "friday").title("Gym"); // pick weekdays
67
+ once("2026-06-15").title("Wedding"); // a single date
47
68
  ```
48
69
 
49
- > Full grammar (`every`/`from`/`once`, positions, bounds, plugin selectors): the
50
- > [builder guide](https://calendaryjs.dev/guides/builder/). Hand-writing the plain
51
- > config also works β€” both compile to the same model.
70
+ > Prefer raw objects? The builder just `build()`s into a plain config β€” hand-write it
71
+ > if you like; both compile to the same model. Full grammar: the
72
+ > [builder guide](https://calendaryjs.dev/guides/builder/).
73
+
74
+ ## 3 Β· Read & query
75
+
76
+ ```ts
77
+ cal.getEvents("2026-12-25"); // a single day
78
+ cal.getEventsInRange("2026-01-01", "2026-12-31"); // a range
79
+ cal.search().group("holidays").range("2026-01-01", "2026-12-31").getEvents();
80
+ ```
52
81
 
53
- ### Collections
82
+ ## 4 Β· Add a calendar system
54
83
 
55
- Bundle events into a portable **collection** (a `.cdy` file is its JSON form) and
56
- load it with `cal.load()`. It declares the plugins its events need; register those
57
- first β€” `load()` validates them and errors clearly if any is missing.
84
+ A plugin extends the engine **and** the builder's vocabulary β€” install it, `use()` it,
85
+ and new event types become available:
58
86
 
59
- ```typescript
60
- import { calendary } from "calendaryjs";
87
+ ```ts
61
88
  import { lunar } from "calendaryjs-plugin-lunar";
62
89
 
63
90
  const cal = calendary().use(lunar());
64
-
65
- cal.load({
66
- collection: "holidays",
67
- plugins: ["calendaryjs-plugin-lunar"],
68
- events: [
69
- { type: "const", id: "new-year", month: 1, day: 1, title: "New Year" },
70
- { type: "lunar", id: "lunar-new-year", lunarMonth: 1, lunarDay: 1, title: "Lunar New Year" },
71
- ],
91
+ cal.addGroup({
92
+ id: "lunar",
93
+ events: [every("year").on(lunar.date(1, 1)).title("Lunar New Year")],
72
94
  });
73
-
74
- // …or from a .cdy (JSON) string, e.g. read from disk or fetched
75
- cal.load(jsonString);
76
95
  ```
77
96
 
78
- ### Class-based API
97
+ | Plugin | Adds |
98
+ | -------------------------------------------------------------------------------------------- | ------------------------------------------ |
99
+ | [calendaryjs-plugin-lunar](https://www.npmjs.com/package/calendaryjs-plugin-lunar) | Lunar (lunisolar) date conversion + events |
100
+ | [calendaryjs-plugin-hijri](https://www.npmjs.com/package/calendaryjs-plugin-hijri) | Islamic (Hijri) date conversion + events |
101
+ | [calendaryjs-plugin-liturgical](https://www.npmjs.com/package/calendaryjs-plugin-liturgical) | Easter computus, movable feasts, seasons |
79
102
 
80
- > `Calendary` is an alias of the canonical `CalendaryInstance` class, kept for backward compatibility.
103
+ ## 5 Β· Bundle & share β€” collections
81
104
 
82
- ```typescript
83
- import { Calendary } from "calendaryjs";
105
+ Bundle events into a portable **collection** (a `.cdy` file is its JSON form) and load it
106
+ with `cal.load()`. It declares the plugins its events need; register those first β€”
107
+ `load()` validates them and errors clearly if any is missing.
84
108
 
85
- const cal = new Calendary();
109
+ ```ts
110
+ const cal = calendary().use(lunar());
86
111
 
87
- cal.addGroup({
88
- id: "holidays",
89
- name: "Holidays",
112
+ cal.load({
113
+ collection: "holidays",
114
+ plugins: ["calendaryjs-plugin-lunar"],
90
115
  events: [
91
- { type: "const", id: "newyear", month: 1, day: 1, title: "New Year" },
92
- { type: "fixed", id: "wedding", year: 2025, month: 6, day: 15, title: "Wedding" },
116
+ { type: "const", id: "new-year", month: 1, day: 1, title: "New Year" },
117
+ { type: "lunar", id: "tet", lunarMonth: 1, lunarDay: 1, title: "Lunar New Year" },
93
118
  ],
94
119
  });
120
+
121
+ cal.load(jsonString); // …or from a .cdy (JSON) string, read from disk or fetched
95
122
  ```
96
123
 
97
- ## Event Types
124
+ ## Reference
125
+
126
+ ### Event types
98
127
 
99
128
  | Type | Description | Example |
100
129
  | ------------- | ------------------------------------------ | ---------------------------- |
101
130
  | `const` | Fixed annual date | Christmas (Dec 25) |
102
131
  | `fixed` | One-time date | Wedding (Jun 15, 2025) |
103
132
  | `monthly` | Same day every month (interval/exclusions) | Payday (15th) |
104
- | `weekly` | Same weekday every week (interval/range) | Standup (Mon) |
133
+ | `weekly` | One or more weekdays (interval/range) | Standup (Mon, Wed, Fri) |
105
134
  | `nth-weekday` | Nth weekday of a month, or anchored | Thanksgiving (4th Thu / Nov) |
106
135
  | `formula` | Custom formula | Last Monday of May |
107
136
  | `relative` | Offset from a registered anchor | 49 days after an anchor |
108
137
 
109
138
  Plugins add more types (e.g. `lunar`, `hijri`, `liturgical`).
110
139
 
111
- ## Plugin System
112
-
113
- ```typescript
114
- import { calendary } from "calendaryjs";
115
-
116
- // Extend with custom functionality
117
- calendary.extend((option, C, d) => {
118
- C.prototype.myMethod = function () {
119
- return "custom method";
120
- };
121
- });
122
-
123
- // Use plugins
124
- import { lunar } from "calendaryjs-plugin-lunar";
125
-
126
- const cal = calendary();
127
- cal.use(lunar());
128
- ```
129
-
130
- ## Event Properties
140
+ ### Event properties
131
141
 
132
- Every event shares `BaseEventProperties` (below) plus its type-specific date fields.
142
+ Every event shares `BaseEventProperties` plus its type-specific date fields.
133
143
  **`id`, `type`, and `title` are required; everything else is optional.**
134
144
 
135
- ### Identity & display
136
-
137
- | Property | Type | Notes |
138
- | ------------- | -------- | ------------------------------------------------------------------------------------------------------- |
139
- | `id` | `string` | unique id β€” _required_ |
140
- | `type` | `string` | `const` Β· `fixed` Β· `monthly` Β· `weekly` Β· `nth-weekday` Β· `formula` Β· `relative` Β· plugin β€” _required_ |
141
- | `title` | `string` | _required_ |
142
- | `description` | `string` | β€” |
143
- | `location` | `string` | β€” |
144
- | `url` | `string` | β€” |
145
- | `icon` | `string` | emoji or glyph |
146
- | `color` | `string` | β€” |
147
-
148
- ### Timing
149
-
150
- | Property | Type | Notes |
151
- | ----------- | --------- | --------- |
152
- | `allDay` | `boolean` | β€” |
153
- | `startTime` | `string` | `"09:00"` |
154
- | `endTime` | `string` | `"17:00"` |
155
- | `duration` | `number` | β€” |
156
-
157
- ### Classification
158
-
159
- | Property | Type | Notes |
160
- | ------------ | ------------------------------------------- | ---------------------------------------------------- |
161
- | `keywords` | `string[]` | β€” |
162
- | `categories` | `string[]` | β€” |
163
- | `status` | `'confirmed' \| 'tentative' \| 'cancelled'` | β€” |
164
- | `priority` | `number` | z-index on a shared day; higher = on top (default 0) |
165
- | `source` | `string` | origin: plugin / feed / ICS subscription |
166
- | `metadata` | `Record<string, unknown>` | arbitrary per-event data |
167
- | `reminders` | `Reminder[]` | β€” |
168
-
169
- ### Recurrence control
170
-
171
- | Property | Type | Notes |
172
- | --------------- | ------------------ | --------------------------------------------------------------- |
173
- | `onConflict` | `ConflictResolver` | same-day conflict: keep / drop / reschedule |
174
- | `overrideDates` | `OverrideDatesMap` | force-move an occurrence to another date |
175
- | `exceptions` | `EventExceptions` | per-occurrence skip / override (ICS `EXDATE` / `RECURRENCE-ID`) |
176
-
177
- ## Plugins
178
-
179
- | Package | Description |
180
- | -------------------------------------------------------------------------------------------- | ---------------------- |
181
- | [calendaryjs-plugin-lunar](https://www.npmjs.com/package/calendaryjs-plugin-lunar) | Lunar calendar events |
182
- | [calendaryjs-plugin-liturgical](https://www.npmjs.com/package/calendaryjs-plugin-liturgical) | Easter & offset events |
183
- | [calendaryjs-plugin-hijri](https://www.npmjs.com/package/calendaryjs-plugin-hijri) | Islamic (Hijri) events |
145
+ | Property | Type | Notes |
146
+ | ---------------------------------- | ------------------------------------- | ---------------------------------------------------- |
147
+ | `id` Β· `type` Β· `title` | `string` | required |
148
+ | `description` Β· `location` Β· `url` | `string` | display metadata |
149
+ | `icon` Β· `color` | `string` | per-event motif |
150
+ | `allDay` | `boolean` | β€” |
151
+ | `startTime` Β· `endTime` | `string` | `"09:00"` … `"17:00"` |
152
+ | `duration` | `number` | minutes |
153
+ | `keywords` Β· `categories` | `string[]` | classification |
154
+ | `status` | `confirmed \| tentative \| cancelled` | β€” |
155
+ | `priority` | `number` | z-index on a shared day; higher = on top (default 0) |
156
+ | `source` | `string` | origin: plugin / feed / ICS subscription |
157
+ | `metadata` | `Record<string, unknown>` | arbitrary per-event data |
158
+ | `reminders` | `Reminder[]` | lead-time offsets (β†’ ICS `VALARM`) |
159
+ | `onConflict` | `ConflictResolver` | same-day conflict: keep / drop / reschedule |
160
+ | `overrideDates` | `OverrideDatesMap` | force-move an occurrence to another date |
161
+ | `exceptions` | `EventExceptions` | per-occurrence skip / override (ICS `EXDATE`) |
184
162
 
185
163
  ## License
186
164
 
@@ -0,0 +1,17 @@
1
+ <svg width="560" height="128" viewBox="0 0 560 128" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="calendary.js">
2
+ <!-- light-theme variant: dark ink mark + text, amber accents -->
3
+ <g transform="translate(-8 0)">
4
+ <path d="M28 28H100V44H44V84H100V100H28V28Z" fill="#16120F" />
5
+ <rect x="72" y="56" width="16" height="16" rx="2" fill="#F59E0B" />
6
+ </g>
7
+ <text
8
+ x="116"
9
+ y="87"
10
+ font-family="'JetBrains Mono', 'DejaVu Sans Mono', ui-monospace, monospace"
11
+ font-weight="700"
12
+ font-size="60"
13
+ letter-spacing="-1"
14
+ >
15
+ <tspan fill="#16120F">calendary</tspan><tspan fill="#F59E0B">.js</tspan>
16
+ </text>
17
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "calendaryjs",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Composable calendar & recurrence engine with pluggable calendar systems.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -43,7 +43,8 @@
43
43
  }
44
44
  },
45
45
  "files": [
46
- "dist"
46
+ "dist",
47
+ "assets/logo.svg"
47
48
  ],
48
49
  "tsup": {
49
50
  "entry": [