BoxPistols / BoxPistols/BoostRecord
[トラッキング][Web版] サーバーレスの BoostRecord Web
- Dominant language
- JavaScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 11m
- Merged PRs (30d)
- 19
Description
インストール不要でブラウザから使える軽量版を作る。**バックエンドを持たない**のが設計の中核。
## なぜこの形なのか
Boostnote本家の死因は、[2021年にローカルストレージを削除してサインイン必須にした](https://github.com/BoostIO/BoostNote-Legacy/issues/3709)ことにあります。個人のローカルノートアプリから、[*"document driven project management tool that maximizes remote DevOps team velocity"*](https://github.com/BoostIO/BoostNote-App) への転換。Notionの土俵に、Notionの何十分の一のリソースで乗った結果、コア層が離れて2022年に開発が止まり、[2025年9月30日にサービス終了](``https://alternativeto.net/news/2025/6/boost-note-service-is-shutting-down-in-september-2025-and-urges-users-to-export-data/)しました。``
マネタイズの失敗が原因というより、**マネタイズのためにプロダクトの正体を変えたことが原因**です。
**バックエンドを持たなければ運用費がゼロになり、マネタイズの圧力そのものが発生しません。** 同じ死に方を構造的に回避できます。
## 前提: 設計はすでにこの形に備えている
`app/src/data/repository.ts` の `NotesRepository` がデータ層のシームとして定義済みです。
> The renderer only ever talks to a NotesRepository; the Electron build will provide an implementation that reads/writes real `.cson` files in the main process and bridges them over IPC. **The browser foundation uses an in-memory repository seeded with sample data.**
```
React (app/src)
↓ NotesRepository(シーム)
├─ Electron : window.boostnote → preload → main → node:fs [実装済み]
├─ in-memory : sampleNotes.ts [実装済み]
└─ Web : File System Access API [これを追加]
```
**Web版は3つ目の実装を足すだけ**で、契約(`app/src/electron.d.ts` の6メソッド)は変更不要です。
## 実装方針
| 契約 | Web実装 |
|---|---|
| `pickStorage()` | `showDirectoryPicker()` → `FileSystemDirectoryHandle` を取得し `notes/*.cson` を走査 |
| `loadNotes()` | IndexedDBに永続化したハンドルを復元 → `queryPermission()` / `requestPermission()` |
| `saveNote(note)` | `getFileHandle(key + '.cson', {create:true})` → `createWritable()` |
| `createNote(opts)` | 同上 |
| `deleteNote(key)` | `removeEntry(key + '.cson')` |
| `exportNote(payload)` | `showSaveFilePicker()`、非対応時はBlobダウンロード |
**デスクトップ版と同じ `.cson` フォルダを、Web版から直接読み書きできます。** 同期サーバーは不要です。
## ブラウザ対応([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/showDirectoryPicker) 準拠)
`showDirectoryPicker` は **Chromium系のみ**。FirefoxとSafariは非対応(Safari 15.2+ はOPFSのみ)。二段構えにします。
| ブラウザ | 保存先 | 体験 |
|---|---|---|
| Chrome / Edge / Opera | ローカルフォルダを直接 | デスクトップ版と同じ実体を共有。本命 |
| Safari / Firefox | OPFS(ブラウザprivate)| zipの入出力でデータを出し入れ |
## 検証済みの技術的事実
`.cson` のパースがブラウザで動くかを実測しました。
- `cson-parser@1.3.4` は `lib/` 内で **node組み込み(`fs` / `path` / `node:*`)を一切参照していない**
- parse / stringifyの往復を実行し、**日本語と `"""` 複数行ブロックを含むケースで正しく復元**されることを確認
- 依存は `coffee-script@^1.10.0` のみ。ディスク上456K(未圧縮)
→ **ブラウザで動きます。** ただしバンドルサイズは要計測です。重すぎる場合、Boostnoteの `.cson` はCSONのごく一部の構文しか使っていないため、サブセット専用パーサを書く選択肢があります。
## やらないこと(最重要)
- アカウント / サインイン
- 同期サーバー
- チーム機能・課金
**これを足した瞬間にBoostnoteの死に方をなぞります。** `poc/collab-core` のYjs + self-host Hocuspocusは「使いたい人が自分で立てる」オプションに留め、**デフォルトの体験にはしない**。
## 段階
| Phase | 内容 | 状態 |
|---|---|---|
| A | FSAアダプタ + ハンドルのIndexedDB永続化 | #175でマージ済み。実ブラウザ確認は #177 |
| B | OPFSフォールバック + zipの入出力 | #178 |
| C | 静的サイトとして公開 | #179 |
| D | PWA化 | #180 |
このIssueは以降トラッキング用です。
## 未解決の設計論点
1. **ディレクトリハンドルの再許可UX** — Chromeはセッションをまたぐと権限の再付与(クリック)を要求します。起動のたびに「フォルダを許可」を押させない導線をどう作るか
2. **デスクトップ版との同時編集** — 同じフォルダを両方から開いた場合の競合検知。最低限、書き込み前のmtime比較は要る
3. **バンドルサイズ** — 計測してからCSONパーサの方針を決める
Contributor guide
Research direction
Start with app/src/data/repository.ts and the six-method contract in app/src/electron.d.ts. Then inspect the implementation and status of phases #175–#180, beginning with the merged FSA work in #175 and browser verification in #177. This tracking issue has no single remaining change or completion test; its scope is split across those follow-up issues.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- frontend, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100