calendaryjs 0.2.0 β 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/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +6 -5
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://github.com/calendaryjs/calendaryjs/tree/main/packages/lunar) | Lunar calendar events |
|
|
182
|
-
| [calendaryjs-plugin-liturgical](https://github.com/calendaryjs/calendaryjs/tree/main/packages/liturgical) | Easter & offset events |
|
|
183
|
-
| [calendaryjs-plugin-hijri](https://github.com/calendaryjs/calendaryjs/tree/main/packages/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/dist/index.cjs
CHANGED
|
@@ -1015,7 +1015,7 @@ var CalendaryInstance = class _CalendaryInstance {
|
|
|
1015
1015
|
return cloned;
|
|
1016
1016
|
}
|
|
1017
1017
|
/**
|
|
1018
|
-
* Register a plugin (
|
|
1018
|
+
* Register a plugin (use/extend)
|
|
1019
1019
|
*/
|
|
1020
1020
|
use(plugin) {
|
|
1021
1021
|
for (const dep of plugin.dependencies || []) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1085,7 +1085,7 @@ declare class CalendaryInstance<TMetadata extends Record<string, unknown> = Reco
|
|
|
1085
1085
|
*/
|
|
1086
1086
|
clone(): CalendaryInstance<TMetadata, TCategory>;
|
|
1087
1087
|
/**
|
|
1088
|
-
* Register a plugin (
|
|
1088
|
+
* Register a plugin (use/extend)
|
|
1089
1089
|
*/
|
|
1090
1090
|
use(plugin: CalendaryPlugin): this;
|
|
1091
1091
|
hasPlugin(name: string): boolean;
|
|
@@ -1162,7 +1162,7 @@ interface CalendaryFn {
|
|
|
1162
1162
|
isCalendary: typeof isCalendary;
|
|
1163
1163
|
}
|
|
1164
1164
|
/**
|
|
1165
|
-
* Factory function
|
|
1165
|
+
* Factory function with generics support
|
|
1166
1166
|
*
|
|
1167
1167
|
* @template TMetadata - Custom metadata type for events
|
|
1168
1168
|
* @template TCategory - Category type for events
|
package/dist/index.d.ts
CHANGED
|
@@ -1085,7 +1085,7 @@ declare class CalendaryInstance<TMetadata extends Record<string, unknown> = Reco
|
|
|
1085
1085
|
*/
|
|
1086
1086
|
clone(): CalendaryInstance<TMetadata, TCategory>;
|
|
1087
1087
|
/**
|
|
1088
|
-
* Register a plugin (
|
|
1088
|
+
* Register a plugin (use/extend)
|
|
1089
1089
|
*/
|
|
1090
1090
|
use(plugin: CalendaryPlugin): this;
|
|
1091
1091
|
hasPlugin(name: string): boolean;
|
|
@@ -1162,7 +1162,7 @@ interface CalendaryFn {
|
|
|
1162
1162
|
isCalendary: typeof isCalendary;
|
|
1163
1163
|
}
|
|
1164
1164
|
/**
|
|
1165
|
-
* Factory function
|
|
1165
|
+
* Factory function with generics support
|
|
1166
1166
|
*
|
|
1167
1167
|
* @template TMetadata - Custom metadata type for events
|
|
1168
1168
|
* @template TCategory - Category type for events
|
package/dist/index.js
CHANGED
|
@@ -1013,7 +1013,7 @@ var CalendaryInstance = class _CalendaryInstance {
|
|
|
1013
1013
|
return cloned;
|
|
1014
1014
|
}
|
|
1015
1015
|
/**
|
|
1016
|
-
* Register a plugin (
|
|
1016
|
+
* Register a plugin (use/extend)
|
|
1017
1017
|
*/
|
|
1018
1018
|
use(plugin) {
|
|
1019
1019
|
for (const dep of plugin.dependencies || []) {
|
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": [
|
|
@@ -59,12 +60,12 @@
|
|
|
59
60
|
},
|
|
60
61
|
"repository": {
|
|
61
62
|
"type": "git",
|
|
62
|
-
"url": "git+https://github.com/
|
|
63
|
+
"url": "git+https://github.com/vbilltran68/calendaryjs.git",
|
|
63
64
|
"directory": "packages/calendaryjs"
|
|
64
65
|
},
|
|
65
|
-
"homepage": "https://
|
|
66
|
+
"homepage": "https://www.npmjs.com/package/calendaryjs",
|
|
66
67
|
"bugs": {
|
|
67
|
-
"url": "https://github.com/
|
|
68
|
+
"url": "https://github.com/vbilltran68/calendaryjs/issues"
|
|
68
69
|
},
|
|
69
70
|
"scripts": {
|
|
70
71
|
"typecheck": "tsc --noEmit",
|