mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-07 01:21:37 +00:00
Track readable content revisions and durable read cursors in the hub. Acknowledge only rendered foreground tails, persist offline read operations, and preserve newer manual unread choices across devices. Migrate existing history to a read baseline and cover pagination receipts with shared native conformance fixtures.
73 lines
2.4 KiB
Swift
73 lines
2.4 KiB
Swift
import Foundation
|
|
|
|
/// Cursor block of a `GET /api/sessions/:id/messages` response.
|
|
///
|
|
/// Mirrors `MessagesResponse['page']` (`shared/src/apiTypes.ts`); full cursor
|
|
/// semantics in `docs/api/client-contract/pagination.md`. Every cursor is a
|
|
/// `(seq, at)` pair — both halves travel together.
|
|
public struct MessagesPage: Codable, Equatable, Sendable {
|
|
public enum Direction: String, Codable, Sendable {
|
|
case latest
|
|
case before
|
|
case after
|
|
}
|
|
|
|
public var readThroughRevision: Int?
|
|
public var direction: Direction
|
|
public var limit: Int
|
|
/// Server's current epoch for this session; a mismatch on your next
|
|
/// `after` request yields a `reset: true` latest page.
|
|
public var epoch: Int
|
|
/// `true` ⇒ discard the local window, this page replaces it.
|
|
public var reset: Bool
|
|
public var nextBeforeSeq: Int?
|
|
public var nextBeforeAt: Int?
|
|
public var nextAfterSeq: Int?
|
|
public var nextAfterAt: Int?
|
|
/// Newest position at snapshot time (inclusive catch-up bound).
|
|
public var snapshotHeadSeq: Int?
|
|
public var snapshotHeadAt: Int?
|
|
/// More rows exist in the requested direction.
|
|
public var hasMore: Bool
|
|
|
|
public init(
|
|
readThroughRevision: Int? = nil,
|
|
direction: Direction,
|
|
limit: Int,
|
|
epoch: Int,
|
|
reset: Bool,
|
|
nextBeforeSeq: Int? = nil,
|
|
nextBeforeAt: Int? = nil,
|
|
nextAfterSeq: Int? = nil,
|
|
nextAfterAt: Int? = nil,
|
|
snapshotHeadSeq: Int? = nil,
|
|
snapshotHeadAt: Int? = nil,
|
|
hasMore: Bool
|
|
) {
|
|
self.readThroughRevision = readThroughRevision
|
|
self.direction = direction
|
|
self.limit = limit
|
|
self.epoch = epoch
|
|
self.reset = reset
|
|
self.nextBeforeSeq = nextBeforeSeq
|
|
self.nextBeforeAt = nextBeforeAt
|
|
self.nextAfterSeq = nextAfterSeq
|
|
self.nextAfterAt = nextAfterAt
|
|
self.snapshotHeadSeq = snapshotHeadSeq
|
|
self.snapshotHeadAt = snapshotHeadAt
|
|
self.hasMore = hasMore
|
|
}
|
|
}
|
|
|
|
/// Envelope of `GET /api/sessions/:id/messages`.
|
|
public struct MessagesResponse: Codable, Equatable, Sendable {
|
|
/// Ascending display order.
|
|
public var messages: [DecryptedMessage]
|
|
public var page: MessagesPage
|
|
|
|
public init(messages: [DecryptedMessage], page: MessagesPage) {
|
|
self.messages = messages
|
|
self.page = page
|
|
}
|
|
}
|