@gravito/signal 3.0.4 → 3.1.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.
Files changed (124) hide show
  1. package/README.md +26 -15
  2. package/dist/Mailable.d.ts +453 -0
  3. package/dist/OrbitSignal.d.ts +267 -0
  4. package/{src/Queueable.ts → dist/Queueable.d.ts} +1 -1
  5. package/{src/TypedMailable.ts → dist/TypedMailable.d.ts} +12 -13
  6. package/dist/dev/DevMailbox.d.ts +79 -0
  7. package/dist/dev/DevServer.d.ts +39 -0
  8. package/dist/dev/storage/FileMailboxStorage.d.ts +16 -0
  9. package/dist/dev/storage/MailboxStorage.d.ts +14 -0
  10. package/dist/dev/storage/MemoryMailboxStorage.d.ts +13 -0
  11. package/dist/dev/ui/mailbox.d.ts +11 -0
  12. package/dist/dev/ui/preview.d.ts +11 -0
  13. package/dist/dev/ui/shared.d.ts +15 -0
  14. package/dist/errors.d.ts +58 -0
  15. package/{src/events.ts → dist/events.d.ts} +20 -29
  16. package/dist/{lib-HJTRWKU5.mjs → index.cjs} +4687 -10983
  17. package/dist/index.d.ts +303 -1874
  18. package/dist/index.js +317 -45939
  19. package/dist/index.mjs +59748 -27
  20. package/dist/renderers/HtmlRenderer.d.ts +34 -0
  21. package/dist/renderers/MjmlRenderer.d.ts +41 -0
  22. package/dist/renderers/ReactMjmlRenderer.d.ts +38 -0
  23. package/dist/renderers/ReactRenderer.d.ts +46 -0
  24. package/{src/renderers/Renderer.ts → dist/renderers/Renderer.d.ts} +23 -24
  25. package/dist/renderers/TemplateRenderer.d.ts +55 -0
  26. package/dist/renderers/VueMjmlRenderer.d.ts +39 -0
  27. package/dist/renderers/VueRenderer.d.ts +47 -0
  28. package/dist/renderers/mjml-templates.d.ts +11 -0
  29. package/dist/transports/BaseTransport.d.ts +111 -0
  30. package/dist/transports/LogTransport.d.ts +42 -0
  31. package/dist/transports/MemoryTransport.d.ts +51 -0
  32. package/dist/transports/SesTransport.d.ts +79 -0
  33. package/dist/transports/SmtpTransport.d.ts +124 -0
  34. package/dist/transports/Transport.d.ts +44 -0
  35. package/dist/types.d.ts +294 -0
  36. package/{src/utils/html.ts → dist/utils/html.d.ts} +1 -15
  37. package/dist/webhooks/SendGridWebhookDriver.d.ts +45 -0
  38. package/dist/webhooks/SesWebhookDriver.d.ts +23 -0
  39. package/package.json +20 -8
  40. package/CHANGELOG.md +0 -74
  41. package/dist/MjmlRenderer-IUH663FT.mjs +0 -8
  42. package/dist/ReactMjmlRenderer-C3P5YO5L.mjs +0 -8
  43. package/dist/ReactRenderer-24SQ4KRU.mjs +0 -27
  44. package/dist/ReactRenderer-2JFLRVST.mjs +0 -45
  45. package/dist/ReactRenderer-CMCAOEPH.mjs +0 -28
  46. package/dist/ReactRenderer-KYNA4WKE.mjs +0 -28
  47. package/dist/ReactRenderer-LYEOSYFS.mjs +0 -28
  48. package/dist/ReactRenderer-V54CUUEI.mjs +0 -45
  49. package/dist/VueMjmlRenderer-4F4CXHDB.mjs +0 -8
  50. package/dist/VueMjmlRenderer-5WZR4CQG.mjs +0 -8
  51. package/dist/VueMjmlRenderer-U5YMWI44.mjs +0 -8
  52. package/dist/VueRenderer-3YBRQXME.mjs +0 -48
  53. package/dist/VueRenderer-46JGXTJ2.mjs +0 -48
  54. package/dist/VueRenderer-5KWD4R3C.mjs +0 -48
  55. package/dist/VueRenderer-C23U4O5E.mjs +0 -48
  56. package/dist/VueRenderer-DWTCD2RF.mjs +0 -31
  57. package/dist/VueRenderer-IIR5SYTM.mjs +0 -31
  58. package/dist/VueRenderer-LEVDFLHP.mjs +0 -31
  59. package/dist/VueRenderer-RNHSCCRI.mjs +0 -48
  60. package/dist/VueRenderer-SUP66ISX.mjs +0 -29
  61. package/dist/chunk-3WOR3XSL.mjs +0 -82
  62. package/dist/chunk-DBFIVHHG.mjs +0 -79
  63. package/dist/chunk-EBO3CZXG.mjs +0 -15
  64. package/dist/chunk-HEBXNMVQ.mjs +0 -48
  65. package/dist/chunk-KB7IDDBT.mjs +0 -82
  66. package/dist/chunk-LZL5UUPC.mjs +0 -82
  67. package/dist/chunk-W6LXIJKK.mjs +0 -57
  68. package/dist/chunk-XBIVBJS2.mjs +0 -8
  69. package/dist/index.d.mts +0 -2115
  70. package/dist/server-renderer-4IM3P5XZ.mjs +0 -37183
  71. package/dist/server-renderer-4W4FI7YG.mjs +0 -37269
  72. package/dist/server-renderer-7KWFSTPV.mjs +0 -37193
  73. package/dist/server-renderer-S5FPSTJ2.mjs +0 -37183
  74. package/dist/server-renderer-X5LUFVWT.mjs +0 -37193
  75. package/doc/OPTIMIZATION_PLAN.md +0 -496
  76. package/scripts/check-coverage.ts +0 -64
  77. package/src/Mailable.ts +0 -674
  78. package/src/OrbitSignal.ts +0 -451
  79. package/src/dev/DevMailbox.ts +0 -146
  80. package/src/dev/DevServer.ts +0 -192
  81. package/src/dev/storage/FileMailboxStorage.ts +0 -66
  82. package/src/dev/storage/MailboxStorage.ts +0 -15
  83. package/src/dev/storage/MemoryMailboxStorage.ts +0 -36
  84. package/src/dev/ui/mailbox.ts +0 -77
  85. package/src/dev/ui/preview.ts +0 -103
  86. package/src/dev/ui/shared.ts +0 -60
  87. package/src/errors.ts +0 -69
  88. package/src/index.ts +0 -41
  89. package/src/renderers/HtmlRenderer.ts +0 -41
  90. package/src/renderers/MjmlRenderer.ts +0 -73
  91. package/src/renderers/ReactMjmlRenderer.ts +0 -94
  92. package/src/renderers/ReactRenderer.ts +0 -66
  93. package/src/renderers/TemplateRenderer.ts +0 -84
  94. package/src/renderers/VueMjmlRenderer.ts +0 -99
  95. package/src/renderers/VueRenderer.ts +0 -71
  96. package/src/renderers/mjml-templates.ts +0 -50
  97. package/src/transports/BaseTransport.ts +0 -148
  98. package/src/transports/LogTransport.ts +0 -55
  99. package/src/transports/MemoryTransport.ts +0 -55
  100. package/src/transports/SesTransport.ts +0 -129
  101. package/src/transports/SmtpTransport.ts +0 -184
  102. package/src/transports/Transport.ts +0 -45
  103. package/src/types.ts +0 -309
  104. package/src/webhooks/SendGridWebhookDriver.ts +0 -80
  105. package/src/webhooks/SesWebhookDriver.ts +0 -44
  106. package/tests/DevMailbox.test.ts +0 -54
  107. package/tests/FileMailboxStorage.test.ts +0 -56
  108. package/tests/MjmlLayout.test.ts +0 -28
  109. package/tests/MjmlRenderer.test.ts +0 -53
  110. package/tests/OrbitSignalWebhook.test.ts +0 -56
  111. package/tests/ReactMjmlRenderer.test.ts +0 -33
  112. package/tests/SendGridWebhookDriver.test.ts +0 -69
  113. package/tests/SesWebhookDriver.test.ts +0 -46
  114. package/tests/VueMjmlRenderer.test.ts +0 -35
  115. package/tests/dev-server.test.ts +0 -66
  116. package/tests/log-transport.test.ts +0 -21
  117. package/tests/mailable-extra.test.ts +0 -68
  118. package/tests/mailable.test.ts +0 -77
  119. package/tests/orbit-signal.test.ts +0 -43
  120. package/tests/renderers.test.ts +0 -58
  121. package/tests/template-renderer.test.ts +0 -24
  122. package/tests/transports.test.ts +0 -52
  123. package/tests/ui.test.ts +0 -37
  124. package/tsconfig.json +0 -14
