Fold a push's follow-up requests together (#393)
A pushed mail change took three round trips: Email/changes beside a Mailbox/get, then Email/get for what changed, then the list, the open thread and a second Mailbox/get. Each page of changes now carries its own Email/get calls by back-reference, and the one Mailbox/get goes out with it, so a push settles in two. New mail fetched this way is not asked for again by the notice. A reply's sessionState that differs from the session is announced once rather than on every reply, and session refreshes in flight are shared. The mock's session state now matches the sessionState on its replies, as Stalwart's does; tying it to the data counter made every reply trigger a session refresh in development.
This commit is contained in:
@@ -104,6 +104,8 @@ export class JmapClient {
|
||||
private callCounter = 0;
|
||||
private unauthHandlers = new Set<() => void>();
|
||||
private stateHandlers = new Set<(sessionState: string) => void>();
|
||||
/** The last session state announced, so a burst of replies announces it once. */
|
||||
private announcedState: string | null = null;
|
||||
|
||||
get maxCallsInRequest(): number {
|
||||
const core = this.session?.capabilities[CAP.core] as { maxCallsInRequest?: number } | undefined;
|
||||
@@ -255,7 +257,8 @@ export class JmapClient {
|
||||
const body: Record<string, unknown> = { using: this.supportedUsing(using), methodCalls };
|
||||
if (createdIds) body.createdIds = createdIds;
|
||||
const res = await apiFetch<JmapResponse>("/api/jmap", { method: "POST", body: JSON.stringify(body) });
|
||||
if (res.sessionState && this.session && res.sessionState !== this.session.state) {
|
||||
if (res.sessionState && this.session && res.sessionState !== this.session.state && res.sessionState !== this.announcedState) {
|
||||
this.announcedState = res.sessionState;
|
||||
for (const fn of this.stateHandlers) fn(res.sessionState);
|
||||
}
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user