@gravito/constellation 2.0.0 → 3.0.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.cts CHANGED
@@ -1,144 +1,507 @@
1
1
  import { Job } from '@gravito/stream';
2
- import { PlanetCore } from '@gravito/core';
2
+ import { GravitoOrbit, PlanetCore } from '@gravito/core';
3
3
 
4
+ /**
5
+ * Supported change frequency values for sitemap entries.
6
+ *
7
+ * @public
8
+ * @since 3.0.0
9
+ */
4
10
  type ChangeFreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
11
+ /**
12
+ * Represents an alternate language or regional version of a URL.
13
+ *
14
+ * @public
15
+ * @since 3.0.0
16
+ */
5
17
  interface AlternateUrl {
18
+ /** The language code (e.g., 'en', 'zh-TW') or 'x-default'. */
6
19
  lang: string;
20
+ /** The full URL of the alternate version. */
7
21
  url: string;
8
22
  }
23
+ /**
24
+ * Image metadata for a sitemap entry.
25
+ *
26
+ * @public
27
+ * @since 3.0.0
28
+ */
9
29
  interface SitemapImage {
30
+ /** The full URL of the image. */
10
31
  loc: string;
32
+ /** The title of the image. */
11
33
  title?: string | undefined;
34
+ /** A caption for the image. */
12
35
  caption?: string | undefined;
36
+ /** The geographic location of the image. */
13
37
  geo_location?: string | undefined;
38
+ /** A URL to the license for the image. */
14
39
  license?: string | undefined;
15
40
  }
41
+ /**
42
+ * Video metadata for a sitemap entry.
43
+ *
44
+ * @public
45
+ * @since 3.0.0
46
+ */
16
47
  interface SitemapVideo {
48
+ /** The URL of the video thumbnail. */
17
49
  thumbnail_loc: string;
50
+ /** The title of the video. */
18
51
  title: string;
52
+ /** A description of the video. */
19
53
  description: string;
54
+ /** The URL of the actual video file. */
20
55
  content_loc?: string | undefined;
56
+ /** The URL of the video player. */
21
57
  player_loc?: string | undefined;
58
+ /** Duration of the video in seconds. */
22
59
  duration?: number | undefined;
60
+ /** When the video will no longer be available. */
23
61
  expiration_date?: Date | string | undefined;
62
+ /** Rating of the video (0.0 to 5.0). */
24
63
  rating?: number | undefined;
64
+ /** Number of times the video has been viewed. */
25
65
  view_count?: number | undefined;
66
+ /** When the video was first published. */
26
67
  publication_date?: Date | string | undefined;
68
+ /** Whether the video is suitable for children. */
27
69
  family_friendly?: 'yes' | 'no' | undefined;
70
+ /** Tags associated with the video. */
28
71
  tag?: string[] | undefined;
72
+ /** The category of the video. */
29
73
  category?: string | undefined;
74
+ /** Regional restrictions for the video. */
30
75
  restriction?: {
31
76
  relationship: 'allow' | 'deny';
32
77
  countries: string[];
33
78
  } | undefined;
34
79
  }
80
+ /**
81
+ * News metadata for a sitemap entry.
82
+ *
83
+ * @public
84
+ * @since 3.0.0
85
+ */
35
86
  interface SitemapNews {
87
+ /** The publication that the news article belongs to. */
36
88
  publication: {
89
+ /** Name of the news publication. */
37
90
  name: string;
91
+ /** Language of the news publication (ISO 639 code). */
38
92
  language: string;
39
93
  };
94
+ /** The publication date of the news article. */
40
95
  publication_date: Date | string;
96
+ /** The title of the news article. */
41
97
  title: string;
98
+ /** Genres of the news article (e.g., 'PressRelease', 'Blog'). */
42
99
  genres?: string | undefined;
100
+ /** Keywords for the news article. */
43
101
  keywords?: string[] | undefined;
102
+ /** Stock tickers for the news article. */
44
103
  stock_tickers?: string[] | undefined;
45
104
  }
105
+ /**
106
+ * Represents a single URL entry in an XML sitemap.
107
+ *
108
+ * Supports standard sitemap properties as well as Google-specific extensions
109
+ * for images, videos, and news.
110
+ *
111
+ * @public
112
+ * @since 3.0.0
113
+ */
46
114
  interface SitemapEntry {
115
+ /** The full URL of the page including protocol and domain. */
47
116
  url: string;
117
+ /** The date of last modification of the page. */
48
118
  lastmod?: Date | string | undefined;
119
+ /** How frequently the page is likely to change. */
49
120
  changefreq?: ChangeFreq | undefined;
121
+ /** The priority of this URL relative to other URLs on your site (0.0 to 1.0). @default 0.5 */
50
122
  priority?: number | undefined;
123
+ /** Alternate language or regional versions of this URL (i18n). */
51
124
  alternates?: AlternateUrl[] | undefined;
125
+ /** Image information associated with this URL. */
52
126
  images?: SitemapImage[] | undefined;
127
+ /** Video information associated with this URL. */
53
128
  videos?: SitemapVideo[] | undefined;
129
+ /** News-specific information for this URL. */
54
130
  news?: SitemapNews | undefined;
131
+ /** Optional redirect metadata for SEO and tracking purposes. */
55
132
  redirect?: {
133
+ /** The source URL path that redirects to this entry. */
56
134
  from: string;
135
+ /** The destination URL path. */
57
136
  to: string;
137
+ /** The HTTP redirect status code. */
58
138
  type: 301 | 302;
139
+ /** The preferred canonical URL for this page. */
59
140
  canonical?: string;
60
141
  };
61
142
  }
143
+ /**
144
+ * Represents an entry in a sitemap index file.
145
+ *
146
+ * @public
147
+ * @since 3.0.0
148
+ */
62
149
  interface SitemapIndexEntry {
150
+ /** URL of the sub-sitemap file. */
63
151
  url: string;
152
+ /** Last modification time of the sub-sitemap. */
64
153
  lastmod?: Date | string | undefined;
65
154
  }
155
+ /**
156
+ * A provider responsible for yielding sitemap entries.
157
+ *
158
+ * Providers can be implemented to scan databases, file systems, or
159
+ * external APIs to discover content that should be included in the sitemap.
160
+ *
161
+ * @public
162
+ * @since 3.0.0
163
+ */
66
164
  interface SitemapProvider {
165
+ /**
166
+ * Generates a collection of sitemap entries.
167
+ *
168
+ * @returns An array, a promise of an array, or an async iterable of sitemap entries.
169
+ */
67
170
  getEntries(): Promise<SitemapEntry[]> | SitemapEntry[] | AsyncIterable<SitemapEntry>;
68
171
  }
172
+ /**
173
+ * Configuration for the sitemap XML generation stream.
174
+ *
175
+ * @public
176
+ * @since 3.0.0
177
+ */
69
178
  interface SitemapStreamOptions {
179
+ /** Base domain used to normalize relative URLs. */
70
180
  baseUrl: string;
181
+ /** Whether to output formatted and indented XML. @default false */
71
182
  pretty?: boolean | undefined;
72
183
  }