@@ -0,0 +1,34 @@
1
+ import type { Renderer, RenderResult } from './Renderer';
2
+ /**
3
+ * Renderer for plain HTML content.
4
+ *
5
+ * The simplest renderer - accepts raw HTML strings and automatically generates
6
+ * a plain text version by stripping HTML tags. Ideal for pre-rendered HTML or
7
+ * when using external HTML generation libraries.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const renderer = new HtmlRenderer('<h1>Hello</h1>');
12
+ * const result = await renderer.render();
13
+ * // result.html: '<h1>Hello</h1>'
14
+ * // result.text: 'Hello'
15
+ * ```
16
+ *
17
+ * @public
18
+ * @since 3.0.0
19
+ */
20
+ export declare class HtmlRenderer implements Renderer {
21
+ private content;
22
+ /**
23
+ * Creates an instance of HtmlRenderer.
24
+ *
25
+ * @param content - The raw HTML string to be rendered.
26
+ */
27
+ constructor(content: string);
28
+ /**
29
+ * Returns the original HTML and a stripped plain text version.
30
+ *
31
+ * @returns A promise resolving to the rendered content.
32
+ */
33
+ render(): Promise<RenderResult>;
34
+ }
@@ -0,0 +1,41 @@
1
+ import type { Renderer, RenderResult } from './Renderer';
2
+ /**
3
+ * Renderer for MJML-based emails.
4
+ *
5
+ * MJML is a markup language designed to reduce the pain of coding a responsive email.
6
+ * This renderer lazily loads the `mjml` package to keep the core lightweight.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const renderer = new MjmlRenderer('<mjml><mj-body>...</mj-body></mjml>');
11
+ * const result = await renderer.render();
12
+ * ```
13
+ *
14
+ * @public
15
+ * @since 1.1.0
16
+ */
17
+ export declare class MjmlRenderer implements Renderer {
18
+ private content;
19
+ private options;
20
+ private deps;
21
+ /**
22
+ * Creates an instance of MjmlRenderer.
23
+ *
24
+ * @param content - The MJML markup string to be rendered.
25
+ * @param options - Optional MJML transformation options.
26
+ * @param deps - Optional dependency injection for testing.
27
+ */
28
+ constructor(content: string, options?: Record<string, any>, deps?: {
29
+ mjml2html?: (mjml: string, options?: any) => any;
30
+ });
31
+ /**
32
+ * Renders the MJML content to static HTML.
33
+ *
34
+ * This method performs a dynamic import of `mjml` to ensure it's only
35
+ * loaded if this renderer is actually used.
36
+ *
37
+ * @returns A promise resolving to the rendered content.
38
+ * @throws {Error} If MJML dependencies cannot be loaded or rendering fails.
39
+ */
40
+ render(): Promise<RenderResult>;
41
+ }
@@ -0,0 +1,38 @@
1
+ import type { Renderer, RenderResult } from './Renderer';
2
+ /**
3
+ * Renderer for React component-based MJML emails.
4
+ *
5
+ * Renders React components to MJML string using SSR, then converts
6
+ * the MJML to responsive HTML.
7
+ *
8
+ * @typeParam P - Props type for the React component.
9
+ * @public
10
+ * @since 1.1.0
11
+ */
12
+ export declare class ReactMjmlRenderer<P extends object = object> implements Renderer {
13
+ private component;
14
+ private props?;
15
+ private options;
16
+ private deps;
17
+ /**
18
+ * Creates an instance of ReactMjmlRenderer.
19
+ *
20
+ * @param component - The React component to render.
21
+ * @param props - Initial props for the component.
22
+ * @param options - Optional MJML transformation options.
23
+ * @param deps - Optional dependency injection for testing.
24
+ */
25
+ constructor(component: any, props?: P, options?: Record<string, any>, deps?: {
26
+ createElement?: (...args: any[]) => any;
27
+ renderToStaticMarkup?: (element: any) => string;
28
+ mjml2html?: (mjml: string, options?: any) => any;
29
+ });
30
+ /**
31
+ * Renders the React component to a static HTML string via MJML.
32
+ *
33
+ * @param data - Runtime data to be merged with initial props.
34
+ * @returns A promise resolving to the rendered content.
35
+ * @throws {Error} If MJML rendering fails.
36
+ */
37
+ render(data: Record<string, unknown>): Promise<RenderResult>;
38
+ }
@@ -0,0 +1,46 @@
1
+ import type { Renderer, RenderResult } from './Renderer';
2
+ /**
3
+ * Renderer for React component-based emails.
4
+ *
5
+ * Renders React components to static HTML using server-side rendering (SSR).
6
+ * It lazily loads React and ReactDOM dependencies only when needed, preventing
7
+ * unnecessary bundle bloat for users who do not use React renderers.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const renderer = new ReactRenderer(MyComponent, { title: 'Welcome' });
12
+ * const result = await renderer.render({ name: 'John' });
13
+ * ```
14
+ *
15
+ * @typeParam P - Props type for the React component.
16
+ * @public
17
+ * @since 3.0.0
18
+ */
19
+ export declare class ReactRenderer<P extends object = object> implements Renderer {
20
+ private component;
21
+ private props?;
22
+ private deps;
23
+ /**
24
+ * Creates an instance of ReactRenderer.
25
+ *
26
+ * @param component - The React component to render.
27
+ * @param props - Initial props for the component.
28
+ * @param deps - Optional dependency injection for testing.
29
+ */
30
+ constructor(component: any, // Use any to avoid hard React dependency in types
31
+ props?: P, deps?: {
32
+ createElement?: (...args: any[]) => any;
33
+ renderToStaticMarkup?: (element: any) => string;
34
+ });
35
+ /**
36
+ * Renders the React component to a static HTML string.
37
+ *
38
+ * This method performs dynamic imports of `react` and `react-dom/server`
39
+ * to ensure they are only loaded if this renderer is actually used.
40
+ *
41
+ * @param data - Runtime data to be merged with initial props.
42
+ * @returns A promise resolving to the rendered content.
43
+ * @throws {Error} If React dependencies cannot be loaded or rendering fails.
44
+ */
45
+ render(data: Record<string, unknown>): Promise<RenderResult>;
46
+ }
@@ -18,20 +18,19 @@
18
18
  * @since 3.0.0
