samva 0.11.0 → 0.13.0

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 (59) hide show
  1. package/dist/{categories-DvsHUJtX.js → categories-Bcwq5jPV.js} +5 -1
  2. package/dist/client/sdk.gen.d.ts +48 -21
  3. package/dist/client/types.gen.d.ts +340 -64
  4. package/dist/{client-8YXjfsVc.js → client-DYPNDvVU.js} +330 -75
  5. package/dist/effect/analytics.js +1 -1
  6. package/dist/effect/api-keys.js +1 -1
  7. package/dist/effect/attachments.js +1 -1
  8. package/dist/effect/brands.js +2 -2
  9. package/dist/effect/campaigns.d.ts +1 -1
  10. package/dist/effect/campaigns.js +1 -1
  11. package/dist/effect/categories.js +1 -1
  12. package/dist/effect/client.js +1 -1
  13. package/dist/effect/contact-groups.d.ts +0 -3
  14. package/dist/effect/contact-groups.js +1 -1
  15. package/dist/effect/contacts.d.ts +40 -8
  16. package/dist/effect/contacts.js +1 -1
  17. package/dist/effect/conversations.js +1 -1
  18. package/dist/effect/custom-fields.js +1 -1
  19. package/dist/effect/email.d.ts +87 -2
  20. package/dist/effect/email.js +7 -3
  21. package/dist/effect/extension-installations.d.ts +66 -0
  22. package/dist/effect/extension-installations.js +5 -3
  23. package/dist/effect/extensions.js +1 -1
  24. package/dist/effect/feedback.js +2 -2
  25. package/dist/effect/generated-metadata.d.ts +4 -0
  26. package/dist/effect/generated.d.ts +1312 -162
  27. package/dist/effect/index.d.ts +1 -0
  28. package/dist/effect/index.js +5 -4
  29. package/dist/effect/internal/client.d.ts +14 -0
  30. package/dist/effect/internal/operation.d.ts +5 -2
  31. package/dist/effect/mailboxes.d.ts +6 -6
  32. package/dist/effect/mailboxes.js +2 -2
  33. package/dist/effect/media.js +1 -1
  34. package/dist/effect/messages.d.ts +2 -2
  35. package/dist/effect/messages.js +1 -1
  36. package/dist/effect/namespaces.js +1 -1
  37. package/dist/effect/operations.js +1 -1
  38. package/dist/effect/organizations.js +1 -1
  39. package/dist/effect/retry.js +1 -1
  40. package/dist/effect/scheduled-messages.d.ts +1 -1
  41. package/dist/effect/scheduled-messages.js +1 -1
  42. package/dist/effect/templates.js +2 -2
  43. package/dist/effect/unsubscribe-groups.js +1 -1
  44. package/dist/effect/webhooks.js +2 -2
  45. package/dist/index.js +4 -3
  46. package/dist/inline-attachments-B56eS0MF.js +121 -0
  47. package/dist/inline-attachments.d.ts +65 -0
  48. package/dist/{mailbox-events-CcWm8lO4.js → mailbox-events-CsbF35vH.js} +18 -6
  49. package/dist/mailbox-events.d.ts +8 -5
  50. package/dist/{mailboxes-4gJMAJh4.js → mailboxes-D3Kx7elM.js} +4 -4
  51. package/dist/{operation-BuyvAsZ1.js → operation-B_Ty1LG-.js} +45 -3
  52. package/dist/promises/errors.gen.d.ts +14 -2
  53. package/dist/promises/index.d.ts +1 -0
  54. package/dist/promises/index.js +4 -3
  55. package/dist/promises/types.gen.d.ts +1 -1
  56. package/dist/{promises-CqAmI39P.js → promises-D9FJyU0q.js} +178 -20
  57. package/dist/service-map.d.ts +15 -0
  58. package/package.json +2 -2
  59. package/dist/client-attribution-Ct2FKITg.js +0 -9
@@ -43,5 +43,6 @@ export * as UnsubscribeGroups from "./unsubscribe-groups";
43
43
  export * as Webhooks from "./webhooks";
44
44
  export { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, OnboardingReviewRequiredError, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, UnauthorizedError, ValidationError, DeliveryUnavailableError, } from "./generated";
45
45
  export { type ErrorCategory, categoriesOf, hasCategory, isAuthError, isValidationError, isNotFoundError, isConflictError, isThrottlingError, isBillingError, isTransient, isRetryable, catchCategory, catchAuthError, catchValidationError, catchNotFoundError, catchConflictError, catchThrottlingError, catchBillingError, catchTransient, } from "./categories";
46
+ export { MediaUploadError } from "../inline-attachments";
46
47
  export type { CursorPageEnvelope } from "./pagination";
47
48
  export type { Json as JsonValue } from "effect/Schema";
@@ -1,5 +1,6 @@
1
- import { C as ResourceNotFoundError, M as ValidationError, O as UnauthorizedError, S as RateLimitedError, _ as ForbiddenError, a as AnalyticsQueryError, b as OnboardingReviewRequiredError, c as CampaignFooterRequiredError, g as FlagDisabledError, h as ExternalServiceError, l as ConflictError, m as EmailChannelError, o as BillingProviderError, p as DeliveryUnavailableError, s as BrandAddressRequiredError, v as GatewayTimeoutError, x as PaymentRequiredError, y as InternalError } from "../client-8YXjfsVc.js";
2
- import { _ as isTransient, a as catchNotFoundError, c as catchValidationError, d as isAuthError, f as isBillingError, g as isThrottlingError, h as isRetryable, i as catchConflictError, l as categoriesOf, m as isNotFoundError, n as catchBillingError, o as catchThrottlingError, p as isConflictError, r as catchCategory, s as catchTransient, t as catchAuthError, u as hasCategory, v as isValidationError } from "../categories-DvsHUJtX.js";
1
+ import { t as MediaUploadError } from "../inline-attachments-B56eS0MF.js";
2
+ import { C as ResourceNotFoundError, M as ValidationError, O as UnauthorizedError, S as RateLimitedError, _ as ForbiddenError, a as AnalyticsQueryError, b as OnboardingReviewRequiredError, c as CampaignFooterRequiredError, g as FlagDisabledError, h as ExternalServiceError, l as ConflictError, m as EmailChannelError, o as BillingProviderError, p as DeliveryUnavailableError, s as BrandAddressRequiredError, v as GatewayTimeoutError, x as PaymentRequiredError, y as InternalError } from "../client-DYPNDvVU.js";
3
+ import { _ as isTransient, a as catchNotFoundError, c as catchValidationError, d as isAuthError, f as isBillingError, g as isThrottlingError, h as isRetryable, i as catchConflictError, l as categoriesOf, m as isNotFoundError, n as catchBillingError, o as catchThrottlingError, p as isConflictError, r as catchCategory, s as catchTransient, t as catchAuthError, u as hasCategory, v as isValidationError } from "../categories-Bcwq5jPV.js";
3
4
  import { t as retry_exports } from "./retry.js";
