hikoutei 0.4.3 → 0.4.6
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.ja.md +155 -103
- package/README.ko.md +151 -107
- package/README.md +112 -80
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts +2 -2
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js +2 -2
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js.map +1 -1
- package/dist/api/Hikoutei.d.ts +56 -10
- package/dist/api/Hikoutei.d.ts.map +1 -1
- package/dist/api/Hikoutei.js +84 -13
- package/dist/api/Hikoutei.js.map +1 -1
- package/dist/api/entity.d.ts +17 -1
- package/dist/api/entity.d.ts.map +1 -1
- package/dist/api/entity.js +34 -2
- package/dist/api/entity.js.map +1 -1
- package/dist/api/errors.d.ts +24 -0
- package/dist/api/errors.d.ts.map +1 -1
- package/dist/api/errors.js +24 -0
- package/dist/api/errors.js.map +1 -1
- package/dist/application/orm/api/contracts.d.ts +1 -1
- package/dist/application/orm/api/contracts.d.ts.map +1 -1
- package/dist/application/orm/persistence/flush/flushCoordinator.d.ts.map +1 -1
- package/dist/application/orm/persistence/flush/flushCoordinator.js +2 -0
- package/dist/application/orm/persistence/flush/flushCoordinator.js.map +1 -1
- package/dist/application/sync/inbound/autoSystemConflictResolution.d.ts.map +1 -1
- package/dist/application/sync/inbound/autoSystemConflictResolution.js +3 -0
- package/dist/application/sync/inbound/autoSystemConflictResolution.js.map +1 -1
- package/dist/application/sync/service/SyncServiceBootstrap.d.ts.map +1 -1
- package/dist/application/sync/service/SyncServiceBootstrap.js +85 -3
- package/dist/application/sync/service/SyncServiceBootstrap.js.map +1 -1
- package/dist/application/sync/service/syncAutoStart.d.ts +127 -0
- package/dist/application/sync/service/syncAutoStart.d.ts.map +1 -0
- package/dist/application/sync/service/syncAutoStart.js +280 -0
- package/dist/application/sync/service/syncAutoStart.js.map +1 -0
- package/dist/application/sync/sheets/conflictProjectionRegistration.d.ts.map +1 -1
- package/dist/application/sync/sheets/conflictProjectionRegistration.js +1 -0
- package/dist/application/sync/sheets/conflictProjectionRegistration.js.map +1 -1
- package/dist/infrastructure/storage/index.d.ts +2 -2
- package/dist/infrastructure/storage/index.d.ts.map +1 -1
- package/dist/infrastructure/storage/index.js +1 -1
- package/dist/infrastructure/storage/index.js.map +1 -1
- package/dist/infrastructure/storage/state/mapped/mappedPersistenceContext.d.ts.map +1 -1
- package/dist/infrastructure/storage/state/mapped/mappedPersistenceContext.js +1 -0
- package/dist/infrastructure/storage/state/mapped/mappedPersistenceContext.js.map +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -4,11 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
# Hikoutei
|
|
6
6
|
|
|
7
|
-
**Google Sheets
|
|
7
|
+
**SQLite でアプリは高速に、Google Sheets でワークフローを見えるままに。**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
Google Sheets を利用する MVP 向けの型付きリポジトリであり、安全な書き込み
|
|
10
|
+
レイヤー: アプリケーションは型付きエンティティでローカル SQLite を読み書きし、
|
|
11
|
+
コミットされた変更は、人が確認して軽くコラボレーションできるよう Google
|
|
12
|
+
Sheets へ非同期で投影されます。
|
|
13
|
+
|
|
14
|
+
<a href="https://www.npmjs.com/package/hikoutei">npm</a> ·
|
|
15
|
+
<a href="docs/quick-start.md">クイックスタート</a> ·
|
|
16
|
+
<a href="https://github.com/ManddarinShop/Hikoutei/issues">Issues</a>
|
|
12
17
|
|
|
13
18
|
[](https://www.npmjs.com/package/hikoutei)
|
|
14
19
|
[](LICENSE)
|
|
@@ -16,39 +21,23 @@
|
|
|
16
21
|
|
|
17
22
|
</div>
|
|
18
23
|
|
|
19
|
-
Hikoutei
|
|
20
|
-
MVP や社内ワークフローの人間向けの画面として利用できるようにします。
|
|
21
|
-
アプリケーションは型付きエンティティとローカル SQLite を使い、サービス
|
|
22
|
-
アカウントの Google Sheets provider を通して変更を Google Sheets へ非同期に
|
|
23
|
-
届けられます。
|
|
24
|
-
|
|
25
|
-
Hikoutei の対象は意図的に限定されています。汎用データベースの代替、
|
|
26
|
-
Prisma/JPA のクローン、汎用 Google Sheets API ラッパーを目的としていません。
|
|
27
|
-
|
|
28
|
-
## Hikoutei が提供するもの
|
|
24
|
+
## Hikoutei とは
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- 人による確認や軽い共同作業に使える非同期 Google Sheets ビュー。
|
|
34
|
-
- 予期しないスキーマ変更や新しいデータを上書きする問題への保護。
|
|
35
|
-
|
|
36
|
-
## インストール
|
|
26
|
+
Hikoutei は、TypeScript アプリケーションにローカル SQLite を基盤とする型付き
|
|
27
|
+
エンティティ API を提供し、コミットされた変更を Google Sheets へ非同期に
|
|
28
|
+
同期します。
|
|
37
29
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```sh
|
|
41
|
-
npm install hikoutei @mikro-orm/core @mikro-orm/sql
|
|
42
|
-
```
|
|
30
|
+
通常の読み書きでは、アプリケーションは Google Sheets を待ちません。Sheets は
|
|
31
|
+
確認・運用・軽いコラボレーションのための画面として残ります。
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
> Hikoutei は生の Sheets API ラッパーではなく、PostgreSQL の代替でもなく、
|
|
34
|
+
> Google Sheets を権威あるアプリケーションデータベースとして扱いません。
|
|
35
|
+
> SQLite が真実の源泉であり、Sheets は人向けの画面です。
|
|
47
36
|
|
|
48
37
|
## クイックスタート
|
|
49
38
|
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
スカラーエンティティを定義し、リクエストローカルなマネージャーでローカル
|
|
40
|
+
SQLite の権威を利用します。
|
|
52
41
|
|
|
53
42
|
```ts
|
|
54
43
|
import { createTypedSheets, defineTypedSheetsEntity } from "hikoutei";
|
|
@@ -76,97 +65,160 @@ user.name = "Ada Lovelace";
|
|
|
76
65
|
await em.flush();
|
|
77
66
|
```
|
|
78
67
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
68
|
+
**シートには何が起きるのか?** 書き込みは即座にローカル SQLite へコミット
|
|
69
|
+
されます — アプリケーションのリクエストは Google を待ちません。同期サービスが
|
|
70
|
+
有効な場合、Hikoutei は後でエンティティを登録済みの Google Sheet へバック
|
|
71
|
+
グラウンドで投影します。シート上で行われた人の編集は観察・検証され、SQLite
|
|
72
|
+
へ受け入れられるか競合として記録されるかのどちらかで、決して静かに上書き
|
|
73
|
+
されません。
|
|
74
|
+
|
|
75
|
+
## Hikoutei を使う理由
|
|
76
|
+
|
|
77
|
+
- シートの行を手動で変換する代わりに、型付きエンティティを定義する。
|
|
78
|
+
- Google Sheets を待たずにローカル SQLite で読み書きする。
|
|
79
|
+
- コミットされた変更を Sheets へバックグラウンドで同期する。
|
|
80
|
+
- 予期しない列の変更や重複ヘッダーを検出する。
|
|
81
|
+
- 競合時に新しいシート編集を上書きしない。
|
|
84
82
|
|
|
85
83
|
## Hikoutei が適しているケース
|
|
86
84
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
|
|
91
|
-
-
|
|
85
|
+
Hikoutei は以下のケースに適しています。
|
|
86
|
+
|
|
87
|
+
- 製品ワークフローの一部にスプレッドシートがある MVP・プロトタイプ
|
|
88
|
+
- 社内ツールや低トラフィックの管理アプリケーション
|
|
89
|
+
- 人が Sheets を簡単に確認しつつ、型付きのアプリケーションデータを扱いたい
|
|
90
|
+
チーム
|
|
91
|
+
- SQLite をローカルで使い、非同期のシート更新を受け入れられるサービス
|
|
92
92
|
|
|
93
|
-
##
|
|
93
|
+
## 他のツールを選ぶべきケース
|
|
94
94
|
|
|
95
|
-
次の要件がある場合は、通常のデータベースと Google API
|
|
95
|
+
次の要件がある場合は、通常のデータベースと Google API を直接使ってください。
|
|
96
96
|
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
- Google Sheets
|
|
102
|
-
- Google Sheets
|
|
97
|
+
- 多くの行やサービスにまたがる強いトランザクション
|
|
98
|
+
- 高い書き込みスループットや多数の同時ライター
|
|
99
|
+
- 複雑なクエリ・JOIN・レポートワークロード
|
|
100
|
+
- マルチサーバー・マルチリージョンでの調整
|
|
101
|
+
- Google Sheets での読み取り直後の整合性
|
|
102
|
+
- Google Sheets をアプリケーションの主要データベースとして使う場合
|
|
103
|
+
|
|
104
|
+
## Hikoutei はあなたに合った抽象化か?
|
|
105
|
+
|
|
106
|
+
Hikoutei は `google-spreadsheet` や `@googleapis/sheets` を置き換えるものでは
|
|
107
|
+
ありません — その一段上に位置します。生のスプレッドシート操作だけが必要なら、
|
|
108
|
+
API クライアントを直接使ってください。
|
|
109
|
+
|
|
110
|
+
| 機能 | Hikoutei | google-spreadsheet | @googleapis/sheets |
|
|
111
|
+
| --- | :-: | :-: | :-: |
|
|
112
|
+
| 型付きエンティティモデル | ✅ | ❌ | ❌ |
|
|
113
|
+
| 高速なローカルアプリケーション読み取り | ✅ | ❌ | ❌ |
|
|
114
|
+
| Sheets への非同期投影 | ✅ | ❌ | ❌ |
|
|
115
|
+
| 永続的な書き込み再試行と重複排除 | ✅ | ❌ | ❌ |
|
|
116
|
+
| 競合を考慮したシート更新 | ✅ | ❌ | ❌ |
|
|
117
|
+
| 行・セルの直接操作 | 限定的 | ✅ | ✅ |
|
|
118
|
+
| Google Sheets API へのフルアクセス | Provider 経由 | 部分的 | ✅ |
|
|
103
119
|
|
|
104
120
|
## Google Sheets の設定
|
|
105
121
|
|
|
106
|
-
Google Sheets
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
URL
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
122
|
+
Google Sheets の同期はサービス側の関心事です。アプリケーションは provider
|
|
123
|
+
クライアントを import したり、`createTypedSheets()` にシートルートを渡したり、
|
|
124
|
+
書き込みごとに操作を選んだりしません。同期ランタイムはサービスアカウントを
|
|
125
|
+
使う単一の Google Sheets API provider(内部 `googleSheetsApi` bootstrap オプ
|
|
126
|
+
ション)を使用します — Apps Script のデプロイは不要です。
|
|
127
|
+
|
|
128
|
+
### 環境変数による同期の自動開始
|
|
129
|
+
|
|
130
|
+
スプレッドシートの URL を環境変数に設定すると、`createTypedSheets()` が内部で
|
|
131
|
+
Sheets 同期を開始します — `flush()` はセットアップコードなしで outbox
|
|
132
|
+
ワーカー経由で Google Sheets に流れます:
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
HIKOUTEI_SYNC_SPREADSHEET_URL=https://docs.google.com/spreadsheets/d/<ID>/edit
|
|
136
|
+
GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/service-account.json
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
const hikoutei = await createTypedSheets({ dbName: "./hikoutei.sqlite", entities: [User] });
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`HIKOUTEI_SYNC_SPREADSHEET_URL` がない場合、`createTypedSheets()` はローカル
|
|
144
|
+
専用 (SQLite) のままです。起動失敗は明確なメッセージで診断されます: URL の
|
|
145
|
+
不正、資格情報ファイルの欠落・不正、スプレッドシートに共有されていない
|
|
146
|
+
サービスアカウント (共有すべきメールアドレスをエラーが教えてくれます)。
|
|
147
|
+
|
|
148
|
+
### Service-account provider (googleSheetsApi)
|
|
149
|
+
|
|
150
|
+
1. **サービスアカウントを作成する。** Cloud プロジェクトで Google Sheets API
|
|
151
|
+
を有効化し、`https://www.googleapis.com/auth/spreadsheets` スコープの
|
|
152
|
+
サービスアカウントを作成して、対象スプレッドシートをそのメールアドレスに
|
|
153
|
+
**編集者(Editor)**として共有します。provider がタブを作成し、効果行と
|
|
154
|
+
receipt レコードを書き、行アンカーを管理するため、閲覧者権限では不十分
|
|
155
|
+
です。
|
|
156
|
+
2. **キーはサーバー側に置く。** サービスアカウントのキーパスはサーバーの
|
|
157
|
+
`GOOGLE_APPLICATION_CREDENTIALS` に、スプレッドシート ID は追跡されない
|
|
158
|
+
シークレットストアに置きます。キーをブラウザコードや Git に入れないで
|
|
159
|
+
ください。
|
|
160
|
+
3. **内部 sync bootstrap を起動する。** `googleSheetsApi` を設定すると、
|
|
161
|
+
登録済みタブのヘッダーを作成・検証した後、outbox 配信と User_Input ポー
|
|
162
|
+
リングを開始します。
|
|
163
|
+
|
|
164
|
+
Hikoutei は、永続的なローカル outbox・冪等な配信・競合を考慮した更新を使う
|
|
165
|
+
ため、一時的な API 障害でコミット済みのアプリケーション書き込みが失われる
|
|
166
|
+
ことはありません。provider は資格情報・スプレッドシート ID・URL・ペイロードを
|
|
167
|
+
ログに残さず、Google の割り当て枠に収まるようリクエスト開始間隔を調整します。
|
|
168
|
+
詳細な状態機械と復旧ルールは[内部整合性モデル](docs/internal-consistency-model.md)を
|
|
169
|
+
参照してください。
|
|
170
|
+
|
|
171
|
+
ライブの Google 呼び出しはオプトインであり、通常の検証経路はフェイク
|
|
172
|
+
provider と SQLite フィクスチャです。詳細なセットアップとトラブルシューティン
|
|
173
|
+
グは[クイックスタート](docs/quick-start.md)を参照してください。
|
|
174
|
+
|
|
175
|
+
## インストール
|
|
176
|
+
|
|
177
|
+
プロジェクト名と npm パッケージ名はどちらも `hikoutei` です。現在の組み込み
|
|
178
|
+
SQLite provider は MikroORM を必要とします。
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
npm install hikoutei @mikro-orm/core @mikro-orm/sql
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
MikroORM は実装の詳細であり、Hikoutei の公開エンティティ API には現れません。
|
|
143
185
|
|
|
144
186
|
## ドキュメント
|
|
145
187
|
|
|
146
|
-
- [クイックスタート](docs/quick-start.md) — インストール、ORM
|
|
147
|
-
|
|
148
|
-
- [
|
|
149
|
-
- [
|
|
150
|
-
|
|
188
|
+
- [クイックスタート](docs/quick-start.md) — インストール、ORM ライフサイクル、
|
|
189
|
+
サービス側の同期設定
|
|
190
|
+
- [アーキテクチャ](docs/architecture.md) — ローカルストアとシートビューの関係
|
|
191
|
+
- [書き込みと同期フロー](docs/write-and-synchronization-flow.md) — 非同期配信と
|
|
192
|
+
復旧動作
|
|
193
|
+
- [内部整合性モデル](docs/internal-consistency-model.md) — 永続的な outbox、
|
|
194
|
+
冪等な配信、競合を考慮した更新
|
|
195
|
+
- [開発](docs/development.md) — ローカル開発とテストコマンド
|
|
196
|
+
- [ベンチマークノート](docs/sync-bulk-write-benchmark.md) — 日付付きの測定と
|
|
197
|
+
その限界
|
|
151
198
|
|
|
152
199
|
## 制限事項
|
|
153
200
|
|
|
154
|
-
- Google Sheets
|
|
155
|
-
-
|
|
156
|
-
- SQLite
|
|
157
|
-
-
|
|
158
|
-
|
|
201
|
+
- Google Sheets には割り当て枠・レイテンシ・API レート制限があります。
|
|
202
|
+
- シートの更新は非同期であり、アプリケーションはローカル状態を読むべきです。
|
|
203
|
+
- SQLite はサービスのローカルのみであり、分散調整レイヤーではありません。
|
|
204
|
+
- スキーマ変更・手動編集・競合更新には、依然としてアプリケーションの運用
|
|
205
|
+
ポリシーが必要です。
|
|
206
|
+
|
|
207
|
+
## プロジェクトステータス
|
|
208
|
+
|
|
209
|
+
Hikoutei は活発に開発中です。エンティティ API は利用可能ですが、シート編集の
|
|
210
|
+
取り込みと競合表示はまだ発展途上です。マイナーバージョンのアップグレード前に
|
|
211
|
+
リリースノートを確認してください。
|
|
159
212
|
|
|
160
213
|
## ロードマップ
|
|
161
214
|
|
|
162
|
-
- Google Sheets
|
|
163
|
-
-
|
|
164
|
-
- レジストリと直接 provider
|
|
165
|
-
- 公開パッケージのリリースを安定化する。
|
|
215
|
+
- Google Sheets からの意図的なユーザー編集の取り込みを完了する
|
|
216
|
+
- 更新・削除の競合処理と表示を改善する
|
|
217
|
+
- レジストリと直接 provider デプロイのセットアップツールを追加する
|
|
166
218
|
|
|
167
|
-
|
|
168
|
-
|
|
219
|
+
現在の作業は[オープンな Issues](https://github.com/ManddarinShop/Hikoutei/issues)を
|
|
220
|
+
参照してください。
|
|
169
221
|
|
|
170
222
|
## ライセンス
|
|
171
223
|
|
|
172
|
-
Hikoutei は [MIT
|
|
224
|
+
Hikoutei は [MIT ライセンス](LICENSE)で公開されています。
|
package/README.ko.md
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
# Hikoutei
|
|
6
6
|
|
|
7
|
-
**
|
|
7
|
+
**SQLite로 앱은 빠르게, Google Sheets로 업무 흐름은 눈에 보이게.**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
Google Sheets 기반 MVP를 위한 타입 안전 리포지토리이자 안전한 쓰기 계층:
|
|
10
|
+
애플리케이션은 타입이 지정된 엔티티로 로컬 SQLite를 읽고 쓰고, 커밋된 변경은
|
|
11
|
+
사람이 검토하고 가볍게 협업할 수 있도록 Google Sheets에 비동기로 투영됩니다.
|
|
12
|
+
|
|
13
|
+
<a href="https://www.npmjs.com/package/hikoutei">npm</a> ·
|
|
14
|
+
<a href="docs/quick-start.md">빠른 시작</a> ·
|
|
15
|
+
<a href="https://github.com/ManddarinShop/Hikoutei/issues">이슈</a>
|
|
12
16
|
|
|
13
17
|
[](https://www.npmjs.com/package/hikoutei)
|
|
14
18
|
[](LICENSE)
|
|
@@ -16,39 +20,22 @@
|
|
|
16
20
|
|
|
17
21
|
</div>
|
|
18
22
|
|
|
19
|
-
Hikoutei
|
|
20
|
-
내부 업무 흐름의 사람이 읽기 쉬운 화면으로 사용할 수 있게 합니다. 애플리케이션은
|
|
21
|
-
타입이 지정된 엔티티와 로컬 SQLite를 사용하고, 서비스 계정 기반 Google
|
|
22
|
-
Sheets provider를 통해 변경 내용을 Google Sheets에 비동기적으로 전달할 수
|
|
23
|
-
있습니다.
|
|
24
|
-
|
|
25
|
-
Hikoutei의 범위는 의도적으로 작습니다. 범용 데이터베이스 대체재, Prisma/JPA
|
|
26
|
-
클론, 범용 Google Sheets API 래퍼를 목표로 하지 않습니다.
|
|
27
|
-
|
|
28
|
-
## Hikoutei가 제공하는 것
|
|
23
|
+
## Hikoutei란 무엇인가?
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- 원격 스프레드시트 요청을 기다리지 않는 로컬 SQLite 조회.
|
|
33
|
-
- 사람이 검토하고 가볍게 협업할 수 있는 비동기 Google Sheets 뷰.
|
|
34
|
-
- 예상하지 못한 스키마 변경과 최신 데이터를 덮어쓰는 문제에 대한 보호.
|
|
35
|
-
|
|
36
|
-
## 설치
|
|
25
|
+
Hikoutei는 TypeScript 애플리케이션에 로컬 SQLite를 기반으로 한 타입 지정
|
|
26
|
+
엔티티 API를 제공하고, 커밋된 변경을 Google Sheets에 비동기로 동기화합니다.
|
|
37
27
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```sh
|
|
41
|
-
npm install hikoutei @mikro-orm/core @mikro-orm/sql
|
|
42
|
-
```
|
|
28
|
+
일반적인 읽기와 쓰기에서 애플리케이션은 Google Sheets를 기다리지 않습니다.
|
|
29
|
+
Sheets는 검토, 운영, 가벼운 협업을 위한 화면으로 남습니다.
|
|
43
30
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
31
|
+
> Hikoutei는 원시 Sheets API 래퍼가 아니며, PostgreSQL의 대체재도 아니고,
|
|
32
|
+
> Google Sheets를 권위 있는 애플리케이션 데이터베이스로 취급하지 않습니다.
|
|
33
|
+
> SQLite가 진실의 원천이고, Sheets는 사람을 위한 화면입니다.
|
|
47
34
|
|
|
48
35
|
## 빠른 시작
|
|
49
36
|
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
스칼라 엔티티를 정의하고 요청-로컬 매니저를 통해 로컬 SQLite authority를
|
|
38
|
+
사용합니다.
|
|
52
39
|
|
|
53
40
|
```ts
|
|
54
41
|
import { createTypedSheets, defineTypedSheetsEntity } from "hikoutei";
|
|
@@ -76,100 +63,157 @@ user.name = "Ada Lovelace";
|
|
|
76
63
|
await em.flush();
|
|
77
64
|
```
|
|
78
65
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
66
|
+
**시트에는 무슨 일이 일어날까?** 쓰기는 즉시 로컬 SQLite에 커밋됩니다 —
|
|
67
|
+
애플리케이션 요청은 Google을 기다리지 않습니다. 동기화 서비스가 활성화되면
|
|
68
|
+
Hikoutei는 나중에 엔티티를 등록된 Google Sheet에 백그라운드로 투영합니다.
|
|
69
|
+
시트에서 이루어진 사람의 수정은 관찰되고 검증되어 SQLite로 수용되거나
|
|
70
|
+
충돌로 기록되며, 절대 조용히 덮어쓰이지 않습니다.
|
|
84
71
|
|
|
85
|
-
## Hikoutei를
|
|
72
|
+
## Hikoutei를 쓰는 이유
|
|
86
73
|
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
서비스.
|
|
74
|
+
- 시트 행을 수동으로 변환하는 대신 타입 지정 엔티티를 정의합니다.
|
|
75
|
+
- Google Sheets를 기다리지 않고 로컬 SQLite로 읽고 씁니다.
|
|
76
|
+
- 커밋된 변경을 Sheets에 백그라운드로 동기화합니다.
|
|
77
|
+
- 예상치 못한 컬럼 변경과 중복 헤더를 감지합니다.
|
|
78
|
+
- 충돌 중에 더 새로운 시트 수정을 덮어쓰지 않습니다.
|
|
93
79
|
|
|
94
|
-
##
|
|
80
|
+
## Hikoutei를 쓰기 좋은 때
|
|
95
81
|
|
|
96
|
-
다음
|
|
97
|
-
검토하세요.
|
|
82
|
+
Hikoutei는 다음 상황에 잘 맞습니다.
|
|
98
83
|
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
-
|
|
104
|
-
|
|
84
|
+
- 제품 워크플로의 일부로 스프레드시트가 있는 MVP와 프로토타입
|
|
85
|
+
- 내부 도구와 저트래픽 관리 애플리케이션
|
|
86
|
+
- 사람들이 Sheets를 쉽게 확인하면서 타입 지정된 애플리케이션 데이터를
|
|
87
|
+
유지하려는 팀
|
|
88
|
+
- SQLite를 로컬에서 사용하고 비동기 시트 업데이트를 수용할 수 있는 서비스
|
|
89
|
+
|
|
90
|
+
## 다른 도구를 선택해야 할 때
|
|
91
|
+
|
|
92
|
+
다음이 필요하다면 일반 데이터베이스와 Google API를 직접 사용하세요.
|
|
93
|
+
|
|
94
|
+
- 여러 행이나 서비스에 걸친 강력한 트랜잭션
|
|
95
|
+
- 높은 쓰기 처리량 또는 많은 동시 작성자
|
|
96
|
+
- 복잡한 쿼리, 조인, 리포팅 워크로드
|
|
97
|
+
- 멀티 서버·멀티 리전 조정
|
|
98
|
+
- Google Sheets에서의 즉시 읽기-쓰기 일관성
|
|
99
|
+
- Google Sheets를 애플리케이션의 주 데이터베이스로 사용
|
|
100
|
+
|
|
101
|
+
## Hikoutei가 당신에게 맞는 추상화인가요?
|
|
102
|
+
|
|
103
|
+
Hikoutei는 `google-spreadsheet`나 `@googleapis/sheets`를 대체하지 않습니다 —
|
|
104
|
+
한 단계 위에 위치합니다. 원시 스프레드시트 접근만 필요하다면 API 클라이언트를
|
|
105
|
+
직접 사용하세요.
|
|
106
|
+
|
|
107
|
+
| 기능 | Hikoutei | google-spreadsheet | @googleapis/sheets |
|
|
108
|
+
| --- | :-: | :-: | :-: |
|
|
109
|
+
| 타입 지정 엔티티 모델 | ✅ | ❌ | ❌ |
|
|
110
|
+
| 빠른 로컬 애플리케이션 읽기 | ✅ | ❌ | ❌ |
|
|
111
|
+
| Sheets로의 비동기 투영 | ✅ | ❌ | ❌ |
|
|
112
|
+
| 내구성 있는 쓰기 재시도와 중복 제거 | ✅ | ❌ | ❌ |
|
|
113
|
+
| 충돌을 인지하는 시트 업데이트 | ✅ | ❌ | ❌ |
|
|
114
|
+
| 행·셀 직접 조작 | 제한적 | ✅ | ✅ |
|
|
115
|
+
| 전체 Google Sheets API 접근 | Provider 경유 | 부분적 | ✅ |
|
|
105
116
|
|
|
106
117
|
## Google Sheets 설정
|
|
107
118
|
|
|
108
|
-
Google Sheets 동기화는
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
`
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
119
|
+
Google Sheets 동기화는 서비스 측 관심사입니다. 애플리케이션은 provider
|
|
120
|
+
클라이언트를 import하거나, Sheet 라우트를 `createTypedSheets()`에 넘기거나,
|
|
121
|
+
쓰기마다 연산을 선택하지 않습니다. 동기화 런타임은 서비스 계정을 사용하는
|
|
122
|
+
하나의 Google Sheets API provider(내부 `googleSheetsApi` bootstrap 옵션)를
|
|
123
|
+
사용합니다 — Apps Script 배포가 없습니다.
|
|
124
|
+
|
|
125
|
+
### 환경 변수 기반 동기화 자동 시작
|
|
126
|
+
|
|
127
|
+
스프레드시트 URL을 환경 변수로 설정하면 `createTypedSheets()`가 내부적으로
|
|
128
|
+
Sheets 동기화를 시작합니다 — `flush()`는 설정 코드 없이 outbox worker를 통해
|
|
129
|
+
Google Sheets로 흘러갑니다:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
HIKOUTEI_SYNC_SPREADSHEET_URL=https://docs.google.com/spreadsheets/d/<ID>/edit
|
|
133
|
+
GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/service-account.json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
const hikoutei = await createTypedSheets({ dbName: "./hikoutei.sqlite", entities: [User] });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`HIKOUTEI_SYNC_SPREADSHEET_URL`이 없으면 `createTypedSheets()`는 로컬 전용
|
|
141
|
+
(SQLite)으로 유지됩니다. 시작 실패는 명확한 메시지로 진단됩니다: 잘못된 URL,
|
|
142
|
+
없거나 잘못된 자격 증명 파일, 스프레드시트에 공유되지 않은 서비스 계정
|
|
143
|
+
(어떤 이메일을 공유해야 하는지 에러가 알려줍니다).
|
|
144
|
+
|
|
145
|
+
### Service-account provider (googleSheetsApi)
|
|
146
|
+
|
|
147
|
+
1. **서비스 계정을 만듭니다.** Cloud 프로젝트에서 Google Sheets API를
|
|
148
|
+
활성화하고, `https://www.googleapis.com/auth/spreadsheets` 스코프의
|
|
149
|
+
서비스 계정을 만든 뒤 대상 스프레드시트를 해당 이메일에 **편집자(Editor)**로
|
|
150
|
+
공유합니다. provider가 탭을 만들고, 효과 행과 receipt 기록을 쓰고, 행
|
|
151
|
+
anchor를 관리하므로 뷰어 권한으로는 부족합니다.
|
|
152
|
+
2. **키를 서버 측에 둡니다.** 서비스 계정 키 경로를 서버의
|
|
153
|
+
`GOOGLE_APPLICATION_CREDENTIALS`에, 스프레드시트 ID는 추적되지 않는
|
|
154
|
+
비밀 저장소에 둡니다. 키를 브라우저 코드나 Git에 넣지 마세요.
|
|
155
|
+
3. **내부 sync bootstrap을 기동합니다.** `googleSheetsApi`를 설정하면
|
|
156
|
+
등록된 탭의 헤더를 만들고 검증한 뒤 outbox 전달과 User_Input 폴링을
|
|
157
|
+
시작합니다.
|
|
158
|
+
|
|
159
|
+
Hikoutei는 내구성 있는 로컬 outbox, 멱등 전달, 충돌을 인지하는 업데이트를
|
|
160
|
+
사용하므로 일시적인 API 실패가 커밋된 애플리케이션 쓰기를 잃게 하지 않습니다.
|
|
161
|
+
provider는 자격 증명, 스프레드시트 ID, URL, 페이로드를 로그에 남기지 않으며,
|
|
162
|
+
Google 할당량 창 안에 머물도록 요청 시작 간격을 조절합니다. 상세 상태 머신과
|
|
163
|
+
복구 규칙은 [내부 정합성 모델](docs/internal-consistency-model.md)을
|
|
164
|
+
참고하세요.
|
|
165
|
+
|
|
166
|
+
라이브 Google 호출은 opt-in이며, 일반적인 검증 경로는 fake provider와 SQLite
|
|
167
|
+
fixture입니다. 자세한 설정과 문제 해결 단계는 [빠른 시작](docs/quick-start.md)을
|
|
168
|
+
참고하세요.
|
|
169
|
+
|
|
170
|
+
## 설치
|
|
171
|
+
|
|
172
|
+
프로젝트와 npm 패키지 이름은 모두 `hikoutei`입니다. 내장 SQLite provider는
|
|
173
|
+
현재 MikroORM을 필요로 합니다.
|
|
174
|
+
|
|
175
|
+
```sh
|
|
176
|
+
npm install hikoutei @mikro-orm/core @mikro-orm/sql
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
MikroORM은 구현 세부 사항이며 Hikoutei의 공개 엔티티 API에는 나타나지
|
|
180
|
+
않습니다.
|
|
144
181
|
|
|
145
182
|
## 문서
|
|
146
183
|
|
|
147
|
-
- [빠른 시작](docs/quick-start.md) — 설치, ORM
|
|
148
|
-
- [아키텍처](docs/architecture.md) — 로컬 저장소와 Sheet
|
|
184
|
+
- [빠른 시작](docs/quick-start.md) — 설치, ORM 생명주기, 서비스 측 동기화 설정
|
|
185
|
+
- [아키텍처](docs/architecture.md) — 로컬 저장소와 Sheet 화면이 맞물리는 방식
|
|
149
186
|
- [쓰기 및 동기화 흐름](docs/write-and-synchronization-flow.md) — 비동기 전달과
|
|
150
|
-
복구
|
|
151
|
-
- [
|
|
152
|
-
|
|
153
|
-
|
|
187
|
+
복구 동작
|
|
188
|
+
- [내부 정합성 모델](docs/internal-consistency-model.md) — 내구성 outbox,
|
|
189
|
+
멱등 전달, 충돌을 인지하는 업데이트
|
|
190
|
+
- [개발](docs/development.md) — 로컬 개발 및 테스트 명령어
|
|
191
|
+
- [벤치마크 노트](docs/sync-bulk-write-benchmark.md) — 날짜가 기록된 측정과
|
|
192
|
+
그 한계
|
|
193
|
+
|
|
194
|
+
## 한계
|
|
195
|
+
|
|
196
|
+
- Google Sheets에는 quota, 지연, API 요청 제한이 있습니다.
|
|
197
|
+
- 시트 업데이트는 비동기이며, 애플리케이션은 로컬 상태를 읽어야 합니다.
|
|
198
|
+
- SQLite는 서비스 로컬 전용이며 분산 조정 계층이 아닙니다.
|
|
199
|
+
- 스키마 변경, 수동 편집, 충돌 업데이트에는 여전히 애플리케이션의 운영 정책이
|
|
200
|
+
필요합니다.
|
|
154
201
|
|
|
155
|
-
##
|
|
202
|
+
## 프로젝트 상태
|
|
156
203
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
- 스키마 변경, 수동 편집, 충돌하는 변경에 대한 운영 정책은 애플리케이션이
|
|
161
|
-
별도로 정해야 합니다.
|
|
204
|
+
Hikoutei는 활발히 개발 중입니다. 엔티티 API는 사용 가능하지만, 시트 편집
|
|
205
|
+
수집과 충돌 표시는 아직 발전 중입니다. 마이너 버전 업그레이드 전에 릴리스
|
|
206
|
+
노트를 확인하세요.
|
|
162
207
|
|
|
163
208
|
## 로드맵
|
|
164
209
|
|
|
165
|
-
- Google Sheets에서 의도적인 사용자
|
|
166
|
-
-
|
|
167
|
-
- 레지스트리 및 직접 provider 배포를 위한 설정 도구
|
|
168
|
-
- 공개 패키지 릴리스 안정화.
|
|
210
|
+
- Google Sheets에서 의도적인 사용자 편집 수집 완성
|
|
211
|
+
- 업데이트·삭제 충돌 처리와 표시 개선
|
|
212
|
+
- 레지스트리 및 직접 provider 배포를 위한 설정 도구 추가
|
|
169
213
|
|
|
170
|
-
현재 작업은 [
|
|
171
|
-
|
|
214
|
+
현재 작업은 [오픈 이슈](https://github.com/ManddarinShop/Hikoutei/issues)를
|
|
215
|
+
참고하세요.
|
|
172
216
|
|
|
173
217
|
## 라이선스
|
|
174
218
|
|
|
175
|
-
Hikoutei는 [MIT
|
|
219
|
+
Hikoutei는 [MIT 라이선스](LICENSE)로 배포됩니다.
|