@gravito/radiance 1.0.3 → 1.0.5
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 +30 -7
- package/README.zh-TW.md +238 -3
- package/dist/core/src/Application.d.ts +256 -0
- package/dist/core/src/CommandKernel.d.ts +33 -0
- package/dist/core/src/ConfigManager.d.ts +65 -0
- package/dist/core/src/Container/RequestScopeManager.d.ts +62 -0
- package/dist/core/src/Container/RequestScopeMetrics.d.ts +144 -0
- package/dist/core/src/Container.d.ts +153 -0
- package/dist/core/src/ErrorHandler.d.ts +66 -0
- package/dist/core/src/Event.d.ts +5 -0
- package/dist/core/src/EventManager.d.ts +123 -0
- package/dist/core/src/GlobalErrorHandlers.d.ts +47 -0
- package/dist/core/src/GravitoServer.d.ts +28 -0
- package/dist/core/src/HookManager.d.ts +435 -0
- package/dist/core/src/Listener.d.ts +4 -0
- package/dist/core/src/Logger.d.ts +20 -0
- package/dist/core/src/PlanetCore.d.ts +402 -0
- package/dist/core/src/RequestContext.d.ts +97 -0
- package/dist/core/src/Route.d.ts +36 -0
- package/dist/core/src/Router.d.ts +270 -0
- package/dist/core/src/ServiceProvider.d.ts +178 -0
- package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +27 -0
- package/dist/core/src/adapters/bun/BunContext.d.ts +54 -0
- package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +66 -0
- package/dist/core/src/adapters/bun/BunRequest.d.ts +31 -0
- package/dist/core/src/adapters/bun/BunWebSocketHandler.d.ts +48 -0
- package/dist/core/src/adapters/bun/RadixNode.d.ts +19 -0
- package/dist/core/src/adapters/bun/RadixRouter.d.ts +32 -0
- package/dist/core/src/adapters/bun/index.d.ts +7 -0
- package/dist/core/src/adapters/bun/types.d.ts +20 -0
- package/dist/core/src/adapters/types.d.ts +235 -0
- package/dist/core/src/binary/BinaryUtils.d.ts +105 -0
- package/dist/core/src/binary/index.d.ts +5 -0
- package/dist/core/src/cli/queue-commands.d.ts +6 -0
- package/dist/core/src/compat/async-local-storage.d.ts +7 -0
- package/dist/core/src/compat/crypto.d.ts +6 -0
- package/dist/core/src/engine/AOTRouter.d.ts +139 -0
- package/dist/core/src/engine/FastContext.d.ts +141 -0
- package/dist/core/src/engine/Gravito.d.ts +131 -0
- package/dist/core/src/engine/MinimalContext.d.ts +102 -0
- package/dist/core/src/engine/analyzer.d.ts +113 -0
- package/dist/core/src/engine/constants.d.ts +23 -0
- package/dist/core/src/engine/index.d.ts +26 -0
- package/dist/core/src/engine/path.d.ts +26 -0
- package/dist/core/src/engine/pool.d.ts +83 -0
- package/dist/core/src/engine/types.d.ts +149 -0
- package/dist/core/src/error-handling/RequestScopeErrorContext.d.ts +126 -0
- package/dist/core/src/events/BackpressureManager.d.ts +215 -0
- package/dist/core/src/events/CircuitBreaker.d.ts +229 -0
- package/dist/core/src/events/DeadLetterQueue.d.ts +219 -0
- package/dist/core/src/events/EventBackend.d.ts +12 -0
- package/dist/core/src/events/EventOptions.d.ts +204 -0
- package/dist/core/src/events/EventPriorityQueue.d.ts +63 -0
- package/dist/core/src/events/FlowControlStrategy.d.ts +109 -0
- package/dist/core/src/events/IdempotencyCache.d.ts +60 -0
- package/dist/core/src/events/MessageQueueBridge.d.ts +184 -0
- package/dist/core/src/events/PriorityEscalationManager.d.ts +82 -0
- package/dist/core/src/events/RetryScheduler.d.ts +104 -0
- package/dist/core/src/events/WorkerPool.d.ts +98 -0
- package/dist/core/src/events/WorkerPoolConfig.d.ts +153 -0
- package/dist/core/src/events/WorkerPoolMetrics.d.ts +65 -0
- package/dist/core/src/events/aggregation/AggregationWindow.d.ts +77 -0
- package/dist/core/src/events/aggregation/DeduplicationManager.d.ts +135 -0
- package/dist/core/src/events/aggregation/EventAggregationManager.d.ts +108 -0
- package/dist/core/src/events/aggregation/EventBatcher.d.ts +99 -0
- package/dist/core/src/events/aggregation/types.d.ts +117 -0
- package/dist/core/src/events/index.d.ts +26 -0
- package/dist/core/src/events/observability/EventMetrics.d.ts +132 -0
- package/dist/core/src/events/observability/EventTracer.d.ts +68 -0
- package/dist/core/src/events/observability/EventTracing.d.ts +161 -0
- package/dist/core/src/events/observability/OTelEventMetrics.d.ts +332 -0
- package/dist/core/src/events/observability/ObservableHookManager.d.ts +108 -0
- package/dist/core/src/events/observability/StreamWorkerMetrics.d.ts +76 -0
- package/dist/core/src/events/observability/index.d.ts +24 -0
- package/dist/core/src/events/observability/metrics-types.d.ts +16 -0
- package/dist/core/src/events/queue-core.d.ts +77 -0
- package/dist/core/src/events/task-executor.d.ts +51 -0
- package/dist/core/src/events/types.d.ts +134 -0
- package/dist/core/src/exceptions/AuthenticationException.d.ts +8 -0
- package/dist/core/src/exceptions/AuthorizationException.d.ts +8 -0
- package/dist/core/src/exceptions/CircularDependencyException.d.ts +9 -0
- package/dist/core/src/exceptions/GravitoException.d.ts +23 -0
- package/dist/core/src/exceptions/HttpException.d.ts +9 -0
- package/dist/core/src/exceptions/ModelNotFoundException.d.ts +10 -0
- package/dist/core/src/exceptions/ValidationException.d.ts +22 -0
- package/dist/core/src/exceptions/index.d.ts +7 -0
- package/dist/core/src/ffi/NativeAccelerator.d.ts +62 -0
- package/dist/core/src/ffi/NativeHasher.d.ts +139 -0
- package/dist/core/src/ffi/cbor-fallback.d.ts +96 -0
- package/dist/core/src/ffi/hash-fallback.d.ts +33 -0
- package/dist/core/src/ffi/index.d.ts +10 -0
- package/dist/core/src/ffi/types.d.ts +135 -0
- package/dist/core/src/health/HealthProvider.d.ts +67 -0
- package/dist/core/src/helpers/Arr.d.ts +19 -0
- package/dist/core/src/helpers/Str.d.ts +38 -0
- package/dist/core/src/helpers/data.d.ts +25 -0
- package/dist/core/src/helpers/errors.d.ts +34 -0
- package/dist/core/src/helpers/response.d.ts +41 -0
- package/dist/core/src/helpers.d.ts +338 -0
- package/dist/core/src/hooks/ActionManager.d.ts +132 -0
- package/dist/core/src/hooks/AsyncDetector.d.ts +84 -0
- package/dist/core/src/hooks/FilterManager.d.ts +71 -0
- package/dist/core/src/hooks/MigrationWarner.d.ts +24 -0
- package/dist/core/src/hooks/dlq-operations.d.ts +60 -0
- package/dist/core/src/hooks/types.d.ts +107 -0
- package/dist/core/src/http/CookieJar.d.ts +51 -0
- package/dist/core/src/http/cookie.d.ts +29 -0
- package/dist/core/src/http/types.d.ts +395 -0
- package/dist/core/src/index.d.ts +565 -0
- package/dist/core/src/observability/QueueDashboard.d.ts +136 -0
- package/dist/core/src/observability/contracts.d.ts +137 -0
- package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +349 -0
- package/dist/core/src/reliability/RetryPolicy.d.ts +217 -0
- package/dist/core/src/reliability/index.d.ts +6 -0
- package/dist/core/src/router/ControllerDispatcher.d.ts +12 -0
- package/dist/core/src/router/RequestValidator.d.ts +20 -0
- package/dist/core/src/runtime/adapter-bun.d.ts +12 -0
- package/dist/core/src/runtime/adapter-deno.d.ts +12 -0
- package/dist/core/src/runtime/adapter-node.d.ts +12 -0
- package/dist/core/src/runtime/adapter-unknown.d.ts +13 -0
- package/dist/core/src/runtime/archive.d.ts +17 -0
- package/dist/core/src/runtime/compression.d.ts +21 -0
- package/dist/core/src/runtime/deep-equals.d.ts +56 -0
- package/dist/core/src/runtime/detection.d.ts +22 -0
- package/dist/core/src/runtime/escape.d.ts +34 -0
- package/dist/core/src/runtime/index.d.ts +44 -0
- package/dist/core/src/runtime/markdown.d.ts +44 -0
- package/dist/core/src/runtime/types.d.ts +436 -0
- package/dist/core/src/runtime-helpers.d.ts +67 -0
- package/dist/core/src/runtime.d.ts +11 -0
- package/dist/core/src/security/Encrypter.d.ts +33 -0
- package/dist/core/src/security/Hasher.d.ts +29 -0
- package/dist/core/src/testing/HttpTester.d.ts +40 -0
- package/dist/core/src/testing/TestResponse.d.ts +78 -0
- package/dist/core/src/testing/index.d.ts +2 -0
- package/dist/core/src/transpiler-utils.d.ts +170 -0
- package/dist/core/src/types/events.d.ts +94 -0
- package/dist/index.js +1 -274
- package/dist/index.js.map +3 -10
- package/dist/radiance/src/BroadcastManager.d.ts +124 -0
- package/dist/radiance/src/OrbitRadiance.d.ts +98 -0
- package/dist/radiance/src/channels/Channel.d.ts +86 -0
- package/dist/radiance/src/drivers/AblyDriver.d.ts +73 -0
- package/dist/radiance/src/drivers/BroadcastDriver.d.ts +50 -0
- package/dist/radiance/src/drivers/PusherDriver.d.ts +95 -0
- package/dist/radiance/src/drivers/RedisDriver.d.ts +83 -0
- package/dist/radiance/src/drivers/WebSocketDriver.d.ts +89 -0
- package/dist/radiance/src/index.d.ts +39 -0
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -4,14 +4,29 @@ Lightweight, high-performance broadcasting for Gravito with multiple drivers (Pu
|
|
|
4
4
|
|
|
5
5
|
**Status**: v0.1.0 - core features complete with multiple broadcast drivers.
|
|
6
6
|
|
|
7
|
-
## Features
|
|
7
|
+
## ✨ Features
|
|
8
8
|
|
|
9
|
-
- **
|
|
10
|
-
- **Multi-
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
|
|
9
|
+
- 🪐 **Galaxy-Ready Broadcasting**: Native integration with PlanetCore events for automatic real-time delivery.
|
|
10
|
+
- 🔌 **Multi-Driver Support**: Seamlessly switch between **Pusher**, **Ably**, **Redis**, and native **WebSockets**.
|
|
11
|
+
- 📡 **Cross-Satellite Sync**: Synchronize state across multiple isolated Satellite instances.
|
|
12
|
+
- 🛡️ **Channel Authorization**: Built-in support for Private and Presence channels with granular auth logic.
|
|
13
|
+
- 🚀 **Zero Runtime Overhead**: Pure type-safe wrappers designed for maximum performance on Bun.
|
|
14
|
+
|
|
15
|
+
## 🌌 Role in Galaxy Architecture
|
|
16
|
+
|
|
17
|
+
In the **Gravito Galaxy Architecture**, Radiance acts as the **Event Horizon Layer (State Synchronization)**.
|
|
18
|
+
|
|
19
|
+
- **Real-time Interface**: Connects the internal events of the Galaxy to external observers (Clients) via persistent connections.
|
|
20
|
+
- **Satellite Interconnect**: Allows Satellites to broadcast state changes that other Satellites' frontend components can react to instantly.
|
|
21
|
+
- **Presence Core**: Manages the "Who is Online" state across the entire ecosystem, enabling collaborative features.
|
|
22
|
+
|
|
23
|
+
```mermaid
|
|
24
|
+
graph LR
|
|
25
|
+
S[Satellite] -->|Dispatch| E[Event]
|
|
26
|
+
E -->|implement ShouldBroadcast| Radiance{Radiance Orbit}
|
|
27
|
+
Radiance --> Driver[Driver: WS/Pusher]
|
|
28
|
+
Driver --> Client([Connected Clients])
|
|
29
|
+
```
|
|
15
30
|
|
|
16
31
|
## Installation
|
|
17
32
|
|
|
@@ -216,6 +231,14 @@ OrbitRadiance.configure({
|
|
|
216
231
|
})
|
|
217
232
|
```
|
|
218
233
|
|
|
234
|
+
## 📚 Documentation
|
|
235
|
+
|
|
236
|
+
Detailed guides and references for the Galaxy Architecture:
|
|
237
|
+
|
|
238
|
+
- [🏗️ **Architecture Overview**](./README.md) — Multi-driver broadcasting.
|
|
239
|
+
- [📡 **Real-time Sync**](./doc/REAL_TIME_SYNC.md) — **NEW**: Syncing state across Satellites and Clients.
|
|
240
|
+
- [🛡️ **Channel Auth**](#channel-authorization) — Securing private and presence channels.
|
|
241
|
+
|
|
219
242
|
## API Reference
|
|
220
243
|
|
|
221
244
|
### BroadcastManager
|
package/README.zh-TW.md
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
# @gravito/radiance
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
輕量級、高效能的 Gravito 廣播系統,支援多種驅動(Pusher、Ably、Redis、WebSocket)。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**狀態**: v0.1.0 - 核心功能完整,支援多種廣播驅動。
|
|
6
|
+
|
|
7
|
+
## ✨ 功能特色
|
|
8
|
+
|
|
9
|
+
- **零運行時開銷**:純類型封裝,直接委派給驅動程式
|
|
10
|
+
- **多驅動支援**:Pusher、Ably、Redis、WebSocket
|
|
11
|
+
- **模組化設計**:僅需安裝您需要的驅動程式
|
|
12
|
+
- **事件整合**:事件可實現 `ShouldBroadcast` 介面自動廣播
|
|
13
|
+
- **通道授權**:完整支援私有(Private)與存在(Presence)通道
|
|
14
|
+
- **AI 友善**:強型別、清晰的 JSDoc 與可預測的 API
|
|
15
|
+
|
|
16
|
+
## 📦 安裝
|
|
6
17
|
|
|
7
18
|
```bash
|
|
8
19
|
bun add @gravito/radiance
|
|
9
20
|
```
|
|
10
21
|
|
|
11
|
-
## 快速開始
|
|
22
|
+
## 🚀 快速開始
|
|
23
|
+
|
|
24
|
+
### 1. 配置 OrbitRadiance
|
|
12
25
|
|
|
13
26
|
```typescript
|
|
14
27
|
import { PlanetCore } from '@gravito/core'
|
|
@@ -24,7 +37,229 @@ const core = await PlanetCore.boot({
|
|
|
24
37
|
secret: 'your-secret',
|
|
25
38
|
cluster: 'mt1',
|
|
26
39
|
},
|
|
40
|
+
// 錯誤處理選項 (v0.1.1+)
|
|
41
|
+
throwOnError: true,
|
|
42
|
+
|
|
43
|
+
// 通道授權回調
|
|
44
|
+
authorizeChannel: async (channel, socketId, userId) => {
|
|
45
|
+
// 在此實作您的授權邏輯
|
|
46
|
+
return true
|
|
47
|
+
},
|
|
27
48
|
}),
|
|
28
49
|
],
|
|
29
50
|
})
|
|
30
51
|
```
|
|
52
|
+
|
|
53
|
+
### 2. 建立可廣播事件
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { Event, ShouldBroadcast } from '@gravito/core'
|
|
57
|
+
import { PrivateChannel } from '@gravito/radiance'
|
|
58
|
+
|
|
59
|
+
class OrderShipped extends Event implements ShouldBroadcast {
|
|
60
|
+
constructor(public order: Order) {
|
|
61
|
+
super()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 定義廣播通道
|
|
65
|
+
broadcastOn(): PrivateChannel {
|
|
66
|
+
return new PrivateChannel(`user.${this.order.userId}`)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 定義廣播資料 (可選)
|
|
70
|
+
broadcastWith(): Record<string, unknown> {
|
|
71
|
+
return {
|
|
72
|
+
order_id: this.order.id,
|
|
73
|
+
status: 'shipped',
|
|
74
|
+
tracking_number: this.order.trackingNumber,
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 定義事件名稱 (可選)
|
|
79
|
+
broadcastAs(): string {
|
|
80
|
+
return 'OrderShipped'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 3. 發送事件 (自動廣播)
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
await core.events.dispatch(new OrderShipped(order))
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 4. 手動廣播
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const broadcast = c.get('broadcast') as BroadcastManager
|
|
95
|
+
|
|
96
|
+
await broadcast.broadcast(
|
|
97
|
+
event,
|
|
98
|
+
{ name: 'user.123', type: 'private' },
|
|
99
|
+
{ message: 'Hello' },
|
|
100
|
+
'CustomEvent'
|
|
101
|
+
)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 🔌 驅動程式配置
|
|
105
|
+
|
|
106
|
+
### Pusher
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
OrbitRadiance.configure({
|
|
110
|
+
driver: 'pusher',
|
|
111
|
+
config: {
|
|
112
|
+
appId: 'your-app-id',
|
|
113
|
+
key: 'your-key',
|
|
114
|
+
secret: 'your-secret',
|
|
115
|
+
cluster: 'mt1',
|
|
116
|
+
useTLS: true,
|
|
117
|
+
},
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Ably
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
OrbitRadiance.configure({
|
|
125
|
+
driver: 'ably',
|
|
126
|
+
config: {
|
|
127
|
+
apiKey: 'your-api-key',
|
|
128
|
+
},
|
|
129
|
+
})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Redis
|
|
133
|
+
|
|
134
|
+
適用於內部微服務通訊。
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { RedisDriver } from '@gravito/radiance'
|
|
138
|
+
|
|
139
|
+
// 若 Core Container 已有 'redis' 實例,會自動注入
|
|
140
|
+
OrbitRadiance.configure({
|
|
141
|
+
driver: 'redis',
|
|
142
|
+
config: {
|
|
143
|
+
keyPrefix: 'gravito:broadcast:',
|
|
144
|
+
},
|
|
145
|
+
})
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### WebSocket
|
|
149
|
+
|
|
150
|
+
適用於單節點開發或自定義 WebSocket 伺服器。
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
OrbitRadiance.configure({
|
|
154
|
+
driver: 'websocket',
|
|
155
|
+
config: {
|
|
156
|
+
// 提供獲取所有連線的方法
|
|
157
|
+
getConnections: () => {
|
|
158
|
+
return Array.from(websocketConnections.values())
|
|
159
|
+
},
|
|
160
|
+
// 可選:自訂 Logger
|
|
161
|
+
logger: core.logger,
|
|
162
|
+
},
|
|
163
|
+
})
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 📡 通道類型
|
|
167
|
+
|
|
168
|
+
### 公開通道 (Public)
|
|
169
|
+
|
|
170
|
+
任何人都可以訂閱。
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { PublicChannel } from '@gravito/radiance'
|
|
174
|
+
|
|
175
|
+
class PublicEvent extends Event implements ShouldBroadcast {
|
|
176
|
+
broadcastOn(): PublicChannel {
|
|
177
|
+
return new PublicChannel('public-channel')
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 私有通道 (Private)
|
|
183
|
+
|
|
184
|
+
需要授權才能訂閱。名稱以 `private-` 開頭。
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
import { PrivateChannel } from '@gravito/radiance'
|
|
188
|
+
|
|
189
|
+
class PrivateEvent extends Event implements ShouldBroadcast {
|
|
190
|
+
broadcastOn(): PrivateChannel {
|
|
191
|
+
return new PrivateChannel(`user.${this.userId}`)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 存在通道 (Presence)
|
|
197
|
+
|
|
198
|
+
需要授權,並包含使用者資訊。名稱以 `presence-` 開頭。
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { PresenceChannel } from '@gravito/radiance'
|
|
202
|
+
|
|
203
|
+
class PresenceEvent extends Event implements ShouldBroadcast {
|
|
204
|
+
broadcastOn(): PresenceChannel {
|
|
205
|
+
return new PresenceChannel('presence-room')
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## 🔐 通道授權
|
|
211
|
+
|
|
212
|
+
私有與存在通道需要授權回調。
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
OrbitRadiance.configure({
|
|
216
|
+
driver: 'pusher',
|
|
217
|
+
config: { /* ... */ },
|
|
218
|
+
authorizeChannel: async (channel, socketId, userId) => {
|
|
219
|
+
if (channel.startsWith('private-user.')) {
|
|
220
|
+
const channelUserId = channel.replace('private-user.', '')
|
|
221
|
+
// 驗證當前使用者 ID 是否匹配
|
|
222
|
+
return userId?.toString() === channelUserId
|
|
223
|
+
}
|
|
224
|
+
return false
|
|
225
|
+
},
|
|
226
|
+
})
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## 📚 API 參考
|
|
230
|
+
|
|
231
|
+
### BroadcastManager
|
|
232
|
+
|
|
233
|
+
#### 方法
|
|
234
|
+
|
|
235
|
+
- `broadcast(event, channel, data, eventName): Promise<void>` - 廣播事件
|
|
236
|
+
- `authorizeChannel(channel, socketId, userId): Promise<{ auth, channel_data? } | null>` - 授權通道存取
|
|
237
|
+
- `setDriver(driver: BroadcastDriver): void` - 設定廣播驅動
|
|
238
|
+
- `setAuthCallback(callback): void` - 設定授權回調
|
|
239
|
+
- `setThrowOnError(throwOnError: boolean): void` - 設定是否在錯誤時拋出異常
|
|
240
|
+
|
|
241
|
+
### ShouldBroadcast 介面
|
|
242
|
+
|
|
243
|
+
實作此介面的事件會被自動廣播:
|
|
244
|
+
|
|
245
|
+
- `broadcastOn(): string | Channel` - 廣播通道(必須)
|
|
246
|
+
- `broadcastWith?(): Record<string, unknown>` - 廣播資料(可選)
|
|
247
|
+
- `broadcastAs?(): string` - 事件名稱(可選)
|
|
248
|
+
|
|
249
|
+
## ❓ 疑難排解
|
|
250
|
+
|
|
251
|
+
### 廣播失敗但不拋出錯誤?
|
|
252
|
+
|
|
253
|
+
檢查 `throwOnError` 設定。預設為 `true`,若設為 `false` 則只會記錄錯誤日誌。
|
|
254
|
+
|
|
255
|
+
### WebSocket 驅動沒有送出訊息?
|
|
256
|
+
|
|
257
|
+
確認 `getConnections()` 回傳了正確的連線陣列,且連線狀態為 `OPEN`。WebSocket 驅動會自動忽略非開啟狀態的連線。
|
|
258
|
+
|
|
259
|
+
### Redis 驅動報錯 "Redis client not set"?
|
|
260
|
+
|
|
261
|
+
Redis 驅動需要一個 Redis 客戶端實例。請確保在 `OrbitRadiance.configure` 之前或通過依賴注入提供了 `redis` 實例。
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
MIT © Carl Lee
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Application - Enterprise Application Container
|
|
3
|
+
*
|
|
4
|
+
* A high-level application class that orchestrates the entire framework.
|
|
5
|
+
* Provides a centralized entry point for enterprise applications with
|
|
6
|
+
* auto-discovery of providers, config loading, and lifecycle management.
|
|
7
|
+
*
|
|
8
|
+
* Phase 4 優化:Provider 預掃描 + 平行載入
|
|
9
|
+
* - Phase 1:預掃描所有 Provider 文件(語法驗證)
|
|
10
|
+
* - Phase 2:篩選有效 Provider(跳過無效的)
|
|
11
|
+
* - Phase 3:平行 import 所有有效 Provider
|
|
12
|
+
* - Phase 4:註冊到容器
|
|
13
|
+
*
|
|
14
|
+
* @module @gravito/core
|
|
15
|
+
* @since 2.0.0
|
|
16
|
+
*/
|
|
17
|
+
import { ConfigManager } from './ConfigManager';
|
|
18
|
+
import { Container } from './Container';
|
|
19
|
+
import type { EventManager } from './EventManager';
|
|
20
|
+
import type { Logger } from './Logger';
|
|
21
|
+
import { PlanetCore } from './PlanetCore';
|
|
22
|
+
import type { ServiceProvider } from './ServiceProvider';
|
|
23
|
+
/**
|
|
24
|
+
* Application Config options for the Application class.
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export interface ApplicationConfig {
|
|
28
|
+
/**
|
|
29
|
+
* Base path of the application
|
|
30
|
+
*/
|
|
31
|
+
basePath: string;
|
|
32
|
+
/**
|
|
33
|
+
* Path to the config directory (relative to basePath)
|
|
34
|
+
* @default 'config'
|
|
35
|
+
*/
|
|
36
|
+
configPath?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Path to the providers directory (relative to basePath)
|
|
39
|
+
* @default 'src/Providers'
|
|
40
|
+
*/
|
|
41
|
+
providersPath?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Environment (development, production, testing)
|
|
44
|
+
*/
|
|
45
|
+
env?: 'development' | 'production' | 'testing';
|
|
46
|
+
/**
|
|
47
|
+
* Logger instance
|
|
48
|
+
*/
|
|
49
|
+
logger?: Logger;
|
|
50
|
+
/**
|
|
51
|
+
* Initial configuration values
|
|
52
|
+
*/
|
|
53
|
+
config?: Record<string, unknown>;
|
|
54
|
+
/**
|
|
55
|
+
* Service providers to register
|
|
56
|
+
*/
|
|
57
|
+
providers?: ServiceProvider[];
|
|
58
|
+
/**
|
|
59
|
+
* Whether to auto-discover providers from providersPath
|
|
60
|
+
* @default true
|
|
61
|
+
*/
|
|
62
|
+
autoDiscoverProviders?: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Application - Enterprise-grade application container.
|
|
66
|
+
*
|
|
67
|
+
* Provides a higher-level abstraction over PlanetCore for building
|
|
68
|
+
* enterprise applications with convention-over-configuration patterns.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* // Create application
|
|
73
|
+
* const app = new Application({
|
|
74
|
+
* basePath: import.meta.dir,
|
|
75
|
+
* env: process.env.NODE_ENV as 'development' | 'production',
|
|
76
|
+
* });
|
|
77
|
+
*
|
|
78
|
+
* // Boot the application
|
|
79
|
+
* await app.boot();
|
|
80
|
+
*
|
|
81
|
+
* // Access core
|
|
82
|
+
* export default app.core.liftoff();
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare class Application {
|
|
86
|
+
/**
|
|
87
|
+
* The underlying PlanetCore instance.
|
|
88
|
+
*/
|
|
89
|
+
readonly core: PlanetCore;
|
|
90
|
+
/**
|
|
91
|
+
* The IoC container.
|
|
92
|
+
*/
|
|
93
|
+
readonly container: Container;
|
|
94
|
+
/**
|
|
95
|
+
* The configuration manager.
|
|
96
|
+
*/
|
|
97
|
+
readonly config: ConfigManager;
|
|
98
|
+
/**
|
|
99
|
+
* The event manager.
|
|
100
|
+
*/
|
|
101
|
+
readonly events: EventManager;
|
|
102
|
+
/**
|
|
103
|
+
* The logger instance.
|
|
104
|
+
*/
|
|
105
|
+
readonly logger: Logger;
|
|
106
|
+
/**
|
|
107
|
+
* Application base path.
|
|
108
|
+
*/
|
|
109
|
+
readonly basePath: string;
|
|
110
|
+
/**
|
|
111
|
+
* Environment mode.
|
|
112
|
+
*/
|
|
113
|
+
readonly env: 'development' | 'production' | 'testing';
|
|
114
|
+
/**
|
|
115
|
+
* Configuration options.
|
|
116
|
+
*/
|
|
117
|
+
private readonly options;
|
|
118
|
+
/**
|
|
119
|
+
* Whether the application has been booted.
|
|
120
|
+
*/
|
|
121
|
+
private booted;
|
|
122
|
+
constructor(options: ApplicationConfig);
|
|
123
|
+
/**
|
|
124
|
+
* Boot the application and its dependencies.
|
|
125
|
+
*
|
|
126
|
+
* This method orchestrates the full application lifecycle:
|
|
127
|
+
* 1. Configuration: Loads all config files from the config directory.
|
|
128
|
+
* 2. Discovery: Auto-discovers ServiceProviders from the providers directory.
|
|
129
|
+
* 3. Registration: Registers all discovered and explicit providers.
|
|
130
|
+
* 4. Bootstrapping: Triggers the PlanetCore bootstrap sequence.
|
|
131
|
+
*
|
|
132
|
+
* @returns Promise that resolves to the application instance for chaining.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const app = new Application({ basePath: import.meta.dir });
|
|
137
|
+
* await app.boot();
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
boot(): Promise<this>;
|
|
141
|
+
/**
|
|
142
|
+
* Load configuration files from the config directory.
|
|
143
|
+
*
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
146
|
+
private loadConfiguration;
|
|
147
|
+
/**
|
|
148
|
+
* Discover and register providers from the providers directory.
|
|
149
|
+
*
|
|
150
|
+
* Phase 4 優化版本:採用 4-Phase 載入策略
|
|
151
|
+
* - Phase 1:預掃描所有候選 Provider 檔案(語法驗證)
|
|
152
|
+
* - Phase 2:篩選有效 Provider 檔案(跳過語法錯誤的)
|
|
153
|
+
* - Phase 3:平行 import 所有有效 Provider(從循序 → 並行)
|
|
154
|
+
* - Phase 4:逐一註冊到容器
|
|
155
|
+
*
|
|
156
|
+
* 效能改進:N 個 Provider 從 O(N * importTime) 降至 O(importTime + overhead)
|
|
157
|
+
*
|
|
158
|
+
* @internal
|
|
159
|
+
*/
|
|
160
|
+
private discoverProviders;
|
|
161
|
+
/**
|
|
162
|
+
* Phase 1+2:預掃描 Provider 目錄中的所有候選檔案。
|
|
163
|
+
*
|
|
164
|
+
* 使用輕量語法驗證(嘗試讀取 + 基本結構檢查)篩選有效的 Provider 檔案,
|
|
165
|
+
* 讓語法錯誤在 import 之前被發現,提供更清晰的錯誤訊息。
|
|
166
|
+
*
|
|
167
|
+
* 策略:
|
|
168
|
+
* 1. 使用 Bun.Transpiler 進行 import 掃描(在 Bun 環境下)
|
|
169
|
+
* 2. Fallback 至基本檔案讀取驗證(在 Node/Deno 環境下)
|
|
170
|
+
*
|
|
171
|
+
* @param providersPath - Provider 目錄絕對路徑
|
|
172
|
+
* @returns 掃描結果陣列(含有效/無效標記)
|
|
173
|
+
* @internal
|
|
174
|
+
*/
|
|
175
|
+
private prescribeProviders;
|
|
176
|
+
/**
|
|
177
|
+
* Phase 3:平行 import 所有有效的 Provider 檔案。
|
|
178
|
+
*
|
|
179
|
+
* 使用 Promise.all() 同時 import 所有通過預掃描的 Provider 檔案,
|
|
180
|
+
* 從循序載入(O(N))改善為平行載入(O(1) 理論上),
|
|
181
|
+
* 實際效能受 I/O、CPU 和 V8 模組解析限制。
|
|
182
|
+
*
|
|
183
|
+
* @param validProviders - 通過預掃描的 Provider 掃描結果
|
|
184
|
+
* @returns 模組載入結果陣列
|
|
185
|
+
* @internal
|
|
186
|
+
*/
|
|
187
|
+
private loadProvidersInParallel;
|
|
188
|
+
/**
|
|
189
|
+
* Resolve a service instance from the IoC container.
|
|
190
|
+
*
|
|
191
|
+
* This is a convenience wrapper around `container.make()`.
|
|
192
|
+
*
|
|
193
|
+
* @template T - The expected type of the service.
|
|
194
|
+
* @param key - The unique identifier or class name of the service.
|
|
195
|
+
* @returns The resolved service instance.
|
|
196
|
+
* @throws Error if the service is not bound in the container.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* const db = app.make<Database>('db');
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
make<T>(key: string): T;
|
|
204
|
+
/**
|
|
205
|
+
* Check if a service is bound.
|
|
206
|
+
*
|
|
207
|
+
* @param key - The service key
|
|
208
|
+
* @returns True if bound
|
|
209
|
+
*/
|
|
210
|
+
has(key: string): boolean;
|
|
211
|
+
/**
|
|
212
|
+
* Retrieve a configuration value using dot notation.
|
|
213
|
+
*
|
|
214
|
+
* @template T - The expected type of the configuration value.
|
|
215
|
+
* @param key - The configuration key (e.g., 'app.name', 'database.connections.mysql').
|
|
216
|
+
* @param defaultValue - Optional value to return if the key is not found.
|
|
217
|
+
* @returns The configuration value or the default value.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* const port = app.getConfig<number>('app.port', 3000);
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
getConfig<T>(key: string, defaultValue?: T): T;
|
|
225
|
+
/**
|
|
226
|
+
* Resolve an absolute path relative to the application base path.
|
|
227
|
+
*
|
|
228
|
+
* @param segments - Path segments to join with the base path.
|
|
229
|
+
* @returns The absolute path string.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* const storagePath = app.path('storage', 'logs');
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
path(...segments: string[]): string;
|
|
237
|
+
/**
|
|
238
|
+
* Get the config path.
|
|
239
|
+
*
|
|
240
|
+
* @param segments - Additional path segments
|
|
241
|
+
* @returns Absolute path to config directory
|
|
242
|
+
*/
|
|
243
|
+
configPath(...segments: string[]): string;
|
|
244
|
+
/**
|
|
245
|
+
* Check if running in production.
|
|
246
|
+
*/
|
|
247
|
+
isProduction(): boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Check if running in development.
|
|
250
|
+
*/
|
|
251
|
+
isDevelopment(): boolean;
|
|
252
|
+
/**
|
|
253
|
+
* Check if running in testing.
|
|
254
|
+
*/
|
|
255
|
+
isTesting(): boolean;
|
|
256
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Container } from './Container';
|
|
2
|
+
/**
|
|
3
|
+
* CommandHandler type for custom CLI commands.
|
|
4
|
+
*/
|
|
5
|
+
export type CommandHandler = (args: string[], container: Container) => Promise<void> | void;
|
|
6
|
+
/**
|
|
7
|
+
* CommandKernel - Structured CLI Command handling.
|
|
8
|
+
*
|
|
9
|
+
* Manages registration and execution of custom CLI commands that can
|
|
10
|
+
* reuse the application container and providers.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const kernel = new CommandKernel(container);
|
|
15
|
+
* kernel.register('greet', (args) => console.log('Hello', args[0]));
|
|
16
|
+
* await kernel.handle(['greet', 'Universe']);
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare class CommandKernel {
|
|
20
|
+
private container;
|
|
21
|
+
private commands;
|
|
22
|
+
constructor(container: Container);
|
|
23
|
+
/**
|
|
24
|
+
* Register a new command handler.
|
|
25
|
+
*/
|
|
26
|
+
register(name: string, handler: CommandHandler): void;
|
|
27
|
+
/**
|
|
28
|
+
* Handle an incoming CLI command.
|
|
29
|
+
*
|
|
30
|
+
* @param argv - Array of command line arguments (e.g. process.argv.slice(2))
|
|
31
|
+
*/
|
|
32
|
+
handle(argv: string[]): Promise<void>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration manager (ConfigManager)
|
|
3
|
+
*
|
|
4
|
+
* Unifies environment variables and application configuration access.
|
|
5
|
+
*/
|
|
6
|
+
import type { ZodSchema } from 'zod';
|
|
7
|
+
/**
|
|
8
|
+
* ConfigManager - Central configuration store.
|
|
9
|
+
* Supports loading from environment variables and initial objects.
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export declare class ConfigManager {
|
|
13
|
+
private config;
|
|
14
|
+
private schema;
|
|
15
|
+
constructor(initialConfig?: Record<string, unknown>);
|
|
16
|
+
/**
|
|
17
|
+
* Load all environment variables from the active runtime.
|
|
18
|
+
*/
|
|
19
|
+
private loadEnv;
|
|
20
|
+
/**
|
|
21
|
+
* Get a configuration value (generic return type supported).
|
|
22
|
+
* Supports dot notation for deep access (e.g. 'app.name').
|
|
23
|
+
*/
|
|
24
|
+
get<T = unknown>(key: string, defaultValue?: T): T;
|
|
25
|
+
/**
|
|
26
|
+
* Set a configuration value.
|
|
27
|
+
*/
|
|
28
|
+
set(key: string, value: unknown): void;
|
|
29
|
+
/**
|
|
30
|
+
* Check whether a key exists.
|
|
31
|
+
*/
|
|
32
|
+
has(key: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Define a Zod schema for configuration validation.
|
|
35
|
+
*
|
|
36
|
+
* @param schema - Zod schema for validation
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* config.defineSchema(z.object({
|
|
41
|
+
* DATABASE_URL: z.string().url(),
|
|
42
|
+
* PORT: z.number().default(3000),
|
|
43
|
+
* }))
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
defineSchema(schema: ZodSchema): void;
|
|
47
|
+
/**
|
|
48
|
+
* Validate configuration against the defined schema.
|
|
49
|
+
*
|
|
50
|
+
* Should be called during bootstrap to catch configuration errors early.
|
|
51
|
+
*
|
|
52
|
+
* @throws Error if validation fails with details about missing/invalid fields
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* try {
|
|
57
|
+
* config.validate()
|
|
58
|
+
* } catch (error) {
|
|
59
|
+
* console.error('Config validation failed:', error.message)
|
|
60
|
+
* process.exit(1)
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
validate(): void;
|
|
65
|
+
}
|