@gravito/launchpad 1.2.1 → 1.3.1

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/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _gravito_ripple from '@gravito/ripple';
2
2
  import { OrbitRipple } from '@gravito/ripple';
3
3
  import { GravitoOrbit, PlanetCore } from '@gravito/core';
4
- import { ValueObject, AggregateRoot } from '@gravito/enterprise';
4
+ import { ValueObject, AggregateRoot, DomainEvent } from '@gravito/enterprise';
5
5
 
6
6
  interface MissionProps {
7
7
  id: string;
@@ -9,6 +9,15 @@ interface MissionProps {
9
9
  branch: string;
10
10
  commitSha: string;
11
11
  }
12
+ /**
13
+ * Mission represents a deployment task for a specific code version.
14
+ *
15
+ * It is a Value Object containing information about the source repository,
16
+ * branch, and commit to be deployed.
17
+ *
18
+ * @public
19
+ * @since 3.0.0
20
+ */
12
21
  declare class Mission extends ValueObject<MissionProps> {
13
22
  get id(): string;
14
23
  get repoUrl(): string;
@@ -28,6 +37,16 @@ declare enum RocketStatus {
28
37
  DECOMMISSIONED = "DECOMMISSIONED"
29
38
  }
30
39
 
40
+ /**
41
+ * Rocket represents a managed application container within Launchpad.
42
+ *
43
+ * It acts as an Aggregate Root in the domain, maintaining its lifecycle state
44
+ * (IDLE, PREPARING, ORBITING, etc.) and emitting domain events when
45
+ * state transitions occur.
46
+ *
47
+ * @public
48
+ * @since 3.0.0
49
+ */
31
50
  declare class Rocket extends AggregateRoot<string> {
32
51
  private _status;
33
52
  private _currentMission;
@@ -62,6 +81,17 @@ declare class Rocket extends AggregateRoot<string> {
62
81
  * 火箭除役 (移除容器)
63
82
  */
64
83
  decommission(): void;
84
+ /**
85
+ * 替換底層容器(僅在 REFURBISHING 狀態時允許)
86
+ * 用於 destroy-recreate 策略
87
+ *
88
+ * @param newContainerId - 新容器 ID
89
+ * @throws {Error} 當火箭不在 REFURBISHING 狀態時
90
+ *
91
+ * @public
92
+ * @since 1.3.0
93
+ */
94
+ replaceContainer(newContainerId: string): void;
65
95
  toJSON(): {
66
96
  id: string;
67
97
  containerId: string;
@@ -129,6 +159,13 @@ interface IRouterAdapter {
129
159
  unregister(domain: string): void;
130
160
  start(port: number): void;
131
161
  }
162
+ /**
163
+ * 負責與 GitHub API 互動的轉接器
164
+ */
165
+ interface IGitHubAdapter {
166
+ verifySignature(payload: string, signature: string, secret: string): boolean;
167
+ postComment(repoOwner: string, repoName: string, prNumber: number, comment: string): Promise<void>;
168
+ }
132
169
  /**
133
170
  * 負責持久化火箭狀態的儲存庫介面
134
171
  */
@@ -139,7 +176,68 @@ interface IRocketRepository {
139
176
  findAll(): Promise<Rocket[]>;
140
177
  delete(id: string): Promise<void>;
141
178
  }
179
+ /**
180
+ * Pool 管理配置
181
+ *
182
+ * @public
183
+ * @since 1.3.0
184
+ */
185
+ interface PoolConfig {
186
+ /** 最大 Rocket 數量(硬限制) */
187
+ maxRockets: number;
188
+ /** 初始預熱數量 */
189
+ warmupCount: number;
190
+ /** 最大等待隊列長度 */
191
+ maxQueueSize: number;
192
+ /** 隊列超時時間(毫秒) */
193
+ queueTimeoutMs: number;
194
+ /** 資源不足時的策略:'queue' | 'reject' | 'dynamic' */
195
+ exhaustionStrategy: 'queue' | 'reject' | 'dynamic';
196
+ /** 動態建立的限制(僅當 exhaustionStrategy 為 'dynamic' 時) */
197
+ dynamicLimit?: number;
198
+ }
199
+ /**
200
+ * Pool 管理預設配置
201
+ *
202
+ * @public
203
+ * @since 1.3.0
204
+ */
205
+ declare const DEFAULT_POOL_CONFIG: PoolConfig;
206
+ /**
207
+ * 容器清理策略配置
208
+ *
209
+ * @public
210
+ * @since 1.3.0
211
+ */
212
+ interface RefurbishConfig {
213
+ /** 清理策略:'deep-clean' | 'destroy-recreate' */
214
+ strategy: 'deep-clean' | 'destroy-recreate';
215
+ /** 深度清理命令(僅 deep-clean 策略) */
216
+ cleanupCommands?: string[];
217
+ /** 清理超時(毫秒) */
218
+ cleanupTimeoutMs: number;
219
+ /** 清理失敗時的處理:'decommission' | 'retry' */
220
+ failureAction: 'decommission' | 'retry';
221
+ /** 最大重試次數(僅 retry 模式) */
222
+ maxRetries: number;
223
+ }
224
+ /**
225
+ * 容器清理預設配置
226
+ *
227
+ * @public
228
+ * @since 1.3.0
229
+ */
230
+ declare const DEFAULT_REFURBISH_CONFIG: RefurbishConfig;
142
231
 
232
+ /**
233
+ * PayloadInjector is responsible for deploying application code into Rocket containers.
234
+ *
235
+ * It clones the repository, copies files into the container, installs
236
+ * dependencies (using Bun), and starts the application.
237
+ *
238
+ * @public
239
+ * @since 3.0.0
240
+ */
143
241
  declare class PayloadInjector {
144
242
  private docker;
145
243
  private git;
@@ -147,35 +245,94 @@ declare class PayloadInjector {
147
245
  deploy(rocket: Rocket): Promise<void>;
148
246
  }
149
247
 
248
+ /**
249
+ * RefurbishUnit handles the cleaning and restoration of Rocket containers.
250
+ *
251
+ * After a mission is complete, this unit resets the container environment
252
+ * (clearing files, stopping processes) so the container can be returned
253
+ * to the idle pool for future reuse.
254
+ *
255
+ * @public
256
+ * @since 3.0.0
257
+ */
150
258
  declare class RefurbishUnit {
151
259
  private docker;
152
- constructor(docker: IDockerAdapter);
260
+ private readonly config;
261
+ constructor(docker: IDockerAdapter, config?: Partial<RefurbishConfig>);
153
262
  /**
154
263
  * 執行火箭翻新邏輯
155
264
  */
156
265
  refurbish(rocket: Rocket): Promise<void>;
157
266
  }
158
267
 
268
+ /**
269
+ * PoolManager handles the lifecycle and pooling of Rocket containers.
270
+ *
271
+ * It manages a pool of pre-warmed containers to ensure fast deployment of
272
+ * new missions. It also handles rocket assignment and recycling (refurbishment).
273
+ *
274
+ * @public
275
+ * @since 3.0.0
276
+ */
159
277
  declare class PoolManager {
160
278
  private dockerAdapter;
161
279
  private rocketRepository;
162
280
  private refurbishUnit?;
163
281
  private router?;
164
- constructor(dockerAdapter: IDockerAdapter, rocketRepository: IRocketRepository, refurbishUnit?: RefurbishUnit | undefined, router?: IRouterAdapter | undefined);
282
+ private readonly config;
283
+ private readonly missionQueue;
284
+ private dynamicRocketCount;
285
+ constructor(dockerAdapter: IDockerAdapter, rocketRepository: IRocketRepository, refurbishUnit?: RefurbishUnit | undefined, router?: IRouterAdapter | undefined, config?: Partial<PoolConfig>);
286
+ /**
287
+ * 取得當前 Pool 狀態
288
+ */
289
+ getPoolStatus(): Promise<{
290
+ total: number;
291
+ idle: number;
292
+ orbiting: number;
293
+ refurbishing: number;
294
+ decommissioned: number;
295
+ dynamicCount: number;
296
+ maxRockets: number;
297
+ queueLength: number;
298
+ }>;
165
299
  /**
166
300
  * 初始化發射場:預先準備指定數量的火箭
167
301
  */
168
- warmup(count: number): Promise<void>;
302
+ warmup(count?: number): Promise<void>;
169
303
  /**
170
304
  * 獲取一架可用的火箭並分配任務
305
+ *
306
+ * @throws {PoolExhaustedException} 當 Pool 耗盡且無法處理請求時
171
307
  */
172
308
  assignMission(mission: Mission): Promise<Rocket>;
173
309
  /**
174
310
  * 回收指定任務的火箭
175
311
  */
176
312
  recycle(missionId: string): Promise<void>;
313
+ /**
314
+ * 處理等待隊列中的任務
315
+ */
316
+ private processQueue;
317
+ /**
318
+ * 取得隊列統計資訊
319
+ */
320
+ getQueueStats(): {
321
+ length: number;
322
+ maxSize: number;
323
+ oldestWaitMs: number | null;
324
+ };
177
325
  }
178
326
 
327
+ /**
328
+ * MissionControl orchestrates the high-level process of launching missions.
329
+ *
330
+ * it coordinates between the `PoolManager`, `PayloadInjector`, and `DockerAdapter`
331
+ * to deploy code into containers, assign domains, and monitor execution.
332
+ *
333
+ * @public
334
+ * @since 3.0.0
335
+ */
179
336
  declare class MissionControl {
180
337
  private poolManager;
181
338
  private injector;
@@ -185,16 +342,176 @@ declare class MissionControl {
185
342
  launch(mission: Mission, onTelemetry: (type: string, data: any) => void): Promise<string>;
186
343
  }
187
344
 
345
+ interface QueuedMission {
346
+ mission: Mission;
347
+ resolve: (rocket: Rocket) => void;
348
+ reject: (error: Error) => void;
349
+ enqueuedAt: number;
350
+ timeoutId: ReturnType<typeof setTimeout>;
351
+ }
188
352
  /**
189
- * Gravito Launchpad Orbit
353
+ * MissionQueue manages pending mission requests when pool is exhausted.
354
+ *
355
+ * Implements FIFO queue with timeout handling and backpressure support.
356
+ *
357
+ * @public
358
+ * @since 1.3.0
359
+ */
360
+ declare class MissionQueue {
361
+ private queue;
362
+ private readonly maxSize;
363
+ private readonly timeoutMs;
364
+ constructor(maxSize?: number, timeoutMs?: number);
365
+ get length(): number;
366
+ get isFull(): boolean;
367
+ /**
368
+ * 將任務加入隊列,返回 Promise 等待分配
369
+ */
370
+ enqueue(mission: Mission): Promise<Rocket>;
371
+ /**
372
+ * 取出下一個等待的任務
373
+ */
374
+ dequeue(): QueuedMission | null;
375
+ /**
376
+ * 從隊列中移除指定任務
377
+ */
378
+ private removeFromQueue;
379
+ /**
380
+ * 清空隊列並拒絕所有等待的任務
381
+ */
382
+ clear(reason: string): void;
383
+ /**
384
+ * 取得隊列統計資訊
385
+ */
386
+ getStats(): {
387
+ length: number;
388
+ maxSize: number;
389
+ oldestWaitMs: number | null;
390
+ };
391
+ }
392
+ /**
393
+ * Pool 資源耗盡異常
394
+ *
395
+ * @public
396
+ * @since 1.3.0
397
+ */
398
+ declare class PoolExhaustedException extends Error {
399
+ constructor(message: string);
400
+ }
401
+ /**
402
+ * 隊列等待超時異常
403
+ *
404
+ * @public
405
+ * @since 1.3.0
406
+ */
407
+ declare class QueueTimeoutException extends Error {
408
+ constructor(message: string);
409
+ }
410
+
411
+ /**
412
+ * Event emitted when a mission is assigned to a rocket.
413
+ *
414
+ * @public
415
+ * @since 3.0.0
416
+ */
417
+ declare class MissionAssigned extends DomainEvent {
418
+ readonly rocketId: string;
419
+ readonly missionId: string;
420
+ constructor(rocketId: string, missionId: string);
421
+ }
422
+ /**
423
+ * Event emitted when a rocket starts its mission (application started).
424
+ *
425
+ * @public
426
+ * @since 3.0.0
427
+ */
428
+ declare class RocketIgnited extends DomainEvent {
429
+ readonly rocketId: string;
430
+ constructor(rocketId: string);
431
+ }
432
+ /**
433
+ * Event emitted when a rocket mission is completed or terminated.
434
+ *
435
+ * @public
436
+ * @since 3.0.0
437
+ */
438
+ declare class RocketSplashedDown extends DomainEvent {
439
+ readonly rocketId: string;
440
+ constructor(rocketId: string);
441
+ }
442
+ /**
443
+ * Event emitted when a rocket has finished the refurbishment process.
444
+ *
445
+ * @public
446
+ * @since 3.0.0
447
+ */
448
+ declare class RefurbishmentCompleted extends DomainEvent {
449
+ readonly rocketId: string;
450
+ constructor(rocketId: string);
451
+ }
452
+ /**
453
+ * Event emitted when the rocket pool is exhausted.
454
+ *
455
+ * @public
456
+ * @since 1.3.0
457
+ */
458
+ declare class PoolExhausted extends DomainEvent {
459
+ readonly totalRockets: number;
460
+ readonly maxRockets: number;
461
+ readonly queueLength: number;
462
+ constructor(totalRockets: number, maxRockets: number, queueLength: number);
463
+ }
464
+ /**
465
+ * Event emitted when a mission is queued due to pool exhaustion.
466
+ *
467
+ * @public
468
+ * @since 1.3.0
469
+ */
470
+ declare class MissionQueued extends DomainEvent {
471
+ readonly missionId: string;
472
+ readonly queuePosition: number;
473
+ constructor(missionId: string, queuePosition: number);
474
+ }
475
+ /**
476
+ * Event emitted when a queued mission times out.
477
+ *
478
+ * @public
479
+ * @since 1.3.0
480
+ */
481
+ declare class MissionQueueTimeout extends DomainEvent {
482
+ readonly missionId: string;
483
+ readonly waitTimeMs: number;
484
+ constructor(missionId: string, waitTimeMs: number);
485
+ }
486
+
487
+ /**
488
+ * LaunchpadOrbit provides automated deployment and preview capabilities for Gravito.
489
+ * It integrates with Docker and GitHub to provide "Preview Deployments" for Pull Requests.
490
+ *
491
+ * @public
190
492
  */
191
493
  declare class LaunchpadOrbit implements GravitoOrbit {
192
494
  private ripple;
495
+ /**
496
+ * Create a new LaunchpadOrbit instance.
497
+ * @param ripple - Ripple instance for real-time telemetry communication.
498
+ */
193
499
  constructor(ripple: OrbitRipple);
500
+ /**
501
+ * Install the Launchpad orbit into PlanetCore.
502
+ * Registers the service provider and sets up webhook routes for deployment.
503
+ *
504
+ * @param core - The PlanetCore instance.
505
+ */
194
506
  install(core: PlanetCore): Promise<void>;
195
507
  }
196
508
  /**
197
- * 一鍵啟動 Launchpad 應用程式
509
+ * Bootstrap the Launchpad application.
510
+ * Initializes PlanetCore with necessary orbits (Cache, Ripple, Launchpad)
511
+ * and returns the configuration for the server entry point.
512
+ *
513
+ * @returns Server configuration object including port and fetch handler.
514
+ * @public
198
515
  */
199
516
  declare function bootstrapLaunchpad(): Promise<{
200
517
  port: number;
@@ -202,4 +519,4 @@ declare function bootstrapLaunchpad(): Promise<{
202
519
  fetch: (req: Request, server: any) => Response | Promise<Response> | undefined;
203
520
  }>;
204
521
 
205
- export { LaunchpadOrbit, Mission, MissionControl, PayloadInjector, PoolManager, RefurbishUnit, Rocket, RocketStatus, bootstrapLaunchpad };
522
+ export { DEFAULT_POOL_CONFIG, DEFAULT_REFURBISH_CONFIG, type IDockerAdapter, type IGitAdapter, type IGitHubAdapter, type IRocketRepository, type IRouterAdapter, LaunchpadOrbit, Mission, MissionAssigned, MissionControl, MissionQueue, MissionQueueTimeout, MissionQueued, PayloadInjector, type PoolConfig, PoolExhausted, PoolExhaustedException, PoolManager, QueueTimeoutException, type RefurbishConfig, RefurbishUnit, RefurbishmentCompleted, Rocket, RocketIgnited, RocketSplashedDown, RocketStatus, bootstrapLaunchpad };