@craftguild/jscalendar 0.5.0 → 0.5.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 (2) hide show
  1. package/README.md +60 -42
  2. package/package.json +2 -1
package/README.md CHANGED
@@ -1,15 +1,25 @@
1
+ <p style="text-align: center;">
2
+ <img src="assets/d97d4d10-44f9-4b49-9fc2-5aaf33c667ef.png" alt="JSCalendar logo" style="max-height: 320px; height: auto; width: auto;" />
3
+ </p>
4
+
1
5
  # RFC 8984 (JSCalendar) TypeScript Library
2
6
 
3
7
  This library provides a thin, practical TypeScript API for working with
4
- RFC 8984 (JSCalendar) objects. It focuses on creation, mutation, search,
5
- and export. It does **not** implement a calendar application or server.
6
- The goal is to keep the data model easy to use in web apps and CLIs while
7
- preserving access to the full RFC object structure when you need it.
8
+ RFC 8984 (JSCalendar) objects while staying close to the spec. It focuses
9
+ on creation, patching, recurrence expansion, search, and iCalendar export.
10
+ It does **not** implement a calendar application or server; it is a data
11
+ model toolkit you can use in web apps, CLIs, or services.
8
12
 
9
13
  Primary object types are **Event**, **Task**, and **Group**. A **Group**
10
14
  acts as a container when you want to bundle multiple objects. The API is
11
- intentionally small: you create objects, mutate them with safe helpers,
12
- query them with search utilities, and export them to iCalendar as needed.
15
+ intentionally small but opinionated: constructors normalize required
16
+ fields, validation is strict by default, and `patch` applies RFC 8984
17
+ PatchObject semantics.
18
+
19
+ For developer experience, the library offers builder helpers that fill
20
+ `@type` fields and validate nested structures (participants, locations,
21
+ alerts, recurrence rules, and more). You can still pass raw, typed
22
+ JSCalendar objects directly when your data already matches the spec.
13
23
 
14
24
  ## Installation
15
25
 
@@ -84,20 +94,6 @@ const task = new JsCal.Task({
84
94
  });
85
95
  ```
86
96
 
87
- Id maps use `{ id, value }` entries. If you need to merge into an
88
- existing map, pass it as the second argument. Entries with `id` overwrite
89
- matching ids; entries without `id` get new generated ids.
90
-
91
- ```ts
92
- const mergedLocations = JsCal.locations(
93
- [
94
- { id: "l1", value: { name: "Room A Updated" } },
95
- { value: { name: "Room B" } },
96
- ],
97
- existingLocations,
98
- );
99
- ```
100
-
101
97
  ### Group
102
98
 
103
99
  `entries` accepts either plain JSCalendar objects (including `eject()` results)
@@ -204,17 +200,59 @@ plain.title = "Exported";
204
200
  const updated = event.patch({ title: "Live" });
205
201
  ```
206
202
 
207
- ## Updates and Mutations
203
+ ## Patch Usage
208
204
 
209
205
  Patch helpers return new instances and keep metadata such as
210
206
  `updated` and `sequence` consistent. Use `patch` for RFC 8984 PatchObject
211
- semantics.
207
+ semantics. You can set raw values directly, or use helper methods if you
208
+ prefer validated, type-safe inputs.
212
209
 
213
210
  ```ts
214
211
  const patchedEvent = event.patch({ title: "Updated title" });
215
212
  const patchedAgain = patchedEvent.patch({ title: "Patched title" });
216
213
  ```
217
214
 
215
+ You can also patch nested maps by replacing the full map in one call:
216
+
217
+ ```ts
218
+ const withParticipants = event.patch({
219
+ participants: {
220
+ p1: { "@type": "Participant", roles: { attendee: true }, email: "a@example.com" },
221
+ },
222
+ });
223
+ ```
224
+
225
+ Two common patterns for nested patches:
226
+
227
+ 1) Set raw values directly
228
+ ```ts
229
+ const withLocations = event.patch({
230
+ locations: {
231
+ l1: { "@type": "Location", name: "Room A" },
232
+ },
233
+ });
234
+ ```
235
+
236
+ 2) Use helpers to build or merge map values
237
+ ```ts
238
+ const withLocations = event.patch({
239
+ locations: JsCal.locations([
240
+ { id: "l1", value: JsCal.Location({ name: "Room A" }) },
241
+ { value: JsCal.Location({ name: "Room B" }) },
242
+ ]),
243
+ });
244
+ ```
245
+
246
+ To merge into an existing map, pass the current map as the second argument:
247
+ ```ts
248
+ const withLocations = event.patch({
249
+ locations: JsCal.locations(
250
+ [{ value: JsCal.Location({ name: "Room C" }) }],
251
+ event.data.locations,
252
+ ),
253
+ });
254
+ ```
255
+
218
256
  ## Date Inputs and Time Zones
219
257
 
220
258
  Date fields accept either RFC 8984 strings or JavaScript `Date`. When a
@@ -351,26 +389,6 @@ const icalMany = JsCal.toICal([event, task], { includeXJSCalendar: true });
351
389
  console.log(icalMany);
352
390
  ```
353
391
 
354
- ## Practical Example
355
-
356
- **Weekly engineering sync (every Wednesday 10:30, 1 hour)**
357
-
358
- ```ts
359
- const weekly = new JsCal.Event({
360
- title: "Engineering Sync",
361
- start: "2026-02-04T10:30:00",
362
- timeZone: "Asia/Tokyo",
363
- duration: JsCal.duration.hours(1),
364
- recurrenceRules: [
365
- {
366
- "@type": "RecurrenceRule",
367
- frequency: "weekly",
368
- byDay: [{ "@type": "NDay", day: "we" }],
369
- },
370
- ],
371
- });
372
- ```
373
-
374
392
  ## Compliance and Deviations
375
393
 
376
394
  ### RFC 8984 Conformance (Implemented)
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@craftguild/jscalendar",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "RFC 8984 (JSCalendar) data model helpers for TypeScript",
5
+ "license": "MIT",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
7
8
  "types": "dist/index.d.ts",