19
19
  */
20
20
  export interface RenderResult {
21
- /**
22
- * The rendered HTML string.
23
- *
24
- * This is the primary content used for the email body.
25
- */
26
- html: string
27
- /**
28
- * Optional rendered plain text string.
29
- *
30
- * Used as a fallback for email clients that cannot display HTML or for accessibility.
31
- */
32
- text?: string
21
+ /**
22
+ * The rendered HTML string.
23
+ *
24
+ * This is the primary content used for the email body.
25
+ */
26
+ html: string;
27
+ /**
28
+ * Optional rendered plain text string.
29
+ *
30
+ * Used as a fallback for email clients that cannot display HTML or for accessibility.
31
+ */
32
+ text?: string;
33
33
  }
34
-
35
34
  /**
36
35
  * Interface for email content renderers.
37
36
  *
@@ -53,15 +52,15 @@ export interface RenderResult {
53
52
  * @since 3.0.0
54
53
  */
55
54
  export interface Renderer {
56
- /**
57
- * Render the content into HTML and optionally plain text.
58
- *
59
- * This method performs the actual transformation of the source content
60
- * using the provided data context.
61
- *
62
- * @param data - The data context for rendering.
63
- * @returns A promise resolving to the rendered content.
64
- * @throws {Error} If rendering fails due to syntax errors or missing dependencies.
65
- */
66
- render(data: Record<string, unknown>): Promise<RenderResult>
55
+ /**
56
+ * Render the content into HTML and optionally plain text.
57
+ *
58
+ * This method performs the actual transformation of the source content
59
+ * using the provided data context.
60
+ *
61
+ * @param data - The data context for rendering.
62
+ * @returns A promise resolving to the rendered content.
63
+ * @throws {Error} If rendering fails due to syntax errors or missing dependencies.
64
+ */
65
+ render(data: Record<string, unknown>): Promise<RenderResult>;
67
66
  }