184
+ /**
185
+ * Persistence layer for storing generated sitemap files.
186
+ *
187
+ * Supports atomic deployments via "shadow" areas and provides hooks for
188
+ * version management and rollbacks.
189
+ *
190
+ * @public
191
+ * @since 3.0.0
192
+ */
73
193
  interface SitemapStorage {
194
+ /**
195
+ * Write sitemap content to the storage backend.
196
+ *
197
+ * @param filename - The destination filename.
198
+ * @param content - The raw XML content.
199
+ */
74
200
  write(filename: string, content: string): Promise<void>;
201
+ /**
202
+ * Read sitemap content from the storage backend.
203
+ *
204
+ * @param filename - The filename to read.
205
+ * @returns The XML content as a string, or null if not found.
206
+ */
75
207
  read(filename: string): Promise<string | null>;
208
+ /**
209
+ * Check if a sitemap file exists in storage.
210
+ *
211
+ * @param filename - The filename to check.
212
+ * @returns True if the file exists, false otherwise.
213
+ */
76
214
  exists(filename: string): Promise<boolean>;
215
+ /**
216
+ * Get the public URL for a given sitemap filename.
217
+ *
218
+ * @param filename - The sitemap filename.
219
+ * @returns The full public URL.
220
+ */
77
221
  getUrl(filename: string): string;
222
+ /**
223
+ * Write content to a non-public staging area for atomic deployment.
224
+ *
225
+ * @param filename - The target filename.
226
+ * @param content - The XML content.
227
+ * @param shadowId - Optional session identifier.
228
+ */
78
229
  writeShadow?(filename: string, content: string, shadowId?: string): Promise<void>;
230
+ /**
231
+ * Commit all staged files in a shadow session to production.
232
+ *
233
+ * @param shadowId - The identifier of the session to commit.
234
+ */
79
235
  commitShadow?(shadowId: string): Promise<void>;
236
+ /**
237
+ * List available archived versions of a specific sitemap.
238
+ *
239
+ * @param filename - The sitemap filename.
240
+ * @returns An array of version identifiers.
241
+ */
80
242
  listVersions?(filename: string): Promise<string[]>;
243
+ /**
244
+ * Revert a sitemap to a previously archived version.
245
+ *
246
+ * @param filename - The sitemap filename.
247
+ * @param version - The version identifier to switch to.
248
+ */
81
249
  switchVersion?(filename: string, version: string): Promise<void>;
82
250
  }
251
+ /**
252
+ * Cache interface for storing frequently accessed sitemap fragments.
253
+ *
254
+ * @public
255
+ * @since 3.0.0
256
+ */
83
257
  interface SitemapCache {
258
+ /**
259
+ * Retrieve a cached XML fragment.
260
+ *
261
+ * @param key - The cache key.
262
+ * @returns The cached XML string, or null if miss.
263
+ */
84
264
  get(key: string): Promise<string | null>;
265
+ /**
266
+ * Store an XML fragment in the cache.
267
+ *
268
+ * @param key - The cache key.
269
+ * @param value - The XML content to cache.
270
+ * @param ttl - Optional time-to-live in seconds.
271
+ */
85
272
  set(key: string, value: string, ttl?: number): Promise<void>;
273
+ /**
274
+ * Check if a specific fragment is currently cached.
275
+ *
276
+ * @param key - The cache key.
277
+ * @returns True if hit, false otherwise.
278
+ */
86
279
  has(key: string): Promise<boolean>;
87
280
  }
281
+ /**
282
+ * Distributed lock interface to prevent concurrent sitemap generation.
283
+ *
284
+ * @public
285
+ * @since 3.0.0
286
+ */
88
287
  interface SitemapLock {
288
+ /**
289
+ * Attempt to acquire a lock on a resource.
290
+ *
291
+ * @param resource - Identifier for the resource to lock.
292
+ * @param ttl - Lock expiration time in milliseconds.
293
+ * @returns True if the lock was acquired, false otherwise.
294
+ */
89
295
  acquire(resource: string, ttl: number): Promise<boolean>;
296
+ /**
297
+ * Release a previously held lock.
298
+ *
299
+ * @param resource - Identifier for the resource to unlock.
300
+ */
90
301
  release(resource: string): Promise<void>;
91
302
  }
303
+ /**
304
+ * Progress tracking data for large-scale sitemap generation jobs.
305
+ *
306
+ * @public
307
+ * @since 3.0.0
308
+ */
92
309
  interface SitemapProgress {
310
+ /** Unique identifier for the generation job. */
93
311
  jobId: string;
312
+ /** Current state of the generation process. */
94
313
  status: 'pending' | 'processing' | 'completed' | 'failed';
314
+ /** Total number of URLs to be processed. */
95
315
  total: number;
316
+ /** Number of URLs already processed. */
96
317
  processed: number;
318
+ /** Completion percentage (0 to 100). */
97
319
  percentage: number;
320
+ /** Timestamp when the job was started. */
98
321
  startTime?: Date;
322
+ /** Timestamp when the job was finished or failed. */
99
323
  endTime?: Date;
324
+ /** Error message if the status is 'failed'. */
100
325
  error?: string;
101
326
  }
327
+ /**
328
+ * Interface for persisting and retrieving sitemap job progress.
329
+ *
330
+ * @public
331
+ * @since 3.0.0
332
+ */
102
333
  interface SitemapProgressStorage {
334
+ /**
335
+ * Retrieve progress for a specific generation job.
336
+ *
337
+ * @param jobId - The job identifier.
338
+ */
103
339
  get(jobId: string): Promise<SitemapProgress | null>;
340
+ /**
341
+ * Initialize or overwrite a progress record.
342
+ *
343
+ * @param jobId - The job identifier.
344
+ * @param progress - The initial progress state.
345
+ */
104
346
  set(jobId: string, progress: SitemapProgress): Promise<void>;
347
+ /**
348
+ * Update specific fields of an existing progress record.
349
+ *
350
+ * @param jobId - The job identifier.
351
+ * @param updates - Object containing fields to update.
352
+ */
105
353
  update(jobId: string, updates: Partial<SitemapProgress>): Promise<void>;
354
+ /**
355
+ * Delete a progress record from storage.
356
+ *
357
+ * @param jobId - The job identifier.
358
+ */
106
359
  delete(jobId: string): Promise<void>;
360
+ /**
361
+ * List recent sitemap generation jobs.
362
+ *
363
+ * @param limit - Maximum number of records to return. @default 100
364
+ * @returns An array of progress records.
365
+ */
107
366
  list(limit?: number): Promise<SitemapProgress[]>;
108
367
  }
368
+ /**
369
+ * The nature of a structural change detected in the site.
370
+ *
371
+ * @public
372
+ * @since 3.0.0
373
+ */
109
374
  type ChangeType = 'add' | 'update' | 'remove';