4
5
  import { t as analytics_exports } from "./analytics.js";
5
6
  import { t as api_keys_exports } from "./api-keys.js";
@@ -15,7 +16,7 @@ import { t as email_exports } from "./email.js";
15
16
  import { t as extension_installations_exports } from "./extension-installations.js";
16
17
  import { t as extensions_exports } from "./extensions.js";
17
18
  import { t as feedback_exports } from "./feedback.js";
18
- import { L as mailboxes_exports } from "../mailboxes-4gJMAJh4.js";
19
+ import { L as mailboxes_exports } from "../mailboxes-D3Kx7elM.js";
19
20
  import { t as media_exports } from "./media.js";
20
21
  import { t as messages_exports } from "./messages.js";
21
22
  import { t as namespaces_exports } from "./namespaces.js";
@@ -25,4 +26,4 @@ import { t as scheduled_messages_exports } from "./scheduled-messages.js";
25
26
  import { t as templates_exports } from "./templates.js";
26
27
  import { t as unsubscribe_groups_exports } from "./unsubscribe-groups.js";
27
28
  import { t as webhooks_exports } from "./webhooks.js";
28
- export { analytics_exports as Analytics, AnalyticsQueryError, api_keys_exports as ApiKeys, attachments_exports as Attachments, BillingProviderError, BrandAddressRequiredError, brands_exports as Brands, CampaignFooterRequiredError, campaigns_exports as Campaigns, client_exports as Client, ConflictError, contact_groups_exports as ContactGroups, contacts_exports as Contacts, conversations_exports as Conversations, custom_fields_exports as CustomFields, DeliveryUnavailableError, email_exports as Email, EmailChannelError, extension_installations_exports as ExtensionInstallations, extensions_exports as Extensions, ExternalServiceError, feedback_exports as Feedback, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, mailboxes_exports as Mailboxes, media_exports as Media, messages_exports as Messages, namespaces_exports as Namespaces, OnboardingReviewRequiredError, operations_exports as Operations, organizations_exports as Organizations, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, retry_exports as Retry, scheduled_messages_exports as ScheduledMessages, templates_exports as Templates, UnauthorizedError, unsubscribe_groups_exports as UnsubscribeGroups, ValidationError, webhooks_exports as Webhooks, catchAuthError, catchBillingError, catchCategory, catchConflictError, catchNotFoundError, catchThrottlingError, catchTransient, catchValidationError, categoriesOf, hasCategory, isAuthError, isBillingError, isConflictError, isNotFoundError, isRetryable, isThrottlingError, isTransient, isValidationError };
29
+ export { analytics_exports as Analytics, AnalyticsQueryError, api_keys_exports as ApiKeys, attachments_exports as Attachments, BillingProviderError, BrandAddressRequiredError, brands_exports as Brands, CampaignFooterRequiredError, campaigns_exports as Campaigns, client_exports as Client, ConflictError, contact_groups_exports as ContactGroups, contacts_exports as Contacts, conversations_exports as Conversations, custom_fields_exports as CustomFields, DeliveryUnavailableError, email_exports as Email, EmailChannelError, extension_installations_exports as ExtensionInstallations, extensions_exports as Extensions, ExternalServiceError, feedback_exports as Feedback, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, mailboxes_exports as Mailboxes, media_exports as Media, MediaUploadError, messages_exports as Messages, namespaces_exports as Namespaces, OnboardingReviewRequiredError, operations_exports as Operations, organizations_exports as Organizations, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, retry_exports as Retry, scheduled_messages_exports as ScheduledMessages, templates_exports as Templates, UnauthorizedError, unsubscribe_groups_exports as UnsubscribeGroups, ValidationError, webhooks_exports as Webhooks, catchAuthError, catchBillingError, catchCategory, catchConflictError, catchNotFoundError, catchThrottlingError, catchTransient, catchValidationError, categoriesOf, hasCategory, isAuthError, isBillingError, isConflictError, isNotFoundError, isRetryable, isThrottlingError, isTransient, isValidationError };
@@ -1,6 +1,7 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import { HttpApiClient } from "effect/http-api";
3
3
  import * as HttpClient from "effect/http/HttpClient";
4
+ import { MediaUploadError } from "../../inline-attachments";
4
5
  import type { MailboxEventStreamConnection } from "../../mailbox-events";
5
6
  import { SamvaApi } from "../generated";
