아키텍처#
소스 구조#
플러그인의 모든 로직은 src/ 아래에 있습니다:
파일 |
역할 |
|---|---|
|
플러그인 진입점: 설정을 불러오고, 사이드바/월간 뷰, 에디터 서제스트, 라이브 프리뷰 확장, 포스트프로세서를 등록합니다. 사이드바에서 캘린더 열기, 새 탭에서 캘린더 열기, 캘린더 새로고침 명령을 추가합니다. |
|
공유 타입: |
|
기본 설정값과 설정 UI. |
|
공식 |
|
최소한의 읽기 전용 CalDAV 클라이언트입니다: Obsidian의 |
|
|
|
|
|
계정에 설정된 시간대( |
|
|
|
|
|
노트의 |
|
|
|
|
|
인라인 일정 칩과, 클릭하면 열리는 상세 팝업(직접 위치를 계산하는 플로팅 패널, 바깥 클릭이나 Esc로 닫힘)입니다. 조회 범위는 |
|
Live Preview에서 |
|
읽기 모드에서 같은 치환을 수행하는 마크다운 포스트프로세서로, 렌더링된 텍스트 노드를 직접 스캔합니다 - |
|
사이드바 아젠다 목록입니다: 고정 30일 범위의 |
|
전체 탭 월간 그리드 뷰로(아젠다 목록과 같은 |
|
월간 뷰 제목에서 여는 연도/월 선택창으로, 클릭하면 편집 가능해지는 연도 입력란이 있습니다. |
데이터 흐름#
settingsTab.ts --> CalDavAccount[] (server URL, credentials, calendars)
|
v
caldav/client.ts --> PROPFIND/REPORT over requestUrl
| (discovery + event fetch)
v
caldav/ics.ts --> parses each VEVENT into a CalDavEvent
|
v
caldav/recurrence.ts --> expands RRULE occurrences on demand
|
v
caldav/store.ts --> merged, cached, scoped CalDavEvent[]
|
+--> editorSuggest/*.ts --> autocomplete while typing
|
+--> render/livePreview.ts --> widget/chip (Live Preview)
|
+--> render/postProcessor.ts --> widget/chip (Reading view)
| |
| v
| render/eventChip.ts + eventCard.ts --> click-to-open detail popup
|
+--> view/AgendaItemView.ts / vue/AgendaView.vue --> sidebar list
|
+--> view/MonthItemView.ts / vue/MonthView.vue --> month grid
notes/noteEvents.ts (vault-wide frontmatter scan) --> NoteEvent[]
|
+--> (merged into a CalendarListItem[] alongside CalDavEvent[],
inside AgendaItemView.ts/MonthItemView.ts, right before
the sidebar list / month grid above render - nothing else
in this diagram ever sees a NoteEvent)
참조 문법#
{{hrcal:<accountId>:<calendarName>:date:YYYY-MM-DD}}는 날짜 위젯으로, {{hrcal:<accountId>:<calendarName>:event:<uid>}}는 일정 칩으로 렌더링됩니다. 보통은 단계별 {{hrcal: 에디터 서제스트로 삽입되지만, 둘 다 직접 손으로 입력해도 됩니다 — 해석할 수 없는 참조는 조용히 실패하는 대신 흐릿한 점선 칩으로(또는 계정/캘린더가 등록된 것과 일치하지 않는 날짜라면 위젯 안의 경고로) 표시됩니다.
두 종류 모두 항상 참조에 직접 명시된 accountId/calendarName으로 범위가 정해집니다 - 노트 프론트매터(harang-account/harang-calendar, 사용법 참고)는 더 이상 여기서 아무 역할도 하지 않습니다. accountId는 표시 이름이 아니라 계정의 안정적인 내부 id로, 계정이 생성될 때 한 번 만들어져 이후로 바뀌지 않으므로, 이 id 기반 방식이 적용된 뒤에 삽입한 참조는 설정에서 계정 이름을 바꿔도 영향을 받지 않습니다. 반면 calendarName은 여전히 캘린더의 표시 이름이라, 캘린더 이름을 바꾸면 이 변경 이전과 마찬가지로 기존 참조가 깨질 수 있습니다. id-또는-이름 대체 처리(fallback)가 없으므로, 이 변경 이전에 작성된 참조 — 계정의 예전 이름 기반 구간을 담고 있는 — 는 더 이상 해석되지 않으며 {{hrcal: 에디터 서제스트로 지우고 다시 삽입해야 합니다.
노트 일정(harang-date/harang-repeat/harang-time)#
위 참조 문법과는 무관합니다: harang-date 프론트매터(사용법 참고)가 있는 노트는 NoteEvent가 되어 사이드바 아젠다 목록과 월간 그리드에만 항목으로 나타납니다 — {{hrcal:...}} 날짜 위젯이나 일정 칩에는 절대 나타나지 않고, CalDAV 서버에 쓰거나 읽는 일도 전혀 없습니다. harang-repeat은 caldav/recurrence.ts와 같은 rrule 패키지를 재사용하지만, 그 모듈의 함수를 그대로 공유하는 대신 자체적으로 처음부터 작성한 전개 로직을 씁니다(위 notes/noteEvents.ts 참고) — 노트 일정은 기본적으로 시간 개념이 전혀 없어서, 이 프로젝트에서 여러 번 겪고(그리고 고친) 로컬/UTC 종일 날짜 불일치를 여기서도 겪지 않으려면 날짜 계산 전체를 일관되게 UTC 자정 기준으로 처리해야 하기 때문입니다. harang-time은 그 종일 날짜 계산 위에 선택적인 HH:MM-HH:MM 표시 범위를 얹을 뿐입니다 — NoteEvent가 시간대가 있는 CalDAV 일정과 나란히 어떻게 표시되고 정렬되는지에만 영향을 주고, (여전히 UTC 자정 기준인) 날짜 전개 자체는 바뀌지 않습니다.
rrule 외에는 런타임 의존성 없음#
Obsidian 자체가 제공하는 것(obsidian 패키지, CodeMirror 6, Vue 3)과 반복 일정 전개용 rrule 패키지 외에는 런타임 의존성이 없습니다 — CalDAV 클라이언트와 iCalendar 파서 모두 npm에서 가져오지 않고 직접 작성해서, 번들 크기를 작게 유지하고 서드파티 HTTP/XML 파싱 라이브러리 자체의 취약점에 노출되는 것을 피합니다.