Handle hot module unloading in layout

This commit is contained in:
Jon Staab
2025-10-21 08:27:30 -07:00
parent 7476767aa7
commit ecbb3086d8
8 changed files with 262 additions and 285 deletions
+1 -1
View File
@@ -113,7 +113,7 @@ export const makeFeed = ({
onScroll: async () => {
const $buffer = get(buffer)
events.update($events => [...$events, ...$buffer.splice(0, 100)])
events.update($events => [...$events, ...$buffer.splice(0, 30)])
if ($buffer.length < 100) {
ctrl.load(100)
+1 -1
View File
@@ -349,7 +349,7 @@ export const {
// Relays sending events with empty signatures that the user has to choose to trust
export const relaysPendingTrust = writable<string[]>([])
export const relaysPendingTrust = withGetter(writable<string[]>([]))
// Relays that mostly send restricted responses to requests and events
+1 -2
View File
@@ -11,10 +11,9 @@ w.plausible =
;(w.plausible.q = w.plausible.q || []).push(arguments)
}
export const setupAnalytics = () => {
export const setupAnalytics = () =>
page.subscribe($page => {
if ($page.route && getSetting("report_usage")) {
w.plausible("pageview", {u: $page.route.id})
}
})
}
+1 -2
View File
@@ -2,10 +2,9 @@ import {page} from "$app/stores"
export const lastPageBySpaceUrl = new Map<string, string>()
export const setupHistory = () => {
export const setupHistory = () =>
page.subscribe($page => {
if ($page.params.relay) {
lastPageBySpaceUrl.set($page.params.relay, $page.url.pathname)
}
})
}
+123
View File
@@ -0,0 +1,123 @@
import {on, call, dissoc, assoc, uniq} from "@welshman/lib"
import type {StampedEvent} from "@welshman/util"
import type {Socket, RelayMessage, ClientMessage} from "@welshman/net"
import {
makeSocketPolicyAuth,
SocketEvent,
isRelayEvent,
isRelayOk,
isRelayClosed,
isClientReq,
isClientEvent,
isClientClose,
} from "@welshman/net"
import {signer} from "@welshman/app"
import {
userSettingsValues,
getSetting,
relaysPendingTrust,
relaysMostlyRestricted,
} from "@app/core/state"
export const authPolicy = makeSocketPolicyAuth({
sign: (event: StampedEvent) => signer.get()?.sign(event),
shouldAuth: (socket: Socket) => true,
})
export const trustPolicy = (socket: Socket) => {
const buffer: RelayMessage[] = []
const unsubscribers = [
// When the socket goes from untrusted to trusted, receive all buffered messages
userSettingsValues.subscribe($settings => {
if ($settings.trusted_relays.includes(socket.url)) {
for (const message of buffer.splice(0)) {
socket._recvQueue.push(message)
}
}
}),
// When we get an event with no signature from an untrusted relay, remove it from
// the receive queue. If trust status is undefined, buffer it for later.
on(socket, SocketEvent.Receiving, (message: RelayMessage) => {
if (isRelayEvent(message) && !message[2]?.sig) {
const isTrusted = getSetting<string[]>("trusted_relays").includes(socket.url)
if (!isTrusted) {
buffer.push(message)
socket._recvQueue.remove(message)
relaysPendingTrust.update($r => uniq([...$r, socket.url]))
}
}
}),
]
return () => {
unsubscribers.forEach(call)
}
}
export const mostlyRestrictedPolicy = (socket: Socket) => {
let total = 0
let restricted = 0
let error = ""
const pending = new Set<string>()
const updateStatus = () =>
relaysMostlyRestricted.update(
restricted > total / 2 ? assoc(socket.url, error) : dissoc(socket.url),
)
const unsubscribers = [
on(socket, SocketEvent.Receive, (message: RelayMessage) => {
if (isRelayOk(message)) {
const [_, id, ok, details = ""] = message
if (pending.has(id)) {
pending.delete(id)
if (!ok && details.startsWith("restricted: ")) {
restricted++
error = details
updateStatus()
}
}
}
if (isRelayClosed(message)) {
const [_, id, details = ""] = message
if (pending.has(id)) {
pending.delete(id)
if (details.startsWith("restricted: ")) {
restricted++
error = details
updateStatus()
}
}
}
}),
on(socket, SocketEvent.Send, (message: ClientMessage) => {
if (isClientReq(message)) {
total++
pending.add(message[1])
updateStatus()
}
if (isClientEvent(message)) {
total++
pending.add(message[1].id)
updateStatus()
}
if (isClientClose(message)) {
pending.delete(message[1])
}
}),
]
return () => {
unsubscribers.forEach(call)
}
}
+6 -2
View File
@@ -1,5 +1,6 @@
import {
always,
call,
on,
hash,
last,
@@ -281,8 +282,8 @@ const syncWrapManager = async () => {
}
}
export const syncDataStores = () =>
Promise.all([
export const syncDataStores = async () => {
const unsubscribers = await Promise.all([
syncEvents(),
syncTracker(),
syncRelays(),
@@ -292,3 +293,6 @@ export const syncDataStores = () =>
syncPlaintext(),
syncWrapManager(),
])
return () => unsubscribers.forEach(call)
}
+3
View File
@@ -1,3 +1,4 @@
import {noop} from "@welshman/lib"
import * as Sentry from "@sentry/browser"
import {getSetting} from "@app/core/state"
@@ -17,4 +18,6 @@ export const setupTracking = () => {
},
})
}
return noop
}