Skip to content

Commit 36128eb

Browse files
Added missing documentation to WebPushManager
1 parent 3ef7f24 commit 36128eb

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

.spi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
version: 1
22
builder:
33
configs:
4-
- documentation_targets: [WebPush]
4+
- documentation_targets: [WebPush, WebPushTesting]

Sources/WebPush/WebPushManager.swift

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,47 @@ import NIOCore
1515
import NIOPosix
1616
import ServiceLifecycle
1717

18+
/// A manager for sending push messages to subscribers.
19+
///
20+
/// You should instantiate and keep a reference to a single manager, passing a reference as a dependency to requests and other controllers that need to send messages. This is because the manager has an internal cache for managing connections to push services.
21+
///
22+
/// The manager should be installed as a service to wait for any in-flight messages to be sent before your application server shuts down.
1823
public actor WebPushManager: Sendable {
24+
/// The VAPID configuration used when configuring the manager.
1925
public let vapidConfiguration: VAPID.Configuration
2026

2127
/// The maximum encrypted payload size guaranteed by the spec.
28+
///
29+
/// Currently the spec guarantees up to 4,096 encrypted bytes will always be successfull.
30+
///
31+
/// - Note: _Some_, but not all, push services allow an effective encrypted message size that is larger than this, as they misinterpreted the 4096 maximum payload size as the plaintext maximum size, and support the larger size to this day. This library will however warn if this threshold is surpassed and attempt sending the message anyways — it is up to the caller to make sure messages over this size are not regularly attempted, and for fallback mechanisms to be put in place should push result in an error.
2232
public static let maximumEncryptedPayloadSize = 4096
2333

2434
/// The maximum message size allowed.
35+
///
36+
/// This is currently set to 3,993 plaintext bytes. See the discussion for ``maximumEncryptedPayloadSize`` for more information.
2537
public static let maximumMessageSize = maximumEncryptedPayloadSize - 103
2638

39+
/// The internal logger to use when reporting status.
2740
nonisolated let logger: Logger
41+
42+
/// The internal executor to use when delivering messages.
2843
var executor: Executor
2944

45+
/// An internal lookup of keys as provided by the VAPID configuration.
3046
let vapidKeyLookup: [VAPID.Key.ID : VAPID.Key]
47+
48+
/// An internal cache of `Authorization` header values for a combination of endpoint origin and VAPID key ID.
49+
/// - SeeAlso: ``loadCurrentVAPIDAuthorizationHeader(endpoint:signingKey:)``
3150
var vapidAuthorizationCache: [String : (authorization: String, validUntil: Date)] = [:]
3251

52+
/// Initialize a manager with a VAPID configuration.
53+
///
54+
/// - Note: On debug builds, this initializer will assert if VAPID authorization header expiration times are inconsistently set.
55+
/// - Parameters:
56+
/// - vapidConfiguration: The VAPID configuration to use when identifying the application server.
57+
/// - logger: An optional parent logger to use for status updates.
58+
/// - eventLoopGroupProvider: The event loop to use for the internal HTTP client.
3359
public init(
3460
vapidConfiguration: VAPID.Configuration,
3561
// TODO: Add networkConfiguration for proxy, number of simultaneous pushes, etc…
@@ -63,8 +89,12 @@ public actor WebPushManager: Sendable {
6389
}
6490

6591
/// Internal method to install a different executor for mocking.
66-
///
92+
///
6793
/// Note that this must be called before ``run()`` is called or the client's syncShutdown won't be called.
94+
/// - Parameters:
95+
/// - vapidConfiguration: The VAPID configuration to use when identifying the application server.
96+
/// - logger: The logger to use for status updates.
97+
/// - executor: The executor to use when sending push messages.
6898
package init(
6999
vapidConfiguration: VAPID.Configuration,
70100
// TODO: Add networkConfiguration for proxy, number of simultaneous pushes, etc…
@@ -401,7 +431,7 @@ public actor WebPushManager: Sendable {
401431
switch response.status {
402432
case .created: break
403433
case .notFound, .gone: throw BadSubscriberError()
404-
// TODO: 413 payload too large - warn and throw error
434+
// TODO: 413 payload too large - log.error and throw error
405435
// TODO: 429 too many requests, 500 internal server error, 503 server shutting down - check config and perform a retry after a delay?
406436
default: throw HTTPError(response: response)
407437
}
@@ -520,6 +550,7 @@ extension WebPushManager {
520550
///
521551
/// - SeeAlso: [RFC 8030 Generic Event Delivery Using HTTP §5.3. Push Message Urgency](https://datatracker.ietf.org/doc/html/rfc8030#section-5.3)
522552
public struct Urgency: Hashable, Comparable, Sendable, CustomStringConvertible {
553+
/// The internal raw value that is encoded in this type's place when calling ``description``.
523554
let rawValue: String
524555

525556
/// An urgency intended only for devices on power and Wi-Fi.
@@ -542,6 +573,7 @@ extension WebPushManager {
542573
/// For instance, high ugency messages are ideal for incoming phone calls or time-sensitive alerts.
543574
public static let high = Self(rawValue: "high")
544575

576+
/// An internal sort order for urgencies.
545577
@usableFromInline
546578
var comparableValue: Int {
547579
switch self {
@@ -577,11 +609,17 @@ extension WebPushManager.Urgency: Codable {
577609
// MARK: - Package Types
578610

579611
extension WebPushManager {
612+
/// An internal type representing a push message, accessible when using ``/WebPushTesting``.
580613
public enum _Message: Sendable {
614+
/// A message originally sent via ``WebPushManager/send(data:to:expiration:urgency:)``
581615
case data(Data)
616+
617+
/// A message originally sent via ``WebPushManager/send(string:to:expiration:urgency:)``
582618
case string(String)
619+
/// A message originally sent via ``WebPushManager/send(json:to:expiration:urgency:)
583620
case json(any Encodable&Sendable)
584621

622+
/// The message, encoded as data.
585623
var data: Data {
586624
get throws {
587625
switch self {
@@ -599,8 +637,16 @@ extension WebPushManager {
599637
}
600638
}
601639

640+
/// An internal type representing the executor for a push message.
602641
package enum Executor: Sendable {
642+
/// Use an HTTP client to send an encrypted payload to a subscriber.
643+
///
644+
/// This is used in tests to capture the encrypted request and make sure it is well-formed.
603645
case httpClient(any HTTPClientProtocol)
646+
647+
/// Use a handler to capture the original message.
648+
///
649+
/// This is used by ``/WebPushTesting`` to allow mocking a ``WebPushManager``.
604650
case handler(@Sendable (
605651
_ message: _Message,
606652
_ subscriber: Subscriber,

Sources/WebPushTesting/WebPushManager+Testing.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Logging
1010
import WebPush
1111

1212
extension WebPushManager {
13+
/// A push message in its original form, either ``/Foundation/Data``, ``/Swift/String``, or ``/Foundation/Encodable``.
1314
public typealias Message = _Message
1415

1516
/// Create a mocked web push manager.

0 commit comments

Comments
 (0)