6
7
  export interface ConfigBase {
@@ -28,6 +29,19 @@ export interface Interface {
28
29
  readonly operation: <Name extends Operation>(name: Name) => FlatRaw[Name];
29
30
  /** The origin and headers a connection outside HTTP requests, such as the event stream, uses. */
30
31
  readonly connection: MailboxEventStreamConnection;
32
+ /**
33
+ * Put bytes at a presigned storage URL through the configured transport, replaying the
34
+ * instruction's headers exactly and sending no API credentials. Fails with the response status
35
+ * (or the transport error) as `MediaUploadError`.
36
+ */
37
+ readonly putUpload: (input: {
38
+ readonly filename: string;
39
+ readonly mediaId: string;
40
+ readonly url: string;
41
+ readonly method: string;
42
+ readonly headers: Readonly<Record<string, string>>;
43
+ readonly bytes: Uint8Array;
44
+ }) => Effect.Effect<void, MediaUploadError>;
31
45
  }
32
46
  declare const Service_base: Context.ServiceClass<Service, "samva/Client", Interface>;
33
47
  export declare class Service extends Service_base {
@@ -1,4 +1,5 @@
1
1
  import { Effect, Redacted, Stream } from "effect";
2
+ import { type MediaUploadError } from "../../inline-attachments";
2
3
  import { SDK_OPERATION_CALLS } from "../../service-map";
3
4
  import { SendMessagePayload } from "../generated";
4
5
  import { type FlatRaw, type Operation, Service } from "./client";
@@ -80,6 +81,8 @@ export type EmailSendInput = Omit<EmailPayload, "channel" | "email" | "to" | "cc
80
81
  readonly cc?: ErgonomicMessageRecipient | ReadonlyArray<ErgonomicMessageRecipient>;
81
82
  readonly bcc?: ErgonomicMessageRecipient | ReadonlyArray<ErgonomicMessageRecipient>;
82
83
  };
84
+ type SendResult = MethodReturn<FlatRaw["messagesSend"]>;
85
+ type UploadFailure = MediaUploadError | Effect.Error<SendResult>;
83
86
  export declare const sendMessage: (input: MessageSendInput, options?: SendOptions | undefined) => Effect.Effect<{
84
87
  readonly id: string & import("effect/Brand").Brand<"MessageId">;
85
88
  readonly status: "bounced" | "complained" | "delivered" | "failed" | "pending" | "processing" | "queued" | "read" | "scheduled" | "sent";
@@ -91,7 +94,7 @@ export declare const sendMessage: (input: MessageSendInput, options?: SendOption
91
94
  readonly unsubscribeGroupId?: (string & import("effect/Brand").Brand<"UnsubscribeId">) | null;
92
95
  }[];
93
96
  readonly createdAt: string;
94
- }, import("..").BillingProviderError | import("..").ConflictError | import("..").DeliveryUnavailableError | import("..").ExternalServiceError | import("..").FlagDisabledError | import("..").ForbiddenError | import("..").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("..").InternalError | import("..").OnboardingReviewRequiredError | import("..").PaymentRequiredError | import("..").RateLimitedError | import("..").ResourceNotFoundError | import("effect/Schema").SchemaError | import("..").UnauthorizedError | import("..").ValidationError, Service>;
97
+ }, UploadFailure, Service>;
95
98
  export declare const sendEmail: (input: EmailSendInput, options?: SendOptions | undefined) => Effect.Effect<{
96
99
  readonly id: string & import("effect/Brand").Brand<"MessageId">;
97
100
  readonly status: "bounced" | "complained" | "delivered" | "failed" | "pending" | "processing" | "queued" | "read" | "scheduled" | "sent";
@@ -103,7 +106,7 @@ export declare const sendEmail: (input: EmailSendInput, options?: SendOptions |
103
106
  readonly unsubscribeGroupId?: (string & import("effect/Brand").Brand<"UnsubscribeId">) | null;
104
107
  }[];
105
108
  readonly createdAt: string;
106
- }, import("..").BillingProviderError | import("..").ConflictError | import("..").DeliveryUnavailableError | import("..").ExternalServiceError | import("..").FlagDisabledError | import("..").ForbiddenError | import("..").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("..").InternalError | import("..").OnboardingReviewRequiredError | import("..").PaymentRequiredError | import("..").RateLimitedError | import("..").ResourceNotFoundError | import("effect/Schema").SchemaError | import("..").UnauthorizedError | import("..").ValidationError, Service>;
109
+ }, UploadFailure, Service>;
107
110
  type AddSenderRequest = NonNullable<RequestArg<FlatRaw["emailAddSender"]>>;