375
+ /**
376
+ * Represents a single structural change detected in the site.
377
+ *
378
+ * @public
379
+ * @since 3.0.0
380
+ */
110
381
  interface SitemapChange {
382
+ /** The nature of the change (add, update, or remove). */
111
383
  type: ChangeType;
384
+ /** The target URL that was affected. */
112
385
  url: string;
386
+ /** The sitemap entry representation of the URL (for additions and updates). */
113
387
  entry?: SitemapEntry;
388
+ /** When the change was detected. */
114
389
  timestamp: Date;
115
390
  }
391
+ /**
392
+ * Interface for tracking and querying site structure changes over time.
393
+ *
394
+ * Change trackers are used by the `IncrementalGenerator` to perform
395
+ * partial sitemap updates.
396
+ *
397
+ * @public
398
+ * @since 3.0.0
399
+ */
116
400
  interface ChangeTracker {
401
+ /**
402
+ * Record a new site structure change.
403
+ *
404
+ * @param change - The change event to record.
405
+ */
117
406
  track(change: SitemapChange): Promise<void>;
407
+ /**
408
+ * Retrieve all changes recorded since a specific time.
409
+ *
410
+ * @param since - Optional start date for the query.
411
+ * @returns An array of change events.
412
+ */
118
413
  getChanges(since?: Date): Promise<SitemapChange[]>;
414
+ /**
415
+ * Retrieve the full change history for a specific URL.
416
+ *
417
+ * @param url - The URL to query history for.
418
+ * @returns An array of change events.
419
+ */
119
420
  getChangesByUrl(url: string): Promise<SitemapChange[]>;
421
+ /**
422
+ * Purge old change records from storage.
423
+ *
424
+ * @param since - If provided, only records older than this date will be cleared.
425
+ */
120
426
  clear(since?: Date): Promise<void>;
121
427
  }
428
+ /**
429
+ * Defines a 301 or 302 redirect rule managed by Constellation.
430
+ *
431
+ * @public
432
+ * @since 3.0.0
433
+ */
122
434
  interface RedirectRule {
435
+ /** The incoming URL path or glob pattern. */
123
436
  from: string;
437
+ /** The destination URL path or absolute URL. */
124
438
  to: string;
439
+ /** The HTTP status code (301 for permanent, 302 for temporary). */
125
440
  type: 301 | 302;
441
+ /** Timestamp when the redirect rule was created. */
126
442
  createdAt?: Date;
127
443
  }
444
+ /**
445
+ * Manager for registering and resolving redirect rules.
446
+ *
447
+ * @public
448
+ * @since 3.0.0
449
+ */
128
450
  interface RedirectManager {
451
+ /**
452
+ * Register a single redirect rule.
453
+ *
454
+ * @param redirect - The redirect rule to add.
455
+ */
129
456
  register(redirect: RedirectRule): Promise<void>;
457
+ /**
458
+ * Register multiple redirect rules at once.
459
+ *
460
+ * @param redirects - An array of redirect rules.
461
+ */
130
462
  registerBatch(redirects: RedirectRule[]): Promise<void>;
463
+ /**
464
+ * Retrieve a specific redirect rule by its source path.
465
+ *
466
+ * @param from - The source path.
467
+ * @returns The redirect rule, or null if not found.
468
+ */
131
469
  get(from: string): Promise<RedirectRule | null>;
470
+ /**
471
+ * Retrieve all registered redirect rules.
472
+ *
473
+ * @returns An array of all redirect rules.
474
+ */
132
475
  getAll(): Promise<RedirectRule[]>;
476
+ /**
477
+ * Resolve a URL through the redirect table.
478
+ *
479
+ * @param url - The URL to resolve.
480
+ * @param followChains - Whether to recursively resolve if redirects point to other redirects.
481
+ * @param maxChainLength - Maximum depth for chain resolution to prevent infinite loops.
482
+ * @returns The final destination URL, or null if no redirect matches.
483
+ */
133
484
  resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
134
485
  }
135
486
 
487
+ /**
488
+ * Options for configuring the `MemoryChangeTracker`.
489
+ *
490
+ * @public
491
+ * @since 3.0.0
492
+ */
136
493
  interface MemoryChangeTrackerOptions {
494
+ /** Maximum number of changes to keep in memory. @default 100000 */
137
495
  maxChanges?: number;
138
496
  }
139
497
  /**
140
- * 記憶體變更追蹤器實作
141
- * 適用於單一進程或開發環境
498
+ * MemoryChangeTracker is a simple, in-memory implementation of the `ChangeTracker`.
499
+ *
500
+ * It is suitable for single-process applications or development environments where
501
+ * persistence of change history across restarts is not required.
502
+ *
503
+ * @public
504
+ * @since 3.0.0
142
505
  */
143
506
  declare class MemoryChangeTracker implements ChangeTracker {
144
507
  private changes;
@@ -149,14 +512,29 @@ declare class MemoryChangeTracker implements ChangeTracker {
149
512
  getChangesByUrl(url: string): Promise<SitemapChange[]>;
150
513
  clear(since?: Date): Promise<void>;
151
514
  }
515
+ /**
516
+ * Options for configuring the `RedisChangeTracker`.
517
+ *
518
+ * @public
519
+ * @since 3.0.0
520
+ */
152
521
  interface RedisChangeTrackerOptions {
522
+ /** The Redis client instance. */
153
523
  client: any;
524
+ /** Prefix for Redis keys to avoid collisions. @default 'sitemap:changes:' */
154
525
  keyPrefix?: string;
526
+ /** Time-to-live for change records in seconds. @default 604800 (7 days) */
155
527
  ttl?: number;
156
528
  }
157
529
  /**
158
- * Redis 變更追蹤器實作
159
- * 適用於分散式環境或多進程
530
+ * RedisChangeTracker provides a distributed implementation of the `ChangeTracker`.
531
+ *
532
+ * It uses Redis to store change records, making it suitable for multi-process
533
+ * or distributed environments where multiple instances of Gravito need to
534
+ * share change history.
535
+ *
536
+ * @public
537
+ * @since 3.0.0
160
538
  */
161
539
  declare class RedisChangeTracker implements ChangeTracker {
162
540
  private client;
@@ -171,17 +549,39 @@ declare class RedisChangeTracker implements ChangeTracker {
171
549
  clear(since?: Date): Promise<void>;
172
550
  }
173
551
 
552
+ /**
553
+ * Result of a sitemap difference calculation.
554
+ *
555
+ * @public
556
+ * @since 3.0.0
557
+ */
174
558
  interface DiffResult {
559
+ /** Entries that are present in the new set but not in the old one. */
175
560
  added: SitemapEntry[];
561
+ /** Entries that are present in both sets but have different metadata. */
176
562
  updated: SitemapEntry[];
563
+ /** URLs that were present in the old set but are missing from the new one. */
177
564
  removed: string[];
178
565
  }
566
+ /**
567
+ * Options for configuring the `DiffCalculator`.
568
+ *
569
+ * @public
570
+ * @since 3.0.0
571
+ */
179
572
  interface DiffCalculatorOptions {
573
+ /** Batch size for processing large datasets. @default 10000 */
180
574
  batchSize?: number;
181
575
  }
182
576
  /**
183
- * 差異計算器
184
- * 比較兩個 sitemap 狀態,計算差異
577
+ * DiffCalculator compares two sets of sitemap entries to identify changes.
578
+ *
579
+ * It is used for incremental sitemap generation, allowing the system to
580
+ * update only the parts of the sitemap that have actually changed (added,
581
+ * updated, or removed).
582
+ *
583
+ * @public
584
+ * @since 3.0.0
185
585
  */
186
586
  declare class DiffCalculator {
187
587
  private batchSize;
@@ -204,19 +604,47 @@ declare class DiffCalculator {
204
604
  private hasChanged;
205
605
  }
206
606
 
607
+ /**
608
+ * Options for configuring the `ShadowProcessor`.
609
+ *
610
+ * @public
611
+ * @since 3.0.0
612
+ */
207
613
  interface ShadowProcessorOptions {
614
+ /** The storage backend used for writing files. */
208
615
  storage: SitemapStorage;
616
+ /**
617
+ * Deployment mode:
618
+ * - `atomic`: All files are swapped at once when committed.
619
+ * - `versioned`: Each file is committed individually, potentially creating a new version.
620
+ */
209
621
  mode: 'atomic' | 'versioned';
622
+ /** Whether shadow processing is enabled. */
210
623
  enabled: boolean;
211
624
  }
625
+ /**
626
+ * Represents a single file write operation within a shadow session.
627
+ *
628
+ * @public
629
+ * @since 3.0.0
630
+ */
212
631
  interface ShadowOperation {
632
+ /** The destination filename. */
213
633
  filename: string;
634
+ /** The file content to be written. */
214
635
  content: string;
636
+ /** Optional unique identifier for the shadow session. */
215
637
  shadowId?: string;
216
638
  }
217
639
  /**
218
- * 影子處理器
219
- * 管理影子生成流程,支援原子切換和版本化兩種模式
640
+ * ShadowProcessor manages the staging and atomic deployment of generated files.
641
+ *
642
+ * It allows files to be written to a "shadow" location before being "committed"
643
+ * (swapped) to their final destination, ensuring zero-downtime and atomic updates
644
+ * for sitemaps and indexes.
645
+ *
646
+ * @public
647
+ * @since 3.0.0
220
648
  */
221
649
  declare class ShadowProcessor {
222
650
  private options;
@@ -245,21 +673,55 @@ declare class ShadowProcessor {
245
673
  getOperations(): ShadowOperation[];
246
674
  }
247
675
 
676
+ /**
677
+ * Options for configuring the `SitemapGenerator`.
678
+ *
679
+ * @public
680
+ * @since 3.0.0
681
+ */
248
682
  interface SitemapGeneratorOptions extends SitemapStreamOptions {
683
+ /** The storage backend where the sitemap files will be written. */
249
684
  storage: SitemapStorage;
685
+ /** An array of providers that supply the entries to be included in the sitemap. */
250
686
  providers: SitemapProvider[];
687
+ /** Maximum number of entries per individual sitemap file. @default 50000 */
251
688
  maxEntriesPerFile?: number;
689
+ /** The name of the main sitemap or sitemap index file. @default 'sitemap.xml' */
252
690
  filename?: string;
691
+ /** Configuration for staging files before atomic deployment. */
253
692
  shadow?: {
693
+ /** Whether shadow processing is enabled. */
254
694
  enabled: boolean;
695
+ /** Deployment mode: 'atomic' or 'versioned'. */
255
696
  mode: 'atomic' | 'versioned';
256
697
  };
698
+ /** Optional callback to track generation progress. */
257
699
  onProgress?: (progress: {
258
700
  processed: number;
259
701
  total: number;
260
702
  percentage: number;
261
703
  }) => void;
262
704
  }
705
+ /**
706
+ * SitemapGenerator is the primary orchestrator for creating sitemaps in Gravito.
707
+ *
708
+ * It coordinates multiple `SitemapProvider`s, handles file sharding when
709
+ * URL limits are reached, and uses a `ShadowProcessor` for atomic deployments.
710
+ * It automatically generates a sitemap index if multiple files are produced.
711
+ *
712
+ * @example
713
+ * ```typescript
714
+ * const generator = new SitemapGenerator({
715
+ * baseUrl: 'https://example.com',
716
+ * storage: new DiskSitemapStorage('./public'),
717
+ * providers: [new RouteScanner()]
718
+ * });
719
+ * await generator.run();
720
+ * ```
721
+ *
722
+ * @public
723
+ * @since 3.0.0
724
+ */
263
725
  declare class SitemapGenerator {
264
726
  private options;
265
727
  private shadowProcessor;
@@ -271,14 +733,31 @@ declare class SitemapGenerator {
271
733
  getShadowProcessor(): ShadowProcessor | null;
272
734
  }
273
735
 
736
+ /**
737
+ * Options for configuring the `IncrementalGenerator`.
738
+ *
739
+ * Extends `SitemapGeneratorOptions` to include change tracking and difference
740
+ * calculation components.
741
+ *
742
+ * @public
743
+ * @since 3.0.0
744
+ */
274
745
  interface IncrementalGeneratorOptions extends SitemapGeneratorOptions {
746
+ /** The change tracker used to store and retrieve sitemap changes. */
275
747
  changeTracker: ChangeTracker;
748
+ /** Optional difference calculator. Defaults to a new `DiffCalculator` instance. */
276
749
  diffCalculator?: DiffCalculator;
750
+ /** Whether to automatically track changes during full generation. @default true */
277
751
  autoTrack?: boolean;
278
752
  }
279
753
  /**
280
- * 增量生成器
281
- * 只生成變更的 URL,不重新生成整個 sitemap
754
+ * IncrementalGenerator optimizes sitemap updates by processing only changed URLs.
755
+ *
756
+ * Instead of regenerating the entire sitemap from scratch, it uses a `ChangeTracker`
757
+ * to identify new, updated, or removed URLs and updates the sitemap incrementally.
758
+ *
759
+ * @public
760
+ * @since 3.0.0
282
761
  */
283
762
  declare class IncrementalGenerator {
284
763
  private options;
@@ -316,13 +795,26 @@ declare class IncrementalGenerator {
316
795
  private toArray;
317
796
  }
318
797
 
798
+ /**
799
+ * Options for configuring the `ProgressTracker`.
800
+ *
801
+ * @public
802
+ * @since 3.0.0
803
+ */
319
804
  interface ProgressTrackerOptions {
805
+ /** The storage backend used to persist progress information. */
320
806
  storage: SitemapProgressStorage;
807
+ /** Update interval in milliseconds. @default 1000 */
321
808
  updateInterval?: number;
322
809
  }
323
810
  /**
324
- * 進度追蹤器
325
- * 追蹤 sitemap 生成進度
811
+ * ProgressTracker monitors and persists the progress of sitemap generation jobs.
812
+ *
813
+ * It provides methods to initialize, update, and complete progress tracking,
814
+ * ensuring that long-running generation tasks can be monitored via the storage backend.
815
+ *
816
+ * @public
817
+ * @since 3.0.0
326
818
  */
327
819
  declare class ProgressTracker {
328
820
  private storage;
@@ -360,6 +852,23 @@ declare class ProgressTracker {
360
852
  getCurrentProgress(): SitemapProgress | null;
361
853
  }
362
854
 
855
+ /**
856
+ * SitemapIndex handles the generation of sitemap index files.
857
+ *
858
+ * A sitemap index is used when a site has multiple sitemap files, usually
859
+ * because the number of URLs exceeds the 50,000 limit per sitemap.
860
+ *
861
+ * @example
862
+ * ```typescript
863
+ * const index = new SitemapIndex({ baseUrl: 'https://example.com' });
864
+ * index.add('sitemap-posts.xml');
865
+ * index.add({ url: 'sitemap-pages.xml', lastmod: new Date() });
866
+ * const xml = index.toXML();
867
+ * ```
868
+ *
869
+ * @public
870
+ * @since 3.0.0
871
+ */
363
872
  declare class SitemapIndex {
364
873
  private options;
365
874
  private entries;
@@ -370,6 +879,26 @@ declare class SitemapIndex {
370
879
  private escape;
371
880
  }
372
881
 
882
+ /**
883
+ * SitemapStream handles the low-level generation of sitemap XML content.
884
+ *
885
+ * It supports standard sitemap tags as well as Google-specific extensions for
886
+ * images, videos, news, and internationalization (i18n) via `xhtml:link`.
887
+ *
888
+ * @example
889
+ * ```typescript
890
+ * const stream = new SitemapStream({ baseUrl: 'https://example.com' });
891
+ * stream.add({
892
+ * url: '/contact',
893
+ * changefreq: 'monthly',
894
+ * priority: 0.5
895
+ * });
896
+ * const xml = stream.toXML();
897
+ * ```
898
+ *
899
+ * @public
900
+ * @since 3.0.0
901
+ */
373
902
  declare class SitemapStream {
374
903
  private options;
375
904
  private entries;
@@ -400,22 +929,41 @@ type I18nSitemapEntryOptions = Omit<SitemapEntry, 'url' | 'alternates'>;
400
929
  */
401
930
  declare function generateI18nEntries(path: string, locales: string[], baseUrl?: string, options?: I18nSitemapEntryOptions): SitemapEntry[];
402
931
 
932
+ /**
933
+ * Options for configuring the `GenerateSitemapJob`.
934
+ *
935
+ * @public
936
+ * @since 3.0.0
937
+ */
403
938
  interface GenerateSitemapJobOptions {
939
+ /** Options for the underlying sitemap generator. */
404
940
  generatorOptions: SitemapGeneratorOptions;
941
+ /** Unique identifier for the generation job. */
405
942
  jobId: string;
943
+ /** Optional progress tracker to monitor execution state. */
406
944
  progressTracker?: ProgressTracker;
945
+ /** Optional shadow processor for atomic deployments. */
407
946
  shadowProcessor?: ShadowProcessor;
947
+ /** Optional callback triggered during progress updates. */
408
948
  onProgress?: (progress: {
409
949
  processed: number;
410
950
  total: number;
411
951
  percentage: number;
412
952
  }) => void;
953
+ /** Optional callback triggered when the job completes successfully. */
413
954
  onComplete?: () => void;
955
+ /** Optional callback triggered when the job encounters an error. */
414
956
  onError?: (error: Error) => void;
415
957
  }
416
958
  /**
417
- * Sitemap 生成背景任務
418
- * 整合背景任務處理和進度追蹤
959
+ * GenerateSitemapJob is a background task for processing large-scale sitemaps.
960
+ *
961
+ * It integrates with Gravito's `stream` module to provide asynchronous,
962
+ * observable sitemap generation with real-time progress tracking and
963
+ * atomic deployment support.
964
+ *
965
+ * @public
966
+ * @since 3.0.0
419
967
  */
420
968
  declare class GenerateSitemapJob extends Job {
421
969
  private options;
@@ -434,37 +982,110 @@ declare class GenerateSitemapJob extends Job {
434
982
  private generateWithProgress;
435
983
  }
436
984
 
985
+ /**
986
+ * Configuration for a dynamically generated sitemap that is built upon request.
987
+ *
988
+ * Useful for small to medium sites where fresh data is critical. Dynamic sitemaps
989
+ * are generated on-the-fly and can be cached at the HTTP level.
990
+ *
991
+ * @public
992
+ * @since 3.0.0
993
+ */
437
994
  interface DynamicSitemapOptions extends SitemapStreamOptions {
995
+ /** The URL path where the sitemap will be exposed. @default '/sitemap.xml' */
438
996
  path?: string | undefined;
997
+ /** List of sitemap entry providers to scan for content. */
439
998
  providers: SitemapProvider[];
999
+ /** Cache duration in seconds for the HTTP response. @default undefined (no-cache) */
440
1000
  cacheSeconds?: number | undefined;
1001
+ /** Persistence backend for cached XML files. Defaults to MemorySitemapStorage. */
441
1002
  storage?: SitemapStorage | undefined;
1003
+ /** Optional distributed lock to prevent "cache stampede" during heavy generation. */
442
1004
  lock?: SitemapLock | undefined;
443
1005
  }
1006
+ /**
1007
+ * Configuration for a statically pre-generated sitemap.
1008
+ *
1009
+ * Recommended for large sites or high-traffic applications. Static sitemaps
1010
+ * are built (usually as part of a build process) and served as static files.
1011
+ *
1012
+ * @public
1013
+ * @since 3.0.0
1014
+ */
444
1015
  interface StaticSitemapOptions extends SitemapStreamOptions {
1016
+ /** Local directory where generated XML files will be saved. */
445
1017
  outDir: string;
1018
+ /** The name of the root sitemap file. @default 'sitemap.xml' */
446
1019
  filename?: string | undefined;
1020
+ /** List of sitemap entry providers to scan for content. */
447
1021
  providers: SitemapProvider[];
1022
+ /** Custom storage backend. Defaults to DiskSitemapStorage using `outDir`. */
448
1023
  storage?: SitemapStorage | undefined;
1024
+ /** Optional incremental generation settings to only update changed URLs. */
449
1025
  incremental?: {
1026
+ /** Whether to enable incremental builds. */
450
1027
  enabled: boolean;
1028
+ /** Backend for tracking structural site changes. */
451
1029
  changeTracker: ChangeTracker;
1030
+ /** Whether to automatically record new changes during scan. @default false */
452
1031
  autoTrack?: boolean;
453
1032
  };
1033
+ /** Optional SEO redirect orchestration settings. */
454
1034
  redirect?: {
1035
+ /** Whether to automatically handle 301/302 redirects found in sitemap. */
455
1036
  enabled: boolean;
1037
+ /** Backend for managing and resolving redirect rules. */
456
1038
  manager: RedirectManager;
1039
+ /** Strategy for resolving conflicting or chained redirects. @default 'remove_old_add_new' */
457
1040
  strategy?: 'remove_old_add_new' | 'keep_relation' | 'update_url' | 'dual_mark';
1041
+ /** Whether to resolve redirect chains into a single jump. @default false */
458
1042
  followChains?: boolean;
1043
+ /** Maximum number of redirect jumps to follow. @default 5 */
459
1044
  maxChainLength?: number;
460
1045
  };
1046
+ /** Deployment settings for atomic sitemap updates via shadow staging. */
461
1047
  shadow?: {
1048
+ /** Whether to enable "shadow" (atomic staging) mode. */
462
1049
  enabled: boolean;
1050
+ /** The update strategy: 'atomic' (full swap) or 'versioned' (archived). @default 'atomic' */
463
1051
  mode: 'atomic' | 'versioned';
464
1052
  };
1053
+ /** Persistence backend for long-running job progress tracking. */
465
1054
  progressStorage?: SitemapProgressStorage;
466
1055
  }
467
- declare class OrbitSitemap {
1056
+ /**
1057
+ * OrbitSitemap is the enterprise SEO orchestration module for Gravito.
1058
+ *
1059
+ * It provides advanced sitemap generation supporting large-scale indexing,
1060
+ * automatic 301/302 redirect handling, and atomic sitemap deployments.
1061
+ *
1062
+ * It can operate in two modes:
1063
+ * 1. **Dynamic**: Sitemaps are generated on-the-fly and cached.
1064
+ * 2. **Static**: Sitemaps are pre-built (e.g., during CI/CD) and served from disk or cloud storage.
1065
+ *
1066
+ * @example Dynamic Mode
1067
+ * ```typescript
1068
+ * const sitemap = OrbitSitemap.dynamic({
1069
+ * baseUrl: 'https://example.com',
1070
+ * providers: [new PostSitemapProvider()]
1071
+ * });
1072
+ * core.addOrbit(sitemap);
1073
+ * ```
1074
+ *
1075
+ * @example Static Mode
1076
+ * ```typescript
1077
+ * const sitemap = OrbitSitemap.static({
1078
+ * baseUrl: 'https://example.com',
1079
+ * outDir: './public',
1080
+ * shadow: { enabled: true, mode: 'atomic' }
1081
+ * });
1082
+ * await sitemap.generate();
1083
+ * ```
1084
+ *
1085
+ * @public
1086
+ * @since 3.0.0
1087
+ */
1088
+ declare class OrbitSitemap implements GravitoOrbit {
468
1089
  private options;
469
1090
  private mode;
470
1091
  private constructor();
@@ -535,53 +1156,149 @@ declare class OrbitSitemap {
535
1156
  private toArray;
536
1157
  }
537
1158
 
1159
+ /**
1160
+ * Options for configuring the `RouteScanner`.
1161
+ *
1162
+ * @public
1163
+ * @since 3.0.0
1164
+ */
538
1165
  interface RouteScannerOptions {
1166
+ /** Glob patterns of routes to explicitly include. */
539
1167
  include?: string[] | undefined;
1168
+ /** Glob patterns of routes to exclude from the sitemap. */
540
1169
  exclude?: string[] | undefined;
1170
+ /** Default change frequency for scanned routes. @default 'weekly' */
541
1171
  defaultChangefreq?: ChangeFreq | undefined;
1172
+ /** Default priority for scanned routes (0.0 to 1.0). @default 0.5 */
542
1173
  defaultPriority?: number | undefined;
543
1174
  }
1175
+ /**
1176
+ * RouteScanner automatically discovers static GET routes from the Gravito router.
1177
+ *
1178
+ * It filters out routes with parameters (e.g., /user/:id) and non-GET routes
1179
+ * by default, ensuring that only crawlable pages are included in the sitemap.
1180
+ *
1181
+ * @example
1182
+ * ```typescript
1183
+ * const scanner = new RouteScanner(app.router, {
1184
+ * exclude: ['/admin/*', '/internal/*']
1185
+ * });
1186
+ * ```
1187
+ *
1188
+ * @public
1189
+ * @since 3.0.0
1190
+ */
544
1191
  declare class RouteScanner implements SitemapProvider {
545
1192
  private router;
546
1193
  private options;
547
1194
  constructor(router: any, options?: RouteScannerOptions);
1195
+ /**
1196
+ * Scan the router and return discovered entries.
1197
+ *
1198
+ * @returns An array of sitemap entries.
1199
+ */
548
1200
  getEntries(): SitemapEntry[];
549
1201
  private extractRoutes;
550
1202
  private shouldInclude;
551
1203
  }
1204
+ /**
1205
+ * Functional factory for creating a `RouteScanner`.
1206
+ *
1207
+ * @param router - The Gravito router instance.
1208
+ * @param options - Optional scanner configuration.
1209
+ * @returns A new RouteScanner instance.
1210
+ *
1211
+ * @public
1212
+ * @since 3.0.0
1213
+ */
552
1214
  declare function routeScanner(router: any, options?: RouteScannerOptions): RouteScanner;
553
1215
 
1216
+ /**
1217
+ * Options for automatic redirect detection via HTTP probes.
1218
+ *
1219
+ * @public
1220
+ * @since 3.0.0
1221
+ */
554
1222
  interface AutoDetectOptions {
1223
+ /** Whether automatic HTTP detection is enabled. */
555
1224
  enabled: boolean;
1225
+ /** HTTP request timeout in milliseconds. @default 5000 */
556
1226
  timeout?: number;
1227
+ /** Maximum number of concurrent HTTP probes. @default 10 */
557
1228
  maxConcurrent?: number;
1229
+ /** Whether to cache detection results in memory. @default false */
558
1230
  cache?: boolean;
1231
+ /** Cache time-to-live in seconds. @default 3600 */
559
1232
  cacheTtl?: number;
560
1233
  }
1234
+ /**
1235
+ * Options for redirect detection from a database table.
1236
+ *
1237
+ * @public
1238
+ * @since 3.0.0
1239
+ */
561
1240
  interface DatabaseDetectOptions {
1241
+ /** Whether database detection is enabled. */
562
1242
  enabled: boolean;
1243
+ /** The name of the table containing redirect rules. */
563
1244
  table: string;
1245
+ /** Column mapping for the redirect table. */
564
1246
  columns: {
565
1247
  from: string;
566
1248
  to: string;
567
1249
  type: string;
568
1250
  };
1251
+ /** Database connection instance (e.g., Knex, Atlas). */
569
1252
  connection: any;
570
1253
  }
1254
+ /**
1255
+ * Options for redirect detection from a static configuration file.
1256
+ *
1257
+ * @public
1258
+ * @since 3.0.0
1259
+ */
571
1260
  interface ConfigDetectOptions {
1261
+ /** Whether configuration file detection is enabled. */
572
1262
  enabled: boolean;
1263
+ /** Path to the JSON configuration file. */
573
1264
  path: string;
1265
+ /** Whether to watch the file for changes. @default false */
574
1266
  watch?: boolean;
575
1267
  }
1268
+ /**
1269
+ * Options for configuring the `RedirectDetector`.
1270
+ *
1271
+ * @public
1272
+ * @since 3.0.0
1273
+ */
576
1274
  interface RedirectDetectorOptions {
1275
+ /** The base URL of the site being scanned. */
577
1276
  baseUrl: string;
1277
+ /** Configuration for automatic HTTP probing. */
578
1278
  autoDetect?: AutoDetectOptions;
1279
+ /** Configuration for database-driven detection. */
579
1280
  database?: DatabaseDetectOptions;
1281
+ /** Configuration for file-driven detection. */
580
1282
  config?: ConfigDetectOptions;
581
1283
  }
582
1284
  /**
583
- * 轉址偵測器
584
- * 支援多種偵測方式:自動偵測、資料庫、設定檔
1285
+ * RedirectDetector identifies 301 and 302 redirects for URLs.
1286
+ *
1287
+ * It supports multiple detection strategies including database lookups,
1288
+ * static configuration files, and live HTTP probing. This ensures that
1289
+ * sitemaps always point to final destination URLs, improving SEO efficiency.
1290
+ *
1291
+ * @example
1292
+ * ```typescript
1293
+ * const detector = new RedirectDetector({
1294
+ * baseUrl: 'https://example.com',
1295
+ * autoDetect: { enabled: true }
1296
+ * });
1297
+ * const rule = await detector.detect('/old-path');
1298
+ * ```
1299
+ *
1300
+ * @public
1301
+ * @since 3.0.0
585
1302
  */
586
1303
  declare class RedirectDetector {
587
1304
  private options;
@@ -613,16 +1330,45 @@ declare class RedirectDetector {
613
1330
  private cacheResult;
614
1331
  }
615
1332
 
616
- type RedirectHandlingStrategy = 'remove_old_add_new' | 'keep_relation' | 'update_url' | 'dual_mark';
1333
+ /**
1334
+ * Strategies for handling URLs that have redirects in the sitemap.
1335
+ *
1336
+ * @public
1337
+ * @since 3.0.0
1338
+ */
1339
+ type RedirectHandlingStrategy =
1340
+ /** Replace the old URL with the final destination URL. (Default) */
1341
+ 'remove_old_add_new'
1342
+ /** Keep the old URL in the sitemap but mark the final destination as canonical. */
1343
+ | 'keep_relation'
1344
+ /** Silently update the URL to the destination without extra metadata. */
1345
+ | 'update_url'
1346
+ /** Include both the original and destination URLs in the sitemap. */
1347
+ | 'dual_mark';
1348
+ /**
1349
+ * Options for configuring the `RedirectHandler`.
1350
+ *
1351
+ * @public
1352
+ * @since 3.0.0
1353
+ */
617
1354
  interface RedirectHandlerOptions {
1355
+ /** The redirect manager used to resolve rules. */
618
1356
  manager: RedirectManager;
1357
+ /** The strategy to use when a redirect is found. */
619
1358
  strategy: RedirectHandlingStrategy;
1359
+ /** Whether to follow redirect chains to the final destination. @default false */
620
1360
  followChains?: boolean;
1361
+ /** Maximum number of redirect jumps to follow. @default 5 */
621
1362
  maxChainLength?: number;
622
1363
  }
623
1364
  /**
624
- * 轉址處理器
625
- * 處理 sitemap entries 中的轉址
1365
+ * RedirectHandler processes sitemap entries to ensure they handle 301/302 redirects correctly.
1366
+ *
1367
+ * It uses a `RedirectManager` to resolve final destinations and applies one of
1368
+ * the supported `RedirectHandlingStrategy` options to the entry list.
1369
+ *
1370
+ * @public
1371
+ * @since 3.0.0
626
1372
  */
627
1373
  declare class RedirectHandler {
628
1374
  private options;
@@ -649,11 +1395,24 @@ declare class RedirectHandler {
649
1395
  private handleDualMark;
650
1396
  }
651
1397
 
1398
+ /**
1399
+ * Options for configuring the `MemoryRedirectManager`.
1400
+ *
1401
+ * @public
1402
+ * @since 3.0.0
1403
+ */
652
1404
  interface MemoryRedirectManagerOptions {
1405
+ /** Maximum number of rules to keep in memory. @default 100000 */
653
1406
  maxRules?: number;
654
1407
  }
655
1408
  /**
656
- * 記憶體轉址管理器實作
1409
+ * MemoryRedirectManager is a fast, in-memory implementation of the `RedirectManager`.
1410
+ *
1411
+ * It is suitable for development environments or small sites where redirect
1412
+ * rules do not need to persist across application restarts.
1413
+ *
1414
+ * @public
1415
+ * @since 3.0.0
657
1416
  */
658
1417
  declare class MemoryRedirectManager implements RedirectManager {
659
1418
  private rules;
@@ -665,13 +1424,29 @@ declare class MemoryRedirectManager implements RedirectManager {
665
1424
  getAll(): Promise<RedirectRule[]>;
666
1425
  resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
667
1426
  }
1427
+ /**
1428
+ * Options for configuring the `RedisRedirectManager`.
1429
+ *
1430
+ * @public
1431
+ * @since 3.0.0
1432
+ */
668
1433
  interface RedisRedirectManagerOptions {
1434
+ /** The Redis client instance. */
669
1435
  client: any;
1436
+ /** Prefix for Redis keys to avoid collisions. @default 'sitemap:redirects:' */
670
1437
  keyPrefix?: string;
1438
+ /** Time-to-live for redirect rules in seconds. If not set, rules are permanent. */
671
1439
  ttl?: number;
672
1440
  }
673
1441
  /**
674
- * Redis 轉址管理器實作
1442
+ * RedisRedirectManager provides a persistent, distributed implementation of the `RedirectManager`.
1443
+ *
1444
+ * It uses Redis to store redirect rules, making it suitable for production
1445
+ * environments where multiple application instances need to share the same
1446
+ * redirect configuration.
1447
+ *
1448
+ * @public
1449
+ * @since 3.0.0
675
1450
  */
676
1451
  declare class RedisRedirectManager implements RedirectManager {
677
1452
  private client;
@@ -687,6 +1462,22 @@ declare class RedisRedirectManager implements RedirectManager {
687
1462
  resolve(url: string, followChains?: boolean, maxChainLength?: number): Promise<string | null>;
688
1463
  }
689
1464
 
1465
+ /**
1466
+ * DiskSitemapStorage persists sitemap files to the local file system.
1467
+ *
1468
+ * It is the default storage backend for single-server Gravito deployments.
1469
+ * It automatically handles directory creation and ensures filenames are sanitized
1470
+ * to prevent path traversal attacks.
1471
+ *
1472
+ * @example
1473
+ * ```typescript
1474
+ * const storage = new DiskSitemapStorage('./public/sitemaps', 'https://example.com/sitemaps');
1475
+ * await storage.write('sitemap.xml', '...');
1476
+ * ```
1477
+ *
1478
+ * @public
1479
+ * @since 3.0.0
1480
+ */
690
1481
  declare class DiskSitemapStorage implements SitemapStorage {
691
1482
  private outDir;
692
1483
  private baseUrl;
@@ -697,20 +1488,48 @@ declare class DiskSitemapStorage implements SitemapStorage {
697
1488
  getUrl(filename: string): string;
698
1489
  }
699
1490
 
1491
+ /**
1492
+ * Options for configuring the `GCPSitemapStorage`.
1493
+ *
1494
+ * @public
1495
+ * @since 3.0.0
1496
+ */
700
1497
  interface GCPSitemapStorageOptions {
1498
+ /** The Google Cloud Storage bucket name. */
701
1499
  bucket: string;
1500
+ /** Optional prefix (folder path) within the bucket. */
702
1501
  prefix?: string;
1502
+ /** Optional base URL for resolving sitemap locations. Defaults to the standard GCS public URL. */
703
1503
  baseUrl?: string;
1504
+ /** Configuration for staging files before atomic deployment. */
704
1505
  shadow?: {
1506
+ /** Whether shadow processing is enabled. */
705
1507
  enabled: boolean;
1508
+ /** Deployment mode: 'atomic' or 'versioned'. */
706
1509
  mode: 'atomic' | 'versioned';
707
1510
  };
1511
+ /** Path to the service account key file. */
708
1512
  keyFilename?: string;
1513
+ /** The Google Cloud Project ID. */
709
1514
  projectId?: string;
710
1515
  }
711
1516
  /**
712
- * Google Cloud Storage 儲存實作
713
- * 支援影子處理和版本化
1517
+ * GCPSitemapStorage persists sitemap files to Google Cloud Storage.
1518
+ *
1519
+ * It supports atomic deployments via shadow processing and file versioning,
1520
+ * allowing for reliable updates in high-traffic cloud environments.
1521
+ *
1522
+ * @example
1523
+ * ```typescript
1524
+ * const storage = new GCPSitemapStorage({
1525
+ * bucket: 'my-sitemaps',
1526
+ * prefix: 'prod/',
1527
+ * shadow: { enabled: true, mode: 'atomic' }
1528
+ * });
1529
+ * ```
1530
+ *
1531
+ * @public
1532
+ * @since 3.0.0
714
1533
  */
715
1534
  declare class GCPSitemapStorage implements SitemapStorage {
716
1535
  private bucket;
@@ -746,6 +1565,21 @@ declare class MemoryProgressStorage implements SitemapProgressStorage {
746
1565
  list(limit?: number): Promise<SitemapProgress[]>;
747
1566
  }
748
1567
 
1568
+ /**
1569
+ * MemorySitemapStorage is a non-persistent, in-memory storage backend for sitemaps.
1570
+ *
1571
+ * It is primarily used for testing or for applications where sitemaps are
1572
+ * generated on-the-fly and served directly from memory.
1573
+ *
1574
+ * @example
1575
+ * ```typescript
1576
+ * const storage = new MemorySitemapStorage('https://example.com');
1577
+ * await storage.write('sitemap.xml', '...');
1578
+ * ```
1579
+ *
1580
+ * @public
1581
+ * @since 3.0.0
1582
+ */
749
1583
  declare class MemorySitemapStorage implements SitemapStorage {
750
1584
  private baseUrl;
751
1585
  private files;
@@ -756,14 +1590,28 @@ declare class MemorySitemapStorage implements SitemapStorage {
756
1590
  getUrl(filename: string): string;
757
1591
  }
758
1592
 
1593
+ /**
1594
+ * Options for configuring the `RedisProgressStorage`.
1595
+ *
1596
+ * @public
1597
+ * @since 3.0.0
1598
+ */
759
1599
  interface RedisProgressStorageOptions {
1600
+ /** The Redis client instance. */
760
1601
  client: any;
1602
+ /** Prefix for Redis keys to avoid collisions. @default 'sitemap:progress:' */
761
1603
  keyPrefix?: string;
1604
+ /** Time-to-live for progress records in seconds. @default 86400 (24 hours) */
762
1605
  ttl?: number;
763
1606
  }
764
1607
  /**
765
- * Redis 進度儲存實作
766
- * 適用於分散式環境或多進程
1608
+ * RedisProgressStorage persists sitemap generation progress to Redis.
1609
+ *
1610
+ * It is designed for multi-process or distributed environments where progress
1611
+ * needs to be tracked across multiple worker instances.
1612
+ *
1613
+ * @public
1614
+ * @since 3.0.0
767
1615
  */
768
1616
  declare class RedisProgressStorage implements SitemapProgressStorage {
769
1617
  private client;
@@ -779,23 +1627,51 @@ declare class RedisProgressStorage implements SitemapProgressStorage {
779
1627
  list(limit?: number): Promise<SitemapProgress[]>;
780
1628
  }
781
1629
 
1630
+ /**
1631
+ * Options for configuring the `S3SitemapStorage`.
1632
+ *
1633
+ * @public
1634
+ * @since 3.0.0
1635
+ */
782
1636
  interface S3SitemapStorageOptions {
1637
+ /** The AWS S3 bucket name. */
783
1638
  bucket: string;
1639
+ /** The AWS region where the bucket is located. @default 'us-east-1' */
784
1640
  region?: string;
1641
+ /** Optional prefix (folder path) within the bucket. */
785
1642
  prefix?: string;
1643
+ /** Optional base URL for resolving sitemap locations. Defaults to standard S3 URL. */
786
1644
  baseUrl?: string;
1645
+ /** Configuration for staging files before atomic deployment. */
787
1646
  shadow?: {
1647
+ /** Whether shadow processing is enabled. */
788
1648
  enabled: boolean;
1649
+ /** Deployment mode: 'atomic' or 'versioned'. */
789
1650
  mode: 'atomic' | 'versioned';
790
1651
  };
1652
+ /** Optional AWS credentials. If not provided, the SDK will use environment defaults. */
791
1653
  credentials?: {
792
1654
  accessKeyId: string;
793
1655
  secretAccessKey: string;
794
1656
  };
795
1657
  }
796
1658
  /**
797
- * AWS S3 儲存實作
798
- * 支援影子處理和版本化
1659
+ * S3SitemapStorage persists sitemap files to AWS S3.
1660
+ *
1661
+ * It provides robust cloud storage with support for shadow processing
1662
+ * and file versioning, ensuring safe and atomic sitemap updates.
1663
+ *
1664
+ * @example
1665
+ * ```typescript
1666
+ * const storage = new S3SitemapStorage({
1667
+ * bucket: 'my-sitemaps',
1668
+ * region: 'ap-northeast-1',
1669
+ * shadow: { enabled: true, mode: 'atomic' }
1670
+ * });
1671
+ * ```
1672
+ *
1673
+ * @public
1674
+ * @since 3.0.0
799
1675
  */
800
1676
  declare class S3SitemapStorage implements SitemapStorage {
801
1677
  private bucket;