debounce subscription syncing
All checks were successful
CI / lint-check-build (pull_request) Successful in 4m4s
All checks were successful
CI / lint-check-build (pull_request) Successful in 4m4s
This commit is contained in:
parent
cbba1035e7
commit
d6f0e47edf
1 changed files with 57 additions and 37 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import {hash, maybe, spec, throttle} from "@welshman/lib"
|
import {call, hash, maybe, spec, throttle} from "@welshman/lib"
|
||||||
import type {Filter} from "@welshman/util"
|
import type {Filter} from "@welshman/util"
|
||||||
import {Address, DELETE, MESSAGE, makeEvent, makeHttpAuth, makeHttpAuthHeader} from "@welshman/util"
|
import {Address, DELETE, MESSAGE, makeEvent, makeHttpAuth, makeHttpAuthHeader} from "@welshman/util"
|
||||||
import {merged} from "@welshman/store"
|
import {merged} from "@welshman/store"
|
||||||
|
|
@ -75,12 +75,22 @@ const syncRelaySubscriptionsForEmail = (
|
||||||
export class MailNotifications {
|
export class MailNotifications {
|
||||||
_controller = maybe<AbortController>()
|
_controller = maybe<AbortController>()
|
||||||
|
|
||||||
|
// In-flight register promise, so overlapping calls (settings page submit plus
|
||||||
|
// Mail.sync) coalesce into a single PUT instead of racing two subscriptions.
|
||||||
|
_register = maybe<Promise<void>>()
|
||||||
|
|
||||||
async register(email: string, frequency: string) {
|
async register(email: string, frequency: string) {
|
||||||
|
if (this._register) return this._register
|
||||||
|
|
||||||
|
this._register = call(async () => {
|
||||||
|
try {
|
||||||
const $user = User.require(app.get())
|
const $user = User.require(app.get())
|
||||||
const $signer = $user.signer
|
const $signer = $user.signer
|
||||||
|
|
||||||
if (!$signer) {
|
if (!$signer) {
|
||||||
emailNotificationState.set({error: "No signer available. Check your browser extension."})
|
emailNotificationState.set({
|
||||||
|
error: "No signer available. Check your browser extension.",
|
||||||
|
})
|
||||||
throw new Error("No signer available")
|
throw new Error("No signer available")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,7 +103,9 @@ export class MailNotifications {
|
||||||
try {
|
try {
|
||||||
authEvent = await $signer.sign(await makeHttpAuth(EMAIL_NOTIFICATION_SERVER, "PUT"))
|
authEvent = await $signer.sign(await makeHttpAuth(EMAIL_NOTIFICATION_SERVER, "PUT"))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emailNotificationState.set({error: "Failed to create authentication. Check your signer."})
|
emailNotificationState.set({
|
||||||
|
error: "Failed to create authentication. Check your signer.",
|
||||||
|
})
|
||||||
throw new Error("Failed to sign NIP-98 auth", {cause: e})
|
throw new Error("Failed to sign NIP-98 auth", {cause: e})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +119,9 @@ export class MailNotifications {
|
||||||
headers: {Authorization: authHeader, "Content-Type": "application/json"},
|
headers: {Authorization: authHeader, "Content-Type": "application/json"},
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emailNotificationState.set({error: `Could not reach email server. Check your connection.`})
|
emailNotificationState.set({
|
||||||
|
error: `Could not reach email server. Check your connection.`,
|
||||||
|
})
|
||||||
throw new Error("Network error", {cause: e})
|
throw new Error("Network error", {cause: e})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,6 +133,12 @@ export class MailNotifications {
|
||||||
|
|
||||||
const {key, callback} = await res.json()
|
const {key, callback} = await res.json()
|
||||||
emailNotificationState.set({key, callback, email, frequency, error: undefined})
|
emailNotificationState.set({key, callback, email, frequency, error: undefined})
|
||||||
|
} finally {
|
||||||
|
this._register = undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return this._register
|
||||||
}
|
}
|
||||||
|
|
||||||
async unregister() {
|
async unregister() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue