@gravito/dark-matter 1.0.0-beta.1 → 1.0.0

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.md CHANGED
@@ -42,6 +42,10 @@ await Mongo.disconnect()
42
42
  - 🔍 **Query Builder** - Type-safe query building
43
43
  - 📊 **Aggregation Pipeline** - Fluent aggregation API
44
44
  - 🔌 **Multi-connection** - Named connections support
45
+ - 🛡️ **Transactions** - ACID transactions with convenient API
46
+ - 📦 **GridFS** - Handle large file uploads/downloads
47
+ - ⚡ **Change Streams** - Real-time database event listening
48
+ - ✅ **Schema Validation** - JSON Schema enforcement
45
49
 
46
50
  ## API Reference
47
51
 
@@ -111,6 +115,12 @@ await Mongo.collection('users')
111
115
  await Mongo.collection('users')
112
116
  .where('status', 'deleted')
113
117
  .deleteMany()
118
+
119
+ // Bulk Write
120
+ await Mongo.collection('logs').bulkWrite([
121
+ { insertOne: { document: { event: 'login' } } },
122
+ { deleteOne: { filter: { status: 'old' } } }
123
+ ])
114
124
  ```
115
125
 
116
126
  ### Aggregation Pipeline
@@ -140,42 +150,90 @@ const ordersWithCustomers = await Mongo.collection('orders')
140
150
  })
141
151
  .unwind('$customer')
142
152
  .get()
153
+ ```
143
154
 
144
- // Project specific fields
145
- const projected = await Mongo.collection('users')
146
- .aggregate()
147
- .project({
148
- name: 1,
149
- email: 1,
150
- fullName: { $concat: ['$firstName', ' ', '$lastName'] }
151
- })
152
- .get()
155
+ ### Advanced Features
156
+
157
+ #### Transactions
158
+
159
+ ```typescript
160
+ await Mongo.connection().withTransaction(async (session) => {
161
+ // Deduct from sender
162
+ await session.collection('accounts')
163
+ .where('_id', senderId)
164
+ .update({ $inc: { balance: -100 } })
165
+
166
+ // Add to receiver
167
+ await session.collection('accounts')
168
+ .where('_id', receiverId)
169
+ .update({ $inc: { balance: 100 } })
170
+ })
171
+ ```
172
+
173
+ #### Change Streams
174
+
175
+ ```typescript
176
+ const stream = Mongo.collection('orders').watch(
177
+ [{ $match: { 'fullDocument.amount': { $gt: 1000 } } }]
178
+ )
179
+
180
+ for await (const event of stream) {
181
+ console.log('High value order:', event.fullDocument)
182
+ }
183
+ ```
184
+
185
+ #### GridFS (File Storage)
186
+
187
+ ```typescript
188
+ const grid = new MongoGridFS(Mongo.database())
189
+
190
+ // Upload
191
+ const fileId = await grid.upload(Buffer.from('Hello'), { filename: 'hello.txt' })
192
+
193
+ // Download
194
+ const content = await grid.download(fileId)
153
195
  ```
154
196
 
155
- ### Multiple Connections
197
+ #### Schema Validation
156
198
 
157
199
  ```typescript
200
+ await Mongo.database().createCollection('users', {
201
+ schema: {
202
+ validator: {
203
+ $jsonSchema: {
204
+ required: ['username'],
205
+ properties: { username: { bsonType: 'string' } }
206
+ }
207
+ },
208
+ validationAction: 'error'
209
+ }
210
+ })
211
+ ```
212
+
213
+ ### Connection Management
214
+
215
+ ```typescript
216
+ // Configure multiple connections
158
217
  Mongo.configure({
159
218
  default: 'main',
160
219
  connections: {
161
- main: { uri: 'mongodb://localhost:27017', database: 'app' },
162
- analytics: { uri: 'mongodb://analytics.example.com:27017', database: 'analytics' }
220
+ main: { uri: 'mongodb://localhost:27017/app' },
221
+ analytics: { uri: 'mongodb://stats-db:27017/stats' }
163
222
  }
164
223
  })
165
224
 
166
- // Use specific connection
167
- const data = await Mongo.connection('analytics')
168
- .collection('events')
169
- .where('type', 'pageview')
170
- .get()
225
+ // Check health
226
+ const health = await Mongo.connection().getHealthStatus()
227
+ console.log(health.latencyMs) // e.g. 15
171
228
  ```