108
111
  export type EmailAddSenderInput = Omit<AddSenderRequest["payload"], "replyToEmails"> & {
109
112
  readonly replyToEmails?: ErgonomicEmailList | null | undefined;
@@ -1010,7 +1010,7 @@ export declare const sendMessage: (input: {
1010
1010
  readonly unsubscribeGroupId?: (string & import("effect/Brand").Brand<"UnsubscribeId">) | null;
1011
1011
  }[];
1012
1012
  readonly createdAt: string;
1013
- }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").PaymentRequiredError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1013
+ }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").OnboardingReviewRequiredError | import("./generated").PaymentRequiredError | import("./generated").RateLimitedError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1014
1014
  export declare const getMessage: (input: {
1015
1015
  readonly id: string;
1016
1016
  readonly messageId: string;
@@ -1111,7 +1111,7 @@ export declare const reply: (input: {
1111
1111
  readonly unsubscribeGroupId?: (string & import("effect/Brand").Brand<"UnsubscribeId">) | null;
1112
1112
  }[];
1113
1113
  readonly createdAt: string;
1114
- }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").PaymentRequiredError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1114
+ }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").OnboardingReviewRequiredError | import("./generated").PaymentRequiredError | import("./generated").RateLimitedError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1115
1115
  export declare const replyAll: (input: {
1116
1116
  readonly id: string;
1117
1117
  readonly messageId: string;
@@ -1141,7 +1141,7 @@ export declare const replyAll: (input: {
1141
1141
  readonly unsubscribeGroupId?: (string & import("effect/Brand").Brand<"UnsubscribeId">) | null;
1142
1142
  }[];
1143
1143
  readonly createdAt: string;
1144
- }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").PaymentRequiredError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1144
+ }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").OnboardingReviewRequiredError | import("./generated").PaymentRequiredError | import("./generated").RateLimitedError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1145
1145
  export declare const forward: (input: {
1146
1146
  readonly id: string;
1147
1147
  readonly messageId: string;
@@ -1172,7 +1172,7 @@ export declare const forward: (input: {
1172
1172
  readonly unsubscribeGroupId?: (string & import("effect/Brand").Brand<"UnsubscribeId">) | null;
1173
1173
  }[];
1174
1174
  readonly createdAt: string;
1175
- }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").PaymentRequiredError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1175
+ }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").OnboardingReviewRequiredError | import("./generated").PaymentRequiredError | import("./generated").RateLimitedError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1176
1176
  export declare const listQuarantine: ((input: {
1177
1177
  readonly id: string;
1178
1178
  readonly limit?: string | null | undefined;
@@ -1463,7 +1463,7 @@ export declare const sendDraft: (input: {
1463
1463
  readonly unsubscribeGroupId?: (string & import("effect/Brand").Brand<"UnsubscribeId">) | null;
1464
1464
  }[];
1465
1465
  readonly createdAt: string;
1466
- }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").PaymentRequiredError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1466
+ }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").OnboardingReviewRequiredError | import("./generated").PaymentRequiredError | import("./generated").RateLimitedError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1467
1467
  export declare const listActions: ((input: {
1468
1468
  readonly id: string;
1469
1469
  readonly limit?: string | null | undefined;
@@ -1578,7 +1578,7 @@ export declare const approveAction: (input: {
1578
1578
  } | null;
1579
1579
  readonly createdAt: string;
1580
1580
  readonly updatedAt: string;
1581
- }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").PaymentRequiredError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1581
+ }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").OnboardingReviewRequiredError | import("./generated").PaymentRequiredError | import("./generated").RateLimitedError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
1582
1582
  export declare const denyAction: (input: {
1583
1583
  readonly id: string;
1584
1584
  readonly actionId: string;
@@ -1,3 +1,3 @@
1
- import { n as MailboxEventStreamError } from "../mailbox-events-CcWm8lO4.js";
2
- import { $ as updatePolicy, A as listGrants, B as remove, C as getThread, D as listDrafts, E as listActions, F as listThreadNotes, G as revokeGrant, H as reply, I as listThreads, J as update, K as sendDraft, M as listPolicies, N as listQuarantine, O as listEvents, P as listThreadMessages, Q as updateNote, R as pause, S as getPolicy, T as list, U as replyAll, V as removeThreadLabels, W as resume, X as updateGrant, Y as updateDraft, Z as updateLabel, _ as getAgentActivity, a as createGrant, b as getMessageAttachment, c as createPolicy, d as deleteNote, et as updateThread, f as deletePolicy, g as get, h as forward, i as createDraft, j as listLabels, k as listFolders, l as deleteDraft, m as discardMessage, n as approveAction, o as createLabel, p as denyAction, q as sendMessage, r as create, s as createNote, t as addThreadLabels, tt as events, u as deleteLabel, v as getDraft, w as getThreadContent, x as getMessageRaw, y as getMessage, z as releaseMessage } from "../mailboxes-4gJMAJh4.js";
1
+ import { n as MailboxEventStreamError } from "../mailbox-events-CsbF35vH.js";
2
+ import { $ as updatePolicy, A as listGrants, B as remove, C as getThread, D as listDrafts, E as listActions, F as listThreadNotes, G as revokeGrant, H as reply, I as listThreads, J as update, K as sendDraft, M as listPolicies, N as listQuarantine, O as listEvents, P as listThreadMessages, Q as updateNote, R as pause, S as getPolicy, T as list, U as replyAll, V as removeThreadLabels, W as resume, X as updateGrant, Y as updateDraft, Z as updateLabel, _ as getAgentActivity, a as createGrant, b as getMessageAttachment, c as createPolicy, d as deleteNote, et as updateThread, f as deletePolicy, g as get, h as forward, i as createDraft, j as listLabels, k as listFolders, l as deleteDraft, m as discardMessage, n as approveAction, o as createLabel, p as denyAction, q as sendMessage, r as create, s as createNote, t as addThreadLabels, tt as events, u as deleteLabel, v as getDraft, w as getThreadContent, x as getMessageRaw, y as getMessage, z as releaseMessage } from "../mailboxes-D3Kx7elM.js";
3
3
  export { MailboxEventStreamError, addThreadLabels, approveAction, create, createDraft, createGrant, createLabel, createNote, createPolicy, deleteDraft, deleteLabel, deleteNote, deletePolicy, denyAction, discardMessage, events, forward, get, getAgentActivity, getDraft, getMessage, getMessageAttachment, getMessageRaw, getPolicy, getThread, getThreadContent, list, listActions, listDrafts, listEvents, listFolders, listGrants, listLabels, listPolicies, listQuarantine, listThreadMessages, listThreadNotes, listThreads, pause, releaseMessage, remove, removeThreadLabels, reply, replyAll, resume, revokeGrant, sendDraft, sendMessage, update, updateDraft, updateGrant, updateLabel, updateNote, updatePolicy, updateThread };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { n as make } from "../operation-BuyvAsZ1.js";
2
+ import { n as make } from "../operation-B_Ty1LG-.js";
3
3
  //#region src/effect/media.ts
4
4
  var media_exports = /* @__PURE__ */ __exportAll({
5
5
  complete: () => complete,
@@ -84,7 +84,7 @@ export declare const send: (input: MessageSendInput, options?: SendOptions | und
84
84
  readonly unsubscribeGroupId?: (string & import("effect/Brand").Brand<"UnsubscribeId">) | null;
85
85
  }[];
86
86
  readonly createdAt: string;
87
- }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").DeliveryUnavailableError | import("./generated").ExternalServiceError | import("./generated").FlagDisabledError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").OnboardingReviewRequiredError | import("./generated").PaymentRequiredError | import("./generated").RateLimitedError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
87
+ }, import("./generated").BillingProviderError | import("./generated").ConflictError | import("./generated").DeliveryUnavailableError | import("./generated").ExternalServiceError | import("./generated").FlagDisabledError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("..").MediaUploadError | import("./generated").OnboardingReviewRequiredError | import("./generated").PaymentRequiredError | import("./generated").RateLimitedError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
88
88
  export declare const validateEmail: (input: {
89
89
  readonly conversationId?: string | null | undefined;
90
90
  readonly metadata?: {
@@ -208,7 +208,7 @@ export declare const validateEmail: (input: {
208
208
  readonly hasHtml: boolean;
209
209
  readonly hasText: boolean;
210
210
  };
211
- }, import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
211
+ }, import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
212
212
  export declare const get: (input: {
213
213
  readonly id: string;
214
214
  }) => import("effect/Effect").Effect<{
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { i as sendMessage, n as make } from "../operation-BuyvAsZ1.js";
2
+ import { i as sendMessage, n as make } from "../operation-B_Ty1LG-.js";
3
3
  //#region src/effect/messages.ts
4
4
  var messages_exports = /* @__PURE__ */ __exportAll({
5
5
  get: () => get,
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { n as make } from "../operation-BuyvAsZ1.js";
2
+ import { n as make } from "../operation-B_Ty1LG-.js";
3
3
  //#region src/effect/namespaces.ts
4
4
  var namespaces_exports = /* @__PURE__ */ __exportAll({
5
5
  create: () => create,
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { n as make } from "../operation-BuyvAsZ1.js";
2
+ import { n as make } from "../operation-B_Ty1LG-.js";
3
3
  //#region src/effect/operations.ts
4
4
  var operations_exports = /* @__PURE__ */ __exportAll({
5
5
  get: () => get,
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { n as make } from "../operation-BuyvAsZ1.js";
2
+ import { n as make } from "../operation-B_Ty1LG-.js";
3
3
  //#region src/effect/organizations.ts
4
4
  var organizations_exports = /* @__PURE__ */ __exportAll({
5
5
  create: () => create,
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { h as isRetryable } from "../categories-DvsHUJtX.js";
2
+ import { h as isRetryable } from "../categories-Bcwq5jPV.js";
3
3
  import { Context, Duration, Effect, Layer, Option, Random, Schedule } from "effect";
4
4
  import * as Predicate$1 from "effect/Predicate";
5
5
  //#region src/effect/retry.ts
@@ -699,4 +699,4 @@ export declare const resume: (input: {
699
699
  readonly memberRole: string;
700
700
  readonly createdAt: string;
701
701
  readonly updatedAt: string;
702
- }, import("./generated").ConflictError | import("./generated").ExternalServiceError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
702
+ }, import("./generated").ConflictError | import("./generated").ExternalServiceError | import("./generated").ForbiddenError | import("./generated").GatewayTimeoutError | import("effect/http/HttpClientError").HttpClientError | import("./generated").InternalError | import("./generated").ResourceNotFoundError | import("effect/Schema").SchemaError | import("./generated").SenderNotReadyError | import("./generated").UnauthorizedError | import("./generated").ValidationError, import("./client").Service>;
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { n as make } from "../operation-BuyvAsZ1.js";
2
+ import { n as make } from "../operation-B_Ty1LG-.js";
3
3
  //#region src/effect/scheduled-messages.ts
4
4
  var scheduled_messages_exports = /* @__PURE__ */ __exportAll({
5
5
  cancel: () => cancel,
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { n as make } from "../operation-BuyvAsZ1.js";
3
- import { A as UpdateTemplatePayload, d as CreateTemplatePayload } from "../client-8YXjfsVc.js";
2
+ import { n as make } from "../operation-B_Ty1LG-.js";
3
+ import { A as UpdateTemplatePayload, d as CreateTemplatePayload } from "../client-DYPNDvVU.js";
4
4
  //#region src/effect/templates.ts
5
5
  var templates_exports = /* @__PURE__ */ __exportAll({
6
6
  CreatePayload: () => CreateTemplatePayload,
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { n as make } from "../operation-BuyvAsZ1.js";
2
+ import { n as make } from "../operation-B_Ty1LG-.js";
3
3
  //#region src/effect/unsubscribe-groups.ts
4
4
  var unsubscribe_groups_exports = /* @__PURE__ */ __exportAll({
5
5
  addEmails: () => addEmails,
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.js";
2
- import { n as make } from "../operation-BuyvAsZ1.js";
3
- import { E as TestWebhookPayload, f as CreateWebhookPayload, j as UpdateWebhookPayload } from "../client-8YXjfsVc.js";
2
+ import { n as make } from "../operation-B_Ty1LG-.js";
3
+ import { E as TestWebhookPayload, f as CreateWebhookPayload, j as UpdateWebhookPayload } from "../client-DYPNDvVU.js";
4
4
  //#region src/effect/webhooks.ts
5
5
  var webhooks_exports = /* @__PURE__ */ __exportAll({
6
6
  CreatePayload: () => CreateWebhookPayload,
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
- import { S as fromApiError, _ as ResourceNotFoundError, a as CampaignFooterRequiredError, b as UnauthorizedError, c as EmailChannelError, d as ForbiddenError, f as GatewayTimeoutError, g as RateLimitedError, h as PaymentRequiredError, i as BrandAddressRequiredError, l as ExternalServiceError, m as OnboardingReviewRequiredError, n as AnalyticsQueryError, o as ConflictError, p as InternalError, r as BillingProviderError, s as DeliveryUnavailableError, t as createClient, u as FlagDisabledError, v as SamvaApiError, x as ValidationError, y as SamvaTransportError } from "./promises-CqAmI39P.js";
2
- import { n as MailboxEventStreamError, t as MailboxEventStream } from "./mailbox-events-CcWm8lO4.js";
3
- export { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, MailboxEventStream, MailboxEventStreamError, OnboardingReviewRequiredError, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, SamvaApiError, SamvaTransportError, UnauthorizedError, ValidationError, createClient, fromApiError };
1
+ import { t as MediaUploadError } from "./inline-attachments-B56eS0MF.js";
2
+ import { C as fromApiError, S as ValidationError, _ as ResourceNotFoundError, a as CampaignFooterRequiredError, b as SenderNotReadyError, c as EmailChannelError, d as ForbiddenError, f as GatewayTimeoutError, g as RateLimitedError, h as PaymentRequiredError, i as BrandAddressRequiredError, l as ExternalServiceError, m as OnboardingReviewRequiredError, n as AnalyticsQueryError, o as ConflictError, p as InternalError, r as BillingProviderError, s as DeliveryUnavailableError, t as createClient, u as FlagDisabledError, v as SamvaApiError, x as UnauthorizedError, y as SamvaTransportError } from "./promises-D9FJyU0q.js";
3
+ import { n as MailboxEventStreamError, t as MailboxEventStream } from "./mailbox-events-CsbF35vH.js";
4
+ export { AnalyticsQueryError, BillingProviderError, BrandAddressRequiredError, CampaignFooterRequiredError, ConflictError, DeliveryUnavailableError, EmailChannelError, ExternalServiceError, FlagDisabledError, ForbiddenError, GatewayTimeoutError, InternalError, MailboxEventStream, MailboxEventStreamError, MediaUploadError, OnboardingReviewRequiredError, PaymentRequiredError, RateLimitedError, ResourceNotFoundError, SamvaApiError, SamvaTransportError, SenderNotReadyError, UnauthorizedError, ValidationError, createClient, fromApiError };
@@ -0,0 +1,121 @@
1
+ //#endregion
2
+ //#region src/client-attribution.ts
3
+ const SDK_VERSION = "0.13.0";
4
+ const CLIENT_ATTRIBUTION_HEADER = "x-samva-client";
5
+ const clientAttribution = (surface) => `${surface}/${SDK_VERSION}`;
6
+ /** A failed upload of an attachment's bytes to its presigned media URL. */
7
+ var MediaUploadError = class extends Error {
8
+ _tag = "MediaUploadError";
9
+ /** The attachment filename the upload was for. */
10
+ filename;
11
+ mediaId;
12
+ /** The storage response status, absent when the request never completed. */
13
+ status;
14
+ cause;
15
+ constructor(input) {
16
+ super(input.status === void 0 ? `Uploading attachment "${input.filename}" (${input.mediaId}) failed before storage answered` : `Uploading attachment "${input.filename}" (${input.mediaId}) failed with storage status ${input.status}`, { cause: input.cause });
17
+ this.name = "MediaUploadError";
18
+ this.filename = input.filename;
19
+ this.mediaId = input.mediaId;
20
+ this.status = input.status;
21
+ this.cause = input.cause;
22
+ }
23
+ };
24
+ const isRecord = (value) => typeof value === "object" && value !== null;
25
+ const attachmentsOf = (payload) => {
26
+ const email = payload.email;
27
+ if (!isRecord(email)) return [];
28
+ const attachments = email.attachments;
29
+ return Array.isArray(attachments) ? attachments : [];
30
+ };
31
+ /** Decoded byte length of a Base64 string, without decoding it. */
32
+ const decodedBase64Bytes = (content) => {
33
+ const length = content.length;
34
+ if (length === 0) return 0;
35
+ let padding = 0;
36
+ if (content.endsWith("==")) padding = 2;
37
+ else if (content.endsWith("=")) padding = 1;
38
+ return Math.floor(length * 3 / 4) - padding;
39
+ };
40
+ /** The bytes `content` encodes, or `undefined` when it is not Base64. */
41
+ const base64ToBytes = (content) => {
42
+ let binary;
43
+ try {
44
+ binary = atob(content);
45
+ } catch {
46
+ return;
47
+ }
48
+ const bytes = new Uint8Array(binary.length);
49
+ for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
50
+ return bytes;
51
+ };
52
+ /**
53
+ * The inline attachments to upload so the rest fit under {@link INLINE_ATTACHMENT_MAX_BYTES}:
54
+ * largest first, stopping as soon as the remaining inline total is within the cap. Empty when the
55
+ * request is already within the cap, carries no inline content, or carries content that is not
56
+ * Base64: nothing is uploaded for a request the API will refuse, and its 422 names the attachment.
57
+ */
58
+ const planInlineUploads = (payload) => {
59
+ const inline = [];
60
+ for (const [index, entry] of attachmentsOf(payload).entries()) {
61
+ if (!isRecord(entry)) continue;
62
+ const attachment = entry;
63
+ if (typeof attachment.content !== "string") continue;
64
+ if (attachment.mediaId !== void 0) return [];
65
+ inline.push({
66
+ index,
67
+ filename: typeof attachment.filename === "string" ? attachment.filename : "attachment",
68
+ contentType: typeof attachment.contentType === "string" ? attachment.contentType : "application/octet-stream",
69
+ content: attachment.content,
70
+ sizeBytes: typeof attachment.size === "number" ? attachment.size : decodedBase64Bytes(attachment.content)
71
+ });
72
+ }
73
+ let remaining = inline.reduce((total, upload) => total + upload.sizeBytes, 0);
74
+ if (remaining <= 4194304) return [];
75
+ const chosen = [];
76
+ const largestFirst = [...inline].sort((left, right) => right.sizeBytes - left.sizeBytes || left.index - right.index);
77
+ for (const { content, ...upload } of largestFirst) {
78
+ if (remaining <= 4194304) break;
79
+ const bytes = base64ToBytes(content);
80
+ if (bytes === void 0) return [];
81
+ chosen.push({
82
+ ...upload,
83
+ bytes
84
+ });
85
+ remaining -= upload.sizeBytes;
86
+ }
87
+ return chosen;
88
+ };
89
+ /** The `POST /v1/media` body for an inline attachment. */
90
+ const mediaCreateBody = (upload) => ({
91
+ filename: upload.filename,
92
+ contentType: upload.contentType,
93
+ sizeBytes: upload.sizeBytes,
94
+ purpose: "attachment"
95
+ });
96
+ /** The `Content-Type` of the presigned request, for clients that set it from the body. */
97
+ const uploadContentType = (headers) => Object.entries(headers).find(([name]) => name.toLowerCase() === "content-type")?.[1];
98
+ /** Replace each uploaded attachment with its `mediaId` form; everything else is untouched. */
99
+ const withUploadedAttachments = (payload, uploaded) => {
100
+ const email = payload.email;
101
+ const attachments = email.attachments.map((entry, index) => {
102
+ const replacement = uploaded.get(index);
103
+ if (replacement === void 0) return entry;
104
+ const { content: _content, ...rest } = entry;
105
+ return {
106
+ ...rest,
107
+ mediaId: replacement.mediaId
108
+ };
109
+ });
110
+ return {
111
+ ...payload,
112
+ email: {
113
+ ...email,
114
+ attachments
115
+ }
116
+ };
117
+ };
118
+ //#endregion
119
+ export { withUploadedAttachments as a, uploadContentType as i, mediaCreateBody as n, CLIENT_ATTRIBUTION_HEADER as o, planInlineUploads as r, clientAttribution as s, MediaUploadError as t };
120
+
121
+ //# sourceMappingURL=inline-attachments-B56eS0MF.js.map
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Shared, pure planning for email sends whose inline attachments exceed the API's inline cap.
3
+ *
4
+ * The API accepts a bounded number of decoded bytes as Base64 `content` per request (larger files
5
+ * travel as owned media and are referenced by `mediaId`). Both clients call these helpers to decide
6
+ * which inline attachments to upload through media before the single send request, so the choice
7
+ * cannot drift between them. No Effect, no I/O.
8
+ */
9
+ /** Decoded bytes of inline attachment `content` one send request may carry. */
10
+ export declare const INLINE_ATTACHMENT_MAX_BYTES: number;
11
+ /** A failed upload of an attachment's bytes to its presigned media URL. */
12
+ export declare class MediaUploadError extends Error {
13
+ readonly _tag: "MediaUploadError";
14
+ /** The attachment filename the upload was for. */
15
+ readonly filename: string;
16
+ readonly mediaId: string;
17
+ /** The storage response status, absent when the request never completed. */
18
+ readonly status: number | undefined;
19
+ readonly cause: unknown;
20
+ constructor(input: {
21
+ readonly filename: string;
22
+ readonly mediaId: string;
23
+ readonly status?: number | undefined;
24
+ readonly cause?: unknown;
25
+ });
26
+ }
27
+ /** One inline attachment chosen for upload. */
28
+ export interface InlineUpload {
29
+ /** Position in `email.attachments`. */
30
+ readonly index: number;
31
+ readonly filename: string;
32
+ readonly contentType: string;
33
+ /** The decoded `content`, the bytes put to storage. */
34
+ readonly bytes: Uint8Array;
35
+ /** The attachment's declared `size`, the bytes the API charges against the inline cap. */
36
+ readonly sizeBytes: number;
37
+ }
38
+ /** The presigned request `POST /v1/media` returns for putting the bytes into storage. */
39
+ export interface UploadInstruction {
40
+ readonly url: string;
41
+ readonly headers: Readonly<Record<string, string>>;
42
+ }
43
+ /** Decoded byte length of a Base64 string, without decoding it. */
44
+ export declare const decodedBase64Bytes: (content: string) => number;
45
+ /**
46
+ * The inline attachments to upload so the rest fit under {@link INLINE_ATTACHMENT_MAX_BYTES}:
47
+ * largest first, stopping as soon as the remaining inline total is within the cap. Empty when the
48
+ * request is already within the cap, carries no inline content, or carries content that is not
49
+ * Base64: nothing is uploaded for a request the API will refuse, and its 422 names the attachment.
50
+ */
51
+ export declare const planInlineUploads: (payload: Record<string, unknown>) => ReadonlyArray<InlineUpload>;
52
+ /** The `POST /v1/media` body for an inline attachment. */
53
+ export declare const mediaCreateBody: (upload: InlineUpload) => {
54
+ filename: string;
55
+ contentType: string;
56
+ sizeBytes: number;
57
+ purpose: "attachment";
58
+ };
59
+ /** The `Content-Type` of the presigned request, for clients that set it from the body. */
60
+ export declare const uploadContentType: (headers: Readonly<Record<string, string>>) => string | undefined;
61
+ /** Replace each uploaded attachment with its `mediaId` form; everything else is untouched. */
62
+ export declare const withUploadedAttachments: (payload: Record<string, unknown>, uploaded: ReadonlyMap<number, {
63
+ readonly mediaId: string;
64
+ readonly upload: InlineUpload;
65
+ }>) => Record<string, unknown>;
@@ -88,12 +88,17 @@ const RETRY_AFTER_MAX_MILLIS = 3e5;
88
88
  const REFUSAL_BODY_LIMIT = 65536;
89
89
  /** The longest the diagnosing request and its body may take before the refusal is treated as retryable. */
90
90
  const DIAGNOSE_TIMEOUT_MILLIS = 1e4;
91
+ /** The frame that asks the events host whether the connection is alive; pinned to the host's by a test. */
92
+ const MAILBOX_EVENT_STREAM_PING_FRAME = "{\"kind\":\"ping\"}";
93
+ /** How often the stream sends a ping; pinned to the host's constant by a test. */
94
+ const MAILBOX_EVENT_STREAM_PING_MILLIS = 3e4;
91
95
  /**
92
- * How long a connection may stay silent before it is treated as dropped: three heartbeat
93
- * intervals, so one late or lost heartbeat does not reconnect. A socket that died without a close
94
- * event is otherwise indistinguishable from a quiet mailbox.
96
+ * How long a connection may stay silent before it is treated as dropped: three ping intervals, so
97
+ * one late or lost pong does not reconnect. The host sends nothing on a quiet mailbox, so the
98
+ * pong is the only proof of life; a socket that died without a close event is otherwise
99
+ * indistinguishable from a quiet mailbox.
95
100
  */
96
- const MAILBOX_EVENT_STREAM_IDLE_MILLIS = 9e4;
101
+ const MAILBOX_EVENT_STREAM_IDLE_MILLIS = 3 * MAILBOX_EVENT_STREAM_PING_MILLIS;
97
102
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
98
103
  const frameText = (raw) => {
99
104
  if (typeof raw === "string") return raw;
@@ -108,8 +113,9 @@ const decodeFrame = (raw) => {
108
113
  } catch {
109
114
  return;
110
115
  }
116
+ if (isRecord(parsed) && parsed.kind === "pong") return { kind: "pong" };
111
117
  if (!isRecord(parsed) || typeof parsed.cursor !== "string") return void 0;
112
- if (parsed.kind === "live" || parsed.kind === "heartbeat") return {
118
+ if (parsed.kind === "live" || parsed.kind === "progress") return {
113
119
  kind: parsed.kind,
114
120
  cursor: parsed.cursor
115
121
  };
@@ -452,6 +458,7 @@ var MailboxEventStream = class {
452
458
  let opened = false;
453
459
  let settled = false;
454
460
  let idleTimer;
461
+ let pingTimer;
455
462
  const armIdle = () => {
456
463
  clearTimeout(idleTimer);
457
464
  idleTimer = setTimeout(() => {
@@ -466,6 +473,7 @@ var MailboxEventStream = class {
466
473
  if (settled) return;
467
474
  settled = true;
468
475
  clearTimeout(idleTimer);
476
+ clearInterval(pingTimer);
469
477
  this.#stop.signal.removeEventListener("abort", onStop);
470
478
  if (this.#socket === socket) this.#socket = void 0;
471
479
  resolve(result);
@@ -487,6 +495,9 @@ var MailboxEventStream = class {
487
495
  armIdle();
488
496
  socket.addEventListener("open", () => {
489
497
  opened = true;
498
+ pingTimer = setInterval(() => {
499
+ if (socket.readyState === OPEN) socket.send(MAILBOX_EVENT_STREAM_PING_FRAME);
500
+ }, MAILBOX_EVENT_STREAM_PING_MILLIS);
490
501
  });
491
502
  socket.addEventListener("message", (message) => {
492
503
  if (this.#ended) return;
@@ -501,6 +512,7 @@ var MailboxEventStream = class {
501
512
  socket.close(1e3);
502
513
  return;
503
514
  }
515
+ if (frame.kind === "pong") return;
504
516
  if (frame.kind === "event") {
505
517
  this.#queue.push({
506
518
  cursor: frame.cursor,
@@ -614,4 +626,4 @@ const readRefusalBody = async (response) => {
614
626
  //#endregion
615
627
  export { MailboxEventStreamError as n, MailboxEventStream as t };
616
628
 
617
- //# sourceMappingURL=mailbox-events-CcWm8lO4.js.map
629
+ //# sourceMappingURL=mailbox-events-CsbF35vH.js.map
@@ -139,12 +139,15 @@ export interface MailboxEventStreamConnection {
139
139
  readonly headers: Readonly<Record<string, string>>;
140
140
  readonly fetch?: typeof fetch | undefined;
141
141
  }
142
- /** How often the events host sends a heartbeat frame; pinned to the host's constant by a test. */
143
- export declare const MAILBOX_EVENT_STREAM_HEARTBEAT_MILLIS = 30000;
142
+ /** The frame that asks the events host whether the connection is alive; pinned to the host's by a test. */
143
+ export declare const MAILBOX_EVENT_STREAM_PING_FRAME = "{\"kind\":\"ping\"}";
144
+ /** How often the stream sends a ping; pinned to the host's constant by a test. */
145
+ export declare const MAILBOX_EVENT_STREAM_PING_MILLIS = 30000;
144
146
  /**
145
- * How long a connection may stay silent before it is treated as dropped: three heartbeat
146
- * intervals, so one late or lost heartbeat does not reconnect. A socket that died without a close
147
- * event is otherwise indistinguishable from a quiet mailbox.
147
+ * How long a connection may stay silent before it is treated as dropped: three ping intervals, so
148
+ * one late or lost pong does not reconnect. The host sends nothing on a quiet mailbox, so the
149
+ * pong is the only proof of life; a socket that died without a close event is otherwise
150
+ * indistinguishable from a quiet mailbox.
148
151
  */
149
152
  export declare const MAILBOX_EVENT_STREAM_IDLE_MILLIS: number;
150
153
  /** The events URL for an API origin: `https://api.samva.dev` → `wss://events.samva.dev/v1/…`. */
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { n as MailboxEventStreamError, t as MailboxEventStream } from "./mailbox-events-CcWm8lO4.js";
3
- import { n as make } from "./operation-BuyvAsZ1.js";
4
- import { t as Service } from "./client-8YXjfsVc.js";
2
+ import { n as MailboxEventStreamError, t as MailboxEventStream } from "./mailbox-events-CsbF35vH.js";
3
+ import { n as make } from "./operation-B_Ty1LG-.js";
4
+ import { t as Service } from "./client-DYPNDvVU.js";
5
5
  import { Cause, Effect, Exit, Stream } from "effect";
6
6
  //#region src/effect/internal/mailbox-events.ts
7
7
  const toStreamError = (cause) => cause instanceof MailboxEventStreamError ? cause : new MailboxEventStreamError({
@@ -144,4 +144,4 @@ const listEvents = make("mailboxesListEvents");
144
144
  //#endregion
145
145
  export { updatePolicy as $, listGrants as A, remove as B, getThread as C, listDrafts as D, listActions as E, listThreadNotes as F, revokeGrant as G, reply as H, listThreads as I, update as J, sendDraft as K, mailboxes_exports as L, listPolicies as M, listQuarantine as N, listEvents as O, listThreadMessages as P, updateNote as Q, pause as R, getPolicy as S, list as T, replyAll as U, removeThreadLabels as V, resume as W, updateGrant as X, updateDraft as Y, updateLabel as Z, getAgentActivity as _, createGrant as a, getMessageAttachment as b, createPolicy as c, deleteNote as d, updateThread as et, deletePolicy as f, get as g, forward as h, createDraft as i, listLabels as j, listFolders as k, deleteDraft as l, discardMessage as m, approveAction as n, createLabel as o, denyAction as p, sendMessage as q, create as r, createNote as s, addThreadLabels as t, events as tt, deleteLabel as u, getDraft as v, getThreadContent as w, getMessageRaw as x, getMessage as y, releaseMessage as z };
146
146
 
147
- //# sourceMappingURL=mailboxes-4gJMAJh4.js.map
147
+ //# sourceMappingURL=mailboxes-D3Kx7elM.js.map