Skip to content

sen-ltd/diary-local

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

diary-local

ブラウザだけで動く日記アプリ。月カレンダーから日付を選んで書く、データは localStorage に保存 されてサーバには 1 byte も送らない。連続日数 (streak) と総文字数を表示。JSON 形式でのエクスポート / インポートで端末間移行も可能。

diary-local の画面: 暗色テーマで上に "2026 5 月" の月カレンダー (6 行 × 7 列)。今日 (17) が青枠でハイライト、記録済みの日付には緑のドット。下にエントリエディタ (2026-05-17, 38 字、textarea に「今日のことを書く。新しいツールをデプロイした。20 件のテストが pass。」)。4 枚のスタッツカード: 記録した日数 9 / 連続日数 (現在) 6 / 最長連続 6 / 総文字数 125。下部に JSON エクスポート / JSON インポート / 全消去 ボタン

ローカル起動

npm run serve        # python3 -m http.server 8096
# open http://localhost:8096

ブラウザの localStorage に保存するので、別のブラウザ / 端末で開くと別のデータになる。共有したいときは JSON エクスポート → 移行先で JSON インポート。

何をしているか

  1. 月カレンダー UI: 6 行 × 7 列のグリッド、前月末・翌月頭の adjacent 日も描画 (Sunday-first)
  2. 日付クリック → エディタにその日のエントリをロード
  3. 入力 → 280 ms debounce → localStorage 保存。空文字列なら削除 (key 自体が消える)
  4. stat 行 に「記録した日数 / 連続日数 (現在) / 最長連続 / 総文字数」を即時計算で表示
  5. JSON エクスポート / インポート で端末間移行と backup を可能に

純粋ロジックの分離

diary.js は DOM 非依存 (localStorage を直接触らず、Storage-like オブジェクトを受け取る形):

  • formatDate(d) / parseDate(iso) — UTC ベースの ISO 日付変換
  • keyForDate(iso) / isDiaryKey(k) / dateFromKey(k)diary:YYYY-MM-DD key のラップ
  • monthGrid(year, month, todayIso?, weekStart?) — 6×7 のセル配列 ({iso, day, inMonth, isToday})
  • characterCount(text) — code-point ベースの文字数 (CJK / emoji 1 字 = 1)
  • daysBetween(a, b) — 符号付き日数差
  • currentStreak(dates, todayIso) / longestStreak(dates) — 連続日数
  • totalCharacters(entries) — 全エントリの合計文字数
  • readEntries(storageLike) — localStorage 互換オブジェクトから iso → text を抽出

script.js は DOM と localStorage の I/O だけを持ち、計算は全部 diary.js 経由。

テスト

npm test

20 ケース、テストフレームワーク不要 (node --test)。localStorage / DOM は触らず、ピュアロジック側を覆っている:

  • 日付変換: Date と {year, month, day} 両対応、UTC ベース、malformed 入力の rejection
  • monthGrid: 6×7 セル数、in-month 数 (31 日月で 31)、weekStart=0/1、年またぎ
  • characterCount: code-point ベース (CJK / emoji)、whitespace の trim/collapse、non-string → 0
  • streak: 4 連続が 4 と評価される、today なしで 0、途中の missing day で break
  • longestStreak: 複数の run の中で最大、空 / 1 件のエッジケース
  • readEntries: Storage-like API、prefix フィルタ、空文字列を除外、malformed input → {}

やらなかったこと

  • 複数行エントリの Markdown レンダリング — 日記は素の text で十分という判断。プレビューが欲しいなら別エントリの仕事
  • 画像添付 — localStorage に base64 で保存すると 5 MB のクォータをすぐ食う。IndexedDB に書く形なら可能だが、複雑度が上がる
  • タグ付け / 検索 — 一覧性は月カレンダーで足りるという仮定。エントリ数が 1000 を超えたら必要になるかも
  • 暗号化 — localStorage は同じドメインの JS から全部読める。完全に保護したいならクライアント側 AES-GCM + ユーザーパスフレーズが要るが、本ツールのスコープ外

ライセンス

MIT — see LICENSE.

Links

About

Browser-only journaling. Pick a date on the month grid, type, see today's entry alongside your current streak and total characters. Data stays in localStorage; nothing leaves the page.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors