@gravito/constellation 3.0.0 → 3.0.2

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