172
229
 
173
230
  ## Roadmap
174
231
 
175
- - [ ] Schema validation
176
- - [ ] Transactions
177
- - [ ] Change streams
178
- - [ ] GridFS support
232
+ - [x] Connection retry & health check
233
+ - [x] Transactions
234
+ - [x] Schema validation
235
+ - [x] Change streams
236
+ - [x] GridFS support
179
237
 
180
238
  ## License
181
239
 
package/README.zh-TW.md CHANGED
@@ -13,6 +13,7 @@ bun add @gravito/dark-matter mongodb
13
13
  ```typescript
14
14
  import { Mongo } from '@gravito/dark-matter'
15
15
 
16
+ // 設定
16
17
  Mongo.configure({
17
18
  default: 'main',
18
19
  connections: {
@@ -20,13 +21,220 @@ Mongo.configure({
20
21
  }
21
22
  })
22
23
 
24
+ // 連線
23
25
  await Mongo.connect()
24
26
 
27
+ // 使用
25
28
  const users = await Mongo.collection('users')
26
29
  .where('status', 'active')
27
30
  .orderBy('createdAt', 'desc')
28
31
  .limit(10)
29
32
  .get()
30
33
 
34
+ // 斷線
31
35
  await Mongo.disconnect()
32
36
  ```
