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.
- package/README.md +109 -131
- package/assets/logo.svg +17 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,186 +1,164 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
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
|
-
##
|
|
29
|
+
## Install
|
|
14
30
|
|
|
15
31
|
```bash
|
|
16
|
-
|
|
32
|
+
npm i calendaryjs
|
|
17
33
|
```
|
|
18
34
|
|
|
19
|
-
##
|
|
20
|
-
|
|
21
|
-
### Factory API (Recommended)
|
|
35
|
+
## 1 Β· Your first event
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
plain config shown under [Collections](#collections):
|
|
37
|
+
Group events, then read them back as dated occurrences:
|
|
25
38
|
|
|
26
|
-
```
|
|
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
|
-
|
|
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
|
-
|
|
50
|
+
// β [{ title: "Christmas", date: "2026-12-25", type: "const", β¦ }]
|
|
51
|
+
```
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
>
|
|
50
|
-
>
|
|
51
|
-
>
|
|
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
|
-
|
|
82
|
+
## 4 Β· Add a calendar system
|
|
54
83
|
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
```
|
|
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
|
-
|
|
66
|
-
|
|
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
|
-
|
|
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
|
-
|
|
103
|
+
## 5 Β· Bundle & share β collections
|
|
81
104
|
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
109
|
+
```ts
|
|
110
|
+
const cal = calendary().use(lunar());
|
|
86
111
|
|
|
87
|
-
cal.
|
|
88
|
-
|
|
89
|
-
|
|
112
|
+
cal.load({
|
|
113
|
+
collection: "holidays",
|
|
114
|
+
plugins: ["calendaryjs-plugin-lunar"],
|
|
90
115
|
events: [
|
|
91
|
-
{ type: "const", id: "
|
|
92
|
-
{ type: "
|
|
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
|
-
##
|
|
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` |
|
|
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
|
-
|
|
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`
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
|
138
|
-
|
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
|
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
|
|
package/assets/logo.svg
ADDED
|
@@ -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.
|
|
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": [
|