@@ -0,0 +1,55 @@
1
+ import type { Renderer, RenderResult } from './Renderer';
2
+ /**
3
+ * Renderer for template-based emails using Gravito Prism.
4
+ *
5
+ * Renders email templates from the filesystem using the Prism template engine.
6
+ * It uses a static cache for the template engine to avoid redundant initialization
7
+ * costs when rendering multiple emails from the same directory.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const renderer = new TemplateRenderer('welcome', './src/emails');
12
+ * const result = await renderer.render({ name: 'John' });
13
+ * ```
14
+ *
15
+ * @public
16
+ * @since 3.0.0
17
+ */
18
+ export declare class TemplateRenderer implements Renderer {
19
+ private template;
20
+ private viewsDir;
21
+ private static engineCache;
22
+ /**
23
+ * Creates an instance of TemplateRenderer.
24
+ *
25
+ * @param templateName - The name of the template file (without extension).
26
+ * @param viewsDir - The directory containing template files. Defaults to `src/emails`.
27
+ */
28
+ constructor(templateName: string, viewsDir?: string);
29
+ /**
30
+ * Renders the template with the provided data.
31
+ *
32
+ * This method lazily loads `@gravito/prism` to ensure the core package
33
+ * remains lightweight for users who don't need template rendering.
34
+ *
35
+ * @param data - The data context for template interpolation.
36
+ * @returns A promise resolving to the rendered content.
37
+ * @throws {Error} If the template engine fails to load or rendering fails.
38
+ */
39
+ render(data: Record<string, unknown>): Promise<RenderResult>;
40
+ /**
41
+ * Clear template engine cache.
42
+ *
43
+ * Useful in development environments to force recompilation of templates
44
+ * after they have been modified on disk.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * TemplateRenderer.clearCache();
49
+ * ```
50
+ *
51
+ * @public
52
+ * @since 3.1.0
53
+ */
54
+ static clearCache(): void;
55
+ }
@@ -0,0 +1,39 @@
1
+ import type { Renderer, RenderResult } from './Renderer';
2
+ /**
3
+ * Renderer for Vue component-based MJML emails.
4
+ *
5
+ * Renders Vue 3 components to MJML string using SSR, then converts
6
+ * the MJML to responsive HTML.
7
+ *
8
+ * @typeParam P - Props type for the Vue component.
9
+ * @public
10
+ * @since 1.1.0
11
+ */
12
+ export declare class VueMjmlRenderer<P extends object = object> implements Renderer {
13
+ private component;
14
+ private props?;
15
+ private options;
16
+ private deps;
17
+ /**
18
+ * Creates an instance of VueMjmlRenderer.
19
+ *
20
+ * @param component - The Vue component to render.
21
+ * @param props - Initial props for the component.
22
+ * @param options - Optional MJML transformation options.
23
+ * @param deps - Optional dependency injection for testing.
24
+ */
25
+ constructor(component: any, props?: P, options?: Record<string, any>, deps?: {
26
+ createSSRApp?: (...args: any[]) => any;
27
+ h?: (...args: any[]) => any;
28
+ renderToString?: (app: any) => Promise<string>;
29
+ mjml2html?: (mjml: string, options?: any) => any;
30
+ });
31
+ /**
32
+ * Renders the Vue component to a static HTML string via MJML.
33
+ *
34
+ * @param data - Runtime data to be merged with initial props.
35
+ * @returns A promise resolving to the rendered content.
36
+ * @throws {Error} If MJML rendering fails.
37
+ */
38
+ render(data: Record<string, unknown>): Promise<RenderResult>;
39
+ }
@@ -0,0 +1,47 @@
1
+ import type { Renderer, RenderResult } from './Renderer';
2
+ /**
3
+ * Renderer for Vue component-based emails.
4
+ *
5
+ * Renders Vue 3 components to static HTML using server-side rendering (SSR).
6
+ * It lazily loads Vue and `@vue/server-renderer` dependencies only when needed,
7
+ * preventing unnecessary bundle bloat for users who do not use Vue renderers.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const renderer = new VueRenderer(MyComponent, { title: 'Welcome' });
12
+ * const result = await renderer.render({ name: 'John' });
13
+ * ```
14
+ *
15
+ * @typeParam P - Props type for the Vue component.
16
+ * @public
17
+ * @since 3.0.0
18
+ */
19
+ export declare class VueRenderer<P extends object = object> implements Renderer {
20
+ private component;
21
+ private props?;
22
+ private deps;
23
+ /**
24
+ * Creates an instance of VueRenderer.
25
+ *
26
+ * @param component - The Vue component to render.
27
+ * @param props - Initial props for the component.
28
+ * @param deps - Optional dependency injection for testing.
29
+ */
30
+ constructor(component: any, // Use any to avoid hard Vue dependency in types
31
+ props?: P, deps?: {
32
+ createSSRApp?: (...args: any[]) => any;
33
+ h?: (...args: any[]) => any;
34
+ renderToString?: (app: any) => Promise<string>;
35
+ });
36
+ /**
37
+ * Renders the Vue component to a static HTML string.
38
+ *
39
+ * This method performs dynamic imports of `vue` and `@vue/server-renderer`
40
+ * to ensure they are only loaded if this renderer is actually used.
41
+ *
42
+ * @param data - Runtime data to be merged with initial props.
43
+ * @returns A promise resolving to the rendered content.
44
+ * @throws {Error} If Vue dependencies cannot be loaded or rendering fails.
45
+ */
46
+ render(data: Record<string, unknown>): Promise<RenderResult>;
47
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Base layout for MJML emails.
3
+ * Includes common head styles and responsive settings.
4
+ *
5
+ * Placeholder: {{content}}
6
+ */
7
+ export declare const baseLayout: string;
8
+ /**
9
+ * A simple transactional component layout.
10
+ */
11
+ export declare const transactionLayout = "\n<mj-section background-color=\"#ffffff\" padding-top=\"0px\">\n <mj-column>\n {{content}}\n </mj-column>\n</mj-section>\n";
@@ -0,0 +1,111 @@
1
+ import type { Message, Transport } from '../types';
2
+ /**
3
+ * Transport retry configuration options.
4
+ *
5
+ * Defines the behavior of the automatic retry mechanism, including the number of attempts
6
+ * and the timing between them using exponential backoff.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const options: TransportOptions = {
11
+ * maxRetries: 5,
12
+ * retryDelay: 500,
13
+ * backoffMultiplier: 3
14
+ * };
15
+ * ```
16
+ *
17
+ * @public
18
+ */
19
+ export interface TransportOptions {
20
+ /**
21
+ * Maximum number of retry attempts before giving up.
22
+ * Set to 0 to disable retries.
23
+ */
24
+ maxRetries?: number;
25
+ /**
26
+ * Initial delay in milliseconds before the first retry attempt.
27
+ */
28
+ retryDelay?: number;
29
+ /**
30
+ * Multiplier applied to the delay after each failed attempt.
31
+ * Used to implement exponential backoff to avoid overwhelming the service.
32
+ */
33
+ backoffMultiplier?: number;
34
+ }
35
+ /**
36
+ * Base transport class with automatic retry mechanism.
37
+ *
38
+ * This abstract class provides a robust foundation for all transport implementations by
39
+ * handling transient failures through an exponential backoff retry strategy. It ensures
40
+ * that temporary network issues or service rate limits do not immediately fail the email delivery.
41
+ *
42
+ * The retry mechanism works as follows:
43
+ * 1. Attempt to send the message via `doSend()`.
44
+ * 2. If it fails, wait for `retryDelay` milliseconds.
45
+ * 3. Increment the delay by `backoffMultiplier` for the next attempt.
46
+ * 4. Repeat until success or `maxRetries` is reached.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * class MyTransport extends BaseTransport {
51
+ * constructor() {
52
+ * super({ maxRetries: 3, retryDelay: 1000 })
53
+ * }
54
+ *
55
+ * protected async doSend(message: Message): Promise<void> {
56
+ * // Actual implementation of the sending logic
57
+ * // If this throws, BaseTransport will catch and retry
58
+ * }
59
+ * }
60
+ * ```
61
+ *
62
+ * @public
63
+ */
64
+ export declare abstract class BaseTransport implements Transport {
65
+ protected options: Required<TransportOptions>;
66
+ /**
67
+ * Initializes the transport with retry options.
68
+ *
69
+ * @param options - Configuration for the retry mechanism.
70
+ */
71
+ constructor(options?: TransportOptions);
72
+ /**
73
+ * Orchestrates the message delivery with retry logic.
74
+ *
75
+ * This method wraps the concrete `doSend` implementation in a retry loop.
76
+ * It tracks the last error encountered to provide context if all retries fail.
77
+ *
78
+ * @param message - The message to be delivered.
79
+ * @returns A promise that resolves when the message is successfully sent.
80
+ * @throws {MailTransportError} If the message cannot be sent after the maximum number of retries.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * const transport = new SmtpTransport(config);
85
+ * try {
86
+ * await transport.send(message);
87
+ * } catch (error) {
88
+ * console.error('Failed to send email after retries', error);
89
+ * }
90
+ * ```
91
+ */
92
+ send(message: Message): Promise<void>;
93
+ /**
94
+ * Actual transport implementation to be provided by subclasses.
95
+ *
96
+ * This method should contain the protocol-specific logic for delivering the message.
97
+ * It will be automatically retried by the `send` method if it throws an error.
98
+ *
99
+ * @param message - The message to send.
100
+ * @returns A promise that resolves when the delivery is successful.
101
+ * @throws {Error} Any error encountered during delivery, which will trigger a retry.
102
+ */
103
+ protected abstract doSend(message: Message): Promise<void>;
104
+ /**
105
+ * Utility method to pause execution for a given duration.
106
+ *
107
+ * @param ms - Milliseconds to sleep.
108
+ * @returns A promise that resolves after the delay.
109
+ */
110
+ private sleep;
111
+ }
@@ -0,0 +1,42 @@
1
+ import type { Message, Transport } from '../types';
2
+ /**
3
+ * Log transport for development and testing.
4
+ *
5
+ * This transport outputs email details directly to the console instead of performing
6
+ * actual delivery. It is essential for local development to avoid sending real emails
7
+ * while still being able to verify the content, recipients, and subject of outgoing mail.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { LogTransport } from '@gravito/signal';
12
+ *
13
+ * const transport = new LogTransport();
14
+ * await transport.send({
15
+ * from: { address: 'dev@localhost' },
16
+ * to: [{ address: 'user@example.com' }],
17
+ * subject: 'Test Email',
18
+ * html: '<h1>Hello</h1>'
19
+ * });
20
+ * ```
21
+ *
22
+ * @public
23
+ */
24
+ export declare class LogTransport implements Transport {
25
+ /**
26
+ * Outputs the message details to the system console.
27
+ *
28
+ * Formats the email metadata (From, To, Subject) and content size into a readable
29
+ * block in the console output.
30
+ *
31
+ * @param message - The message to log.
32
+ * @returns A promise that resolves immediately after logging.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const transport = new LogTransport();
37
+ * await transport.send(message);
38
+ * // Console: 📧 [OrbitSignal] Email Sent (Simulated)...
39
+ * ```
40
+ */
41
+ send(message: Message): Promise<void>;
42
+ }
@@ -0,0 +1,51 @@
1
+ import type { DevMailbox } from '../dev/DevMailbox';
2
+ import type { Message, Transport } from '../types';
3
+ /**
4
+ * Memory transport for development mode.
5
+ *
6
+ * This transport captures outgoing emails and stores them in an in-memory mailbox.
7
+ * It is primarily used by the Gravito Dev UI to provide a live preview of emails
8
+ * during development without requiring an external mail server.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { DevMailbox, MemoryTransport } from '@gravito/signal';
13
+ *
14
+ * const mailbox = new DevMailbox();
15
+ * const transport = new MemoryTransport(mailbox);
16
+ * await transport.send(message);
17
+ *
18
+ * console.log(mailbox.getAll().length); // 1
19
+ * ```
20
+ *
21
+ * @public
22
+ */
23
+ export declare class MemoryTransport implements Transport {
24
+ private mailbox;
25
+ /**
26
+ * Creates a new MemoryTransport instance.
27
+ *
28
+ * @param mailbox - The in-memory storage where messages will be collected.
29
+ */
30
+ constructor(mailbox: DevMailbox);
31
+ /**
32
+ * Stores the message in the associated mailbox.
33
+ *
34
+ * The message is added to the internal list of the `DevMailbox` instance,
35
+ * making it available for retrieval by the Dev UI or test assertions.
36
+ *
37
+ * @param message - The message to store.
38
+ * @returns A promise that resolves once the message is added to the mailbox.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * await transport.send({
43
+ * from: { address: 'dev@localhost' },
44
+ * to: [{ address: 'test@example.com' }],
45
+ * subject: 'Memory Test',
46
+ * html: '<p>Stored in memory</p>'
47
+ * });
48
+ * ```
49
+ */
50
+ send(message: Message): Promise<void>;
51
+ }
@@ -0,0 +1,79 @@
1
+ import type { Message } from '../types';
2
+ import { BaseTransport, type TransportOptions } from './BaseTransport';
3
+ /**
4
+ * Configuration for AWS SES email transport.
5
+ *
6
+ * Defines the AWS region and credentials required to communicate with the
7
+ * Amazon Simple Email Service API.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const config: SesConfig = {
12
+ * region: 'us-east-1',
13
+ * accessKeyId: 'AKIA...',
14
+ * secretAccessKey: 'wJalr...',
15
+ * maxRetries: 5
16
+ * };
17
+ * ```
18
+ *
19
+ * @public
20
+ */
21
+ export interface SesConfig extends TransportOptions {
22
+ /** AWS region where the SES service is hosted (e.g., 'us-east-1'). */
23
+ region: string;
24
+ /** AWS access key ID. If omitted, the SDK will attempt to use default credential providers. */
25
+ accessKeyId?: string;
26
+ /** AWS secret access key. Required if accessKeyId is provided. */
27
+ secretAccessKey?: string;
28
+ }
29
+ /**
30
+ * AWS SES (Simple Email Service) transport with automatic retry.
31
+ *
32
+ * This transport delivers emails via the Amazon SES API. It requires the
33
+ * `@aws-sdk/client-ses` package to be installed as a dependency. It provides
34
+ * a reliable way to send high volumes of email using AWS infrastructure and
35
+ * includes automatic retry logic for transient API errors.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * import { SesTransport } from '@gravito/signal';
40
+ *
41
+ * const transport = new SesTransport({
42
+ * region: 'us-west-2'
43
+ * });
44
+ *
45
+ * await transport.send(message);
46
+ * ```
47
+ *
48
+ * @public
49
+ */
50
+ export declare class SesTransport extends BaseTransport {
51
+ private transporter;
52
+ /**
53
+ * Initializes the SES transport with the provided configuration.
54
+ *
55
+ * Configures the AWS SES client and wraps it in a nodemailer transporter
56
+ * for consistent message handling.
57
+ *
58
+ * @param config - AWS SES connection and retry configuration.
59
+ */
60
+ constructor(config: SesConfig);
61
+ /**
62
+ * Internal method to perform the actual SES delivery.
63
+ *
64
+ * Converts the generic `Message` object into a raw email format and sends it
65
+ * via the SES `SendRawEmail` API.
66
+ *
67
+ * @param message - The message to deliver.
68
+ * @returns A promise that resolves when SES accepts the message for delivery.
69
+ * @throws {Error} If the SES API returns an error or connection fails.
70
+ */
71
+ protected doSend(message: Message): Promise<void>;
72
+ /**
73
+ * Formats an Address object into a standard RFC 822 string.
74
+ *
75
+ * @param addr - The address object to format.
76
+ * @returns A string in the format "Name <email@example.com>" or just "email@example.com".
77
+ */
78
+ private formatAddress;
79
+ }