37
+
38
+ ## 功能特色
39
+
40
+ - 🚀 **Bun 原生** - 針對 Bun runtime 最佳化
41
+ - 🎯 **Laravel 風格 API** - 熟悉且直觀的 Fluent Interface
42
+ - 🔍 **Query Builder** - 類型安全的查詢建構器
43
+ - 📊 **Aggregation Pipeline** - 流暢的聚合管道 API
44
+ - 🔌 **多連線支援** - 支援多個具名資料庫連線
45
+ - 🛡️ **Transactions** - 支援 ACID 交易與簡便的 API
46
+ - 📦 **GridFS** - 支援大檔案上傳與下載
47
+ - ⚡ **Change Streams** - 即時監聽資料庫變更事件
48
+ - ✅ **Schema Validation** - JSON Schema 資料驗證支援
49
+
50
+ ## API 參考
51
+
52
+ ### 查詢建構器 (Query Builder)
53
+
54
+ ```typescript
55
+ // 基本查詢
56
+ const users = await Mongo.collection('users')
57
+ .where('status', 'active')
58
+ .where('age', '>', 18)
59
+ .whereIn('role', ['admin', 'editor'])
60
+ .get()
61
+
62
+ // 排序與分頁
63
+ const latest = await Mongo.collection('posts')
64
+ .orderBy('createdAt', 'desc')
65
+ .limit(10)
66
+ .skip(20)
67
+ .get()
68
+
69
+ // 選擇特定欄位
70
+ const names = await Mongo.collection('users')
71
+ .select('name', 'email')
72
+ .get()
73
+
74
+ // 根據 ID 查詢
75
+ const user = await Mongo.collection('users').find('507f1f77bcf86cd799439011')
76
+
77
+ // 計數與存在檢查
78
+ const count = await Mongo.collection('users').where('status', 'active').count()
79
+ const exists = await Mongo.collection('users').where('email', 'john@example.com').exists()
80
+ ```
81
+
82
+ ### CRUD 操作
83
+
84
+ ```typescript
85
+ // 新增
86
+ const result = await Mongo.collection('users').insert({
87
+ name: 'John',
88
+ email: 'john@example.com',
89
+ createdAt: new Date()
90
+ })
91
+ console.log(result.insertedId)
92
+
93
+ // 批次新增
94
+ const results = await Mongo.collection('users').insertMany([
95
+ { name: 'Alice' },
96
+ { name: 'Bob' }
97
+ ])
98
+
99
+ // 更新
100
+ await Mongo.collection('users')
101
+ .where('_id', userId)
102
+ .update({ status: 'inactive' })
103
+
104
+ // 批次更新
105
+ await Mongo.collection('users')
106
+ .where('status', 'pending')
107
+ .updateMany({ status: 'active' })
108
+
109
+ // 刪除
110
+ await Mongo.collection('users')
111
+ .where('_id', userId)
112
+ .delete()
113
+
114
+ // 批次刪除
115
+ await Mongo.collection('users')
116
+ .where('status', 'deleted')
117
+ .deleteMany()
118
+
119
+ // 批次寫入 (Bulk Write)
120
+ await Mongo.collection('logs').bulkWrite([
121
+ { insertOne: { document: { event: 'login' } } },
122
+ { deleteOne: { filter: { status: 'old' } } }
123
+ ])
124
+ ```
125
+
126
+ ### 聚合管道 (Aggregation Pipeline)
127
+
128
+ ```typescript
129
+ // 分組與統計
130
+ const stats = await Mongo.collection('orders')
131
+ .aggregate()
132
+ .match({ status: 'completed' })
133
+ .group({
134
+ _id: '$customerId',
135
+ totalOrders: { $sum: 1 },
136
+ totalAmount: { $sum: '$amount' }
137
+ })
138
+ .sort({ totalAmount: 'desc' })
139
+ .limit(10)
140
+ .get()
141
+
142
+ // 關聯查詢 (Lookup / JOIN)
143
+ const ordersWithCustomers = await Mongo.collection('orders')
144
+ .aggregate()
145
+ .lookup({
146
+ from: 'customers',
147
+ localField: 'customerId',
148
+ foreignField: '_id',
149
+ as: 'customer'
150
+ })
151
+ .unwind('$customer')
152
+ .get()
153
+ ```
154
+
155
+ ### 進階功能
156
+
157
+ #### 交易 (Transactions)
158
+
159
+ ```typescript
160
+ await Mongo.connection().withTransaction(async (session) => {
161
+ // 從發送者扣款
162
+ await session.collection('accounts')
163
+ .where('_id', senderId)
164
+ .update({ $inc: { balance: -100 } })
165
+
166
+ // 增加到接收者
167
+ await session.collection('accounts')
168
+ .where('_id', receiverId)
169
+ .update({ $inc: { balance: 100 } })
170
+ })
171
+ ```
172
+
173
+ #### Change Streams (即時變更流)
174
+
175
+ ```typescript
176
+ const stream = Mongo.collection('orders').watch(
177
+ [{ $match: { 'fullDocument.amount': { $gt: 1000 } } }]
178
+ )
179
+
180
+ for await (const event of stream) {
181
+ console.log('高額訂單:', event.fullDocument)
182
+ }
183
+ ```
184
+
185
+ #### GridFS (檔案儲存)
186
+
187
+ ```typescript
188
+ const grid = new MongoGridFS(Mongo.database())
189
+
190
+ // 上傳
191
+ const fileId = await grid.upload(Buffer.from('Hello'), { filename: 'hello.txt' })
192
+
193
+ // 下載
194
+ const content = await grid.download(fileId)
195
+ ```
196
+
197
+ #### Schema Validation (資料驗證)
198
+
199
+ ```typescript
200
+ await Mongo.database().createCollection('users', {
201
+ schema: {
202
+ validator: {
203
+ $jsonSchema: {
204
+ required: ['username'],
205
+ properties: { username: { bsonType: 'string' } }
206
+ }
207
+ },
208
+ validationAction: 'error'
209
+ }
210
+ })
211
+ ```
212
+
213
+ ### 連線管理
214
+
215
+ ```typescript
216
+ // 設定多重連線
217
+ Mongo.configure({
218
+ default: 'main',
219
+ connections: {
220
+ main: { uri: 'mongodb://localhost:27017/app' },
221
+ analytics: { uri: 'mongodb://stats-db:27017/stats' }
222
+ }
223
+ })
224
+
225
+ // 檢查連線健康狀態
226
+ const health = await Mongo.connection().getHealthStatus()
227
+ console.log(health.latencyMs) // 例如: 15
228
+ ```
229
+
230
+ ## 開發路線圖 (Roadmap)
231
+
232
+ - [x] 連線重試與健康檢查
233
+ - [x] 交易 (Transactions) 支援
234
+ - [x] Schema Validation
235
+ - [x] Change Streams
236
+ - [x] GridFS 支援
237
+
238
+ ## 授權
239
+
240
